mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
Types section
This commit is contained in:
parent
6ab00d164c
commit
7ad452d78a
4 changed files with 293 additions and 44 deletions
|
@ -7,7 +7,7 @@ use roc_module::symbol::Symbol;
|
||||||
|
|
||||||
use crate::module_builder::{IndexRelocType, RelocationEntry};
|
use crate::module_builder::{IndexRelocType, RelocationEntry};
|
||||||
use crate::opcodes::*;
|
use crate::opcodes::*;
|
||||||
use crate::serialize::SerialBuffer;
|
use crate::serialize::{SerialBuffer, Serialize};
|
||||||
use crate::{round_up_to_alignment, LocalId, FRAME_ALIGNMENT_BYTES, STACK_POINTER_GLOBAL_ID};
|
use crate::{round_up_to_alignment, LocalId, FRAME_ALIGNMENT_BYTES, STACK_POINTER_GLOBAL_ID};
|
||||||
|
|
||||||
/// Wasm value type. (Rust representation matches Wasm encoding)
|
/// Wasm value type. (Rust representation matches Wasm encoding)
|
||||||
|
@ -300,43 +300,7 @@ impl<'a> CodeBuilder<'a> {
|
||||||
|
|
||||||
/// Generate bytes to declare the function's local variables
|
/// Generate bytes to declare the function's local variables
|
||||||
fn build_local_declarations(&mut self, local_types: &[ValueType]) {
|
fn build_local_declarations(&mut self, local_types: &[ValueType]) {
|
||||||
// reserve one byte for num_batches
|
local_types.serialize(&mut self.preamble);
|
||||||
self.preamble.push(0);
|
|
||||||
|
|
||||||
if local_types.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write declarations in batches of the same ValueType
|
|
||||||
let mut num_batches: u32 = 0;
|
|
||||||
let mut batch_type = local_types[0];
|
|
||||||
let mut batch_size = 0;
|
|
||||||
for t in local_types {
|
|
||||||
if *t == batch_type {
|
|
||||||
batch_size += 1;
|
|
||||||
} else {
|
|
||||||
self.preamble.encode_u32(batch_size);
|
|
||||||
self.preamble.push(batch_type as u8);
|
|
||||||
batch_type = *t;
|
|
||||||
batch_size = 1;
|
|
||||||
num_batches += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.preamble.encode_u32(batch_size);
|
|
||||||
self.preamble.push(batch_type as u8);
|
|
||||||
num_batches += 1;
|
|
||||||
|
|
||||||
// Go back and write the number of batches at the start
|
|
||||||
if num_batches < 128 {
|
|
||||||
self.preamble[0] = num_batches as u8;
|
|
||||||
} else {
|
|
||||||
// We need more than 1 byte to encode num_batches!
|
|
||||||
// This is a ridiculous edge case, so just pad to 5 bytes for simplicity
|
|
||||||
let old_len = self.preamble.len();
|
|
||||||
self.preamble.resize(old_len + 4, 0);
|
|
||||||
self.preamble.copy_within(1..old_len, 5);
|
|
||||||
self.preamble.overwrite_padded_u32(0, num_batches);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate instruction bytes to grab a frame of stack memory on entering the function
|
/// Generate instruction bytes to grab a frame of stack memory on entering the function
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use bumpalo::collections::vec::Vec;
|
use bumpalo::collections::vec::Vec;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
|
||||||
use crate::code_builder::Align;
|
use crate::code_builder::{Align, ValueType};
|
||||||
use crate::serialize::{SerialBuffer, Serialize};
|
use crate::serialize::{SerialBuffer, Serialize};
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
@ -34,7 +34,7 @@ struct SectionHeaderIndices {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a section header, returning the position of the encoded length
|
/// Write a section header, returning the position of the encoded length
|
||||||
fn _write_section_header<T: SerialBuffer>(buffer: &mut T, id: SectionId) -> SectionHeaderIndices {
|
fn write_section_header<T: SerialBuffer>(buffer: &mut T, id: SectionId) -> SectionHeaderIndices {
|
||||||
buffer.append_byte(id as u8);
|
buffer.append_byte(id as u8);
|
||||||
let size_index = buffer.reserve_padded_u32();
|
let size_index = buffer.reserve_padded_u32();
|
||||||
let body_index = buffer.size();
|
let body_index = buffer.size();
|
||||||
|
@ -49,7 +49,7 @@ fn write_custom_section_header<T: SerialBuffer>(
|
||||||
buffer: &mut T,
|
buffer: &mut T,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> SectionHeaderIndices {
|
) -> SectionHeaderIndices {
|
||||||
// buffer.append_byte(SectionId::Custom as u8); // TODO: uncomment when we get rid of parity_wasm
|
buffer.append_byte(SectionId::Custom as u8);
|
||||||
let size_index = buffer.reserve_padded_u32();
|
let size_index = buffer.reserve_padded_u32();
|
||||||
let body_index = buffer.size();
|
let body_index = buffer.size();
|
||||||
name.serialize(buffer);
|
name.serialize(buffer);
|
||||||
|
@ -76,6 +76,262 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Type section (function signature definitions)
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
impl<'a> Serialize for [ValueType] {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
|
// reserve one byte for num_batches
|
||||||
|
let start = buffer.size();
|
||||||
|
buffer.append_byte(0); // mut
|
||||||
|
|
||||||
|
if self.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write declarations in batches of the same ValueType
|
||||||
|
let mut num_batches: u32 = 0;
|
||||||
|
let mut batch_type = self[0];
|
||||||
|
let mut batch_size = 0;
|
||||||
|
for t in self {
|
||||||
|
if *t == batch_type {
|
||||||
|
batch_size += 1;
|
||||||
|
} else {
|
||||||
|
buffer.encode_u32(batch_size);
|
||||||
|
buffer.append_byte(batch_type as u8);
|
||||||
|
batch_type = *t;
|
||||||
|
batch_size = 1;
|
||||||
|
num_batches += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.encode_u32(batch_size);
|
||||||
|
buffer.append_byte(batch_type as u8);
|
||||||
|
num_batches += 1;
|
||||||
|
|
||||||
|
// Go back and write the number of batches at the start
|
||||||
|
if num_batches < 128 {
|
||||||
|
buffer.set_byte(start, num_batches as u8);
|
||||||
|
} else {
|
||||||
|
// We need more than 1 byte to encode num_batches!
|
||||||
|
// This is a ridiculous edge case, so just pad to 5 bytes for simplicity
|
||||||
|
buffer.insert_space_at(1, 4);
|
||||||
|
buffer.overwrite_padded_u32(0, num_batches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Signature<'a> {
|
||||||
|
param_types: Vec<'a, ValueType>,
|
||||||
|
ret_type: Option<ValueType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Serialize for Signature<'a> {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
|
buffer.append_byte(0x60);
|
||||||
|
self.param_types.serialize(buffer);
|
||||||
|
match self.ret_type {
|
||||||
|
Some(t) => [t].serialize(buffer),
|
||||||
|
None => buffer.append_byte(0), // vector of length zero
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TypeSection<'a> {
|
||||||
|
signatures: Vec<'a, Signature<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TypeSection<'a> {
|
||||||
|
pub fn new(arena: &'a Bump) -> Self {
|
||||||
|
TypeSection {
|
||||||
|
signatures: Vec::with_capacity_in(8, arena),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Serialize for TypeSection<'a> {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
|
let header_indices = write_section_header(buffer, SectionId::Type);
|
||||||
|
serialize_vector_with_count(buffer, self.signatures);
|
||||||
|
update_section_size(buffer, header_indices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Import section
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
pub struct ImportSection<'a> {
|
||||||
|
todo: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ImportSection<'a> {
|
||||||
|
pub fn new(arena: &'a Bump) -> Self {
|
||||||
|
ImportSection { todo: "" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Serialize for ImportSection<'a> {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Function section (map function index to signature index)
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
pub struct FunctionSection<'a> {
|
||||||
|
pub signature_indices: Vec<'a, u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FunctionSection<'a> {
|
||||||
|
pub fn new(arena: &'a Bump) -> Self {
|
||||||
|
FunctionSection {
|
||||||
|
signature_indices: Vec::with_capacity_in(8, arena),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Serialize for FunctionSection<'a> {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Memory section
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
enum Limits {
|
||||||
|
Min(u32),
|
||||||
|
MinMax(u32, u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MemorySection {
|
||||||
|
/// number of 64kB pages
|
||||||
|
num_pages: Limits,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemorySection {
|
||||||
|
const PAGE_SIZE_KB: u32 = 64;
|
||||||
|
|
||||||
|
pub fn new(kb: u32) -> Self {
|
||||||
|
MemorySection {
|
||||||
|
num_pages: Limits::Min(kb / Self::PAGE_SIZE_KB),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for MemorySection {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Global section
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
enum InitValue {
|
||||||
|
I32(i32),
|
||||||
|
I64(i64),
|
||||||
|
F32(f32),
|
||||||
|
F64(f64),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Global {
|
||||||
|
init_value: InitValue,
|
||||||
|
is_mutable: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for Global {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GlobalSection<'a>(Vec<'a, Global>);
|
||||||
|
|
||||||
|
impl<'a> GlobalSection<'a> {
|
||||||
|
pub fn new(arena: &'a Bump) -> Self {
|
||||||
|
GlobalSection(Vec::with_capacity_in(1, arena))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Serialize for GlobalSection<'a> {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Export section
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
|
enum ExportType {
|
||||||
|
Func = 0,
|
||||||
|
Table = 1,
|
||||||
|
Mem = 2,
|
||||||
|
Global = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Export {
|
||||||
|
name: String,
|
||||||
|
ty: ExportType,
|
||||||
|
index: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ExportSection<'a> {
|
||||||
|
todo: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExportSection<'a> {
|
||||||
|
pub fn new(arena: &'a Bump) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Serialize for ExportSection<'a> {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Code section
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
pub struct CodeSection<'a> {
|
||||||
|
bytes: Vec<'a, u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CodeSection<'a> {
|
||||||
|
pub fn new(arena: &'a Bump) -> Self {
|
||||||
|
CodeSection {
|
||||||
|
bytes: Vec::with_capacity_in(4096, arena),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Serialize for CodeSection<'a> {
|
||||||
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
*
|
*
|
||||||
* Relocation sections
|
* Relocation sections
|
||||||
|
@ -248,6 +504,7 @@ pub struct LinkingSegment {
|
||||||
pub alignment: Align,
|
pub alignment: Align,
|
||||||
pub flags: u32,
|
pub flags: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for LinkingSegment {
|
impl Serialize for LinkingSegment {
|
||||||
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
todo!();
|
todo!();
|
||||||
|
@ -259,6 +516,7 @@ pub struct LinkingInitFunc {
|
||||||
pub priority: u32,
|
pub priority: u32,
|
||||||
pub symbol_index: u32, // index in the symbol table, not the function index
|
pub symbol_index: u32, // index in the symbol table, not the function index
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for LinkingInitFunc {
|
impl Serialize for LinkingInitFunc {
|
||||||
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
todo!();
|
todo!();
|
||||||
|
@ -284,6 +542,7 @@ pub struct ComdatSym {
|
||||||
pub kind: ComdatSymKind,
|
pub kind: ComdatSymKind,
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for ComdatSym {
|
impl Serialize for ComdatSym {
|
||||||
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
todo!();
|
todo!();
|
||||||
|
@ -300,6 +559,7 @@ pub struct LinkingComdat<'a> {
|
||||||
flags: u32,
|
flags: u32,
|
||||||
syms: Vec<'a, ComdatSym>,
|
syms: Vec<'a, ComdatSym>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Serialize for LinkingComdat<'a> {
|
impl<'a> Serialize for LinkingComdat<'a> {
|
||||||
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
todo!();
|
todo!();
|
||||||
|
@ -352,6 +612,7 @@ pub enum WasmObjectSymbol {
|
||||||
Defined { index: u32, name: String },
|
Defined { index: u32, name: String },
|
||||||
Imported { index: u32 },
|
Imported { index: u32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for WasmObjectSymbol {
|
impl Serialize for WasmObjectSymbol {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
match self {
|
match self {
|
||||||
|
@ -378,6 +639,7 @@ pub enum DataSymbol {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for DataSymbol {
|
impl Serialize for DataSymbol {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
match self {
|
match self {
|
||||||
|
@ -418,6 +680,7 @@ pub struct SymInfo {
|
||||||
flags: u32,
|
flags: u32,
|
||||||
info: SymInfoFields,
|
info: SymInfoFields,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SymInfo {
|
impl SymInfo {
|
||||||
pub fn for_function(wasm_function_index: u32, name: String) -> Self {
|
pub fn for_function(wasm_function_index: u32, name: String) -> Self {
|
||||||
let linking_symbol = WasmObjectSymbol::Defined {
|
let linking_symbol = WasmObjectSymbol::Defined {
|
||||||
|
@ -470,6 +733,7 @@ pub enum LinkingSubSection<'a> {
|
||||||
/// Specifies extra information about the symbols present in the module.
|
/// Specifies extra information about the symbols present in the module.
|
||||||
SymbolTable(Vec<'a, SymInfo>),
|
SymbolTable(Vec<'a, SymInfo>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Serialize for LinkingSubSection<'a> {
|
impl<'a> Serialize for LinkingSubSection<'a> {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
buffer.append_byte(match self {
|
buffer.append_byte(match self {
|
||||||
|
@ -530,7 +794,7 @@ impl<'a> Serialize for LinkingSection<'a> {
|
||||||
*
|
*
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
|
||||||
const WASM_VERSION: u32 = 1;
|
type UnusedSection<'a> = &'a str;
|
||||||
|
|
||||||
pub struct WasmModule<'a> {
|
pub struct WasmModule<'a> {
|
||||||
pub types: &'a str, // TODO
|
pub types: &'a str, // TODO
|
||||||
|
@ -558,6 +822,8 @@ fn maybe_increment_section(size: usize, prev_size: &mut usize, index: &mut u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WasmModule<'a> {
|
impl<'a> WasmModule<'a> {
|
||||||
|
const WASM_VERSION: u32 = 1;
|
||||||
|
|
||||||
pub fn new(arena: &'a Bump) -> Self {
|
pub fn new(arena: &'a Bump) -> Self {
|
||||||
WasmModule {
|
WasmModule {
|
||||||
types: "",
|
types: "",
|
||||||
|
@ -582,7 +848,7 @@ impl<'a> WasmModule<'a> {
|
||||||
fn serialize<T: SerialBuffer>(&mut self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&mut self, buffer: &mut T) {
|
||||||
buffer.append_byte(0);
|
buffer.append_byte(0);
|
||||||
buffer.append_slice("asm".as_bytes());
|
buffer.append_slice("asm".as_bytes());
|
||||||
buffer.write_unencoded_u32(WASM_VERSION);
|
buffer.write_unencoded_u32(Self::WASM_VERSION);
|
||||||
|
|
||||||
let mut index: u32 = 0;
|
let mut index: u32 = 0;
|
||||||
let mut prev_size = buffer.size();
|
let mut prev_size = buffer.size();
|
||||||
|
|
|
@ -71,6 +71,7 @@ macro_rules! encode_padded_sleb128 {
|
||||||
|
|
||||||
pub trait SerialBuffer {
|
pub trait SerialBuffer {
|
||||||
fn append_byte(&mut self, b: u8);
|
fn append_byte(&mut self, b: u8);
|
||||||
|
fn set_byte(&mut self, index: usize, b: u8);
|
||||||
fn append_slice(&mut self, b: &[u8]);
|
fn append_slice(&mut self, b: &[u8]);
|
||||||
fn size(&self) -> usize;
|
fn size(&self) -> usize;
|
||||||
|
|
||||||
|
@ -79,6 +80,8 @@ pub trait SerialBuffer {
|
||||||
encode_sleb128!(encode_i32, i32);
|
encode_sleb128!(encode_i32, i32);
|
||||||
encode_sleb128!(encode_i64, i64);
|
encode_sleb128!(encode_i64, i64);
|
||||||
|
|
||||||
|
/// Inserts extra entries at the given index by copying the following entries to higher indices
|
||||||
|
fn insert_space_at(&mut self, index: usize, size: usize);
|
||||||
fn reserve_padded_u32(&mut self) -> usize;
|
fn reserve_padded_u32(&mut self) -> usize;
|
||||||
fn encode_padded_u32(&mut self, value: u32) -> usize;
|
fn encode_padded_u32(&mut self, value: u32) -> usize;
|
||||||
fn overwrite_padded_u32(&mut self, index: usize, value: u32);
|
fn overwrite_padded_u32(&mut self, index: usize, value: u32);
|
||||||
|
@ -122,12 +125,20 @@ impl SerialBuffer for std::vec::Vec<u8> {
|
||||||
fn append_byte(&mut self, b: u8) {
|
fn append_byte(&mut self, b: u8) {
|
||||||
self.push(b);
|
self.push(b);
|
||||||
}
|
}
|
||||||
|
fn set_byte(&mut self, index: usize, b: u8) {
|
||||||
|
self[index] = b;
|
||||||
|
}
|
||||||
fn append_slice(&mut self, b: &[u8]) {
|
fn append_slice(&mut self, b: &[u8]) {
|
||||||
self.extend_from_slice(b);
|
self.extend_from_slice(b);
|
||||||
}
|
}
|
||||||
fn size(&self) -> usize {
|
fn size(&self) -> usize {
|
||||||
self.len()
|
self.len()
|
||||||
}
|
}
|
||||||
|
fn insert_space_at(&mut self, index: usize, size: usize) {
|
||||||
|
let old_len = self.len();
|
||||||
|
self.resize(old_len + size, 0);
|
||||||
|
self.copy_within(index..old_len, index + size);
|
||||||
|
}
|
||||||
fn reserve_padded_u32(&mut self) -> usize {
|
fn reserve_padded_u32(&mut self) -> usize {
|
||||||
let index = self.len();
|
let index = self.len();
|
||||||
self.resize(index + 5, 0xff);
|
self.resize(index + 5, 0xff);
|
||||||
|
@ -149,12 +160,20 @@ impl<'a> SerialBuffer for Vec<'a, u8> {
|
||||||
fn append_byte(&mut self, b: u8) {
|
fn append_byte(&mut self, b: u8) {
|
||||||
self.push(b);
|
self.push(b);
|
||||||
}
|
}
|
||||||
|
fn set_byte(&mut self, index: usize, b: u8) {
|
||||||
|
self[index] = b;
|
||||||
|
}
|
||||||
fn append_slice(&mut self, b: &[u8]) {
|
fn append_slice(&mut self, b: &[u8]) {
|
||||||
self.extend_from_slice(b);
|
self.extend_from_slice(b);
|
||||||
}
|
}
|
||||||
fn size(&self) -> usize {
|
fn size(&self) -> usize {
|
||||||
self.len()
|
self.len()
|
||||||
}
|
}
|
||||||
|
fn insert_space_at(&mut self, index: usize, size: usize) {
|
||||||
|
let old_len = self.len();
|
||||||
|
self.resize(old_len + size, 0);
|
||||||
|
self.copy_within(index..old_len, index + size);
|
||||||
|
}
|
||||||
fn reserve_padded_u32(&mut self) -> usize {
|
fn reserve_padded_u32(&mut self) -> usize {
|
||||||
let index = self.len();
|
let index = self.len();
|
||||||
self.resize(index + 5, 0xff);
|
self.resize(index + 5, 0xff);
|
||||||
|
|
|
@ -120,7 +120,7 @@ pub fn helper_wasm<'a, T: Wasm32TestResult>(
|
||||||
let module_bytes = parity_module.into_bytes().unwrap();
|
let module_bytes = parity_module.into_bytes().unwrap();
|
||||||
|
|
||||||
// for debugging (e.g. with wasm2wat or wasm-objdump)
|
// for debugging (e.g. with wasm2wat or wasm-objdump)
|
||||||
if false {
|
if true {
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
let mut hash_state = DefaultHasher::new();
|
let mut hash_state = DefaultHasher::new();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue