From 532043a8843082352fb8fa9e9b4cebca4f9f357f Mon Sep 17 00:00:00 2001 From: vms Date: Mon, 19 Apr 2021 16:08:06 +0300 Subject: [PATCH] refactor reader --- .../src/interpreter/instructions/arrays.rs | 6 +- .../instructions/arrays/lower_array.rs | 4 +- .../arrays/{utils.rs => memory_writer.rs} | 0 .../instructions/arrays/read_arrays.rs | 2 +- .../src/interpreter/instructions/records.rs | 235 +----------------- .../instructions/records/lift_record.rs | 192 ++++++++++++++ .../instructions/records/lower_record.rs | 70 ++++++ .../instructions/records/value_reader.rs | 89 +++++++ .../src/interpreter/instructions/utils.rs | 4 + wasmer-it/src/lib.rs | 1 + 10 files changed, 374 insertions(+), 229 deletions(-) rename wasmer-it/src/interpreter/instructions/arrays/{utils.rs => memory_writer.rs} (100%) create mode 100644 wasmer-it/src/interpreter/instructions/records/value_reader.rs diff --git a/wasmer-it/src/interpreter/instructions/arrays.rs b/wasmer-it/src/interpreter/instructions/arrays.rs index 3c9834e..911d6f5 100644 --- a/wasmer-it/src/interpreter/instructions/arrays.rs +++ b/wasmer-it/src/interpreter/instructions/arrays.rs @@ -1,7 +1,7 @@ mod lift_array; mod lower_array; +mod memory_writer; mod read_arrays; -mod utils; mod write_arrays; pub(crate) use lift_array::array_lift_memory_impl; @@ -9,8 +9,8 @@ pub(crate) use lower_array::array_lower_memory_impl; use super::allocate; use super::read_from_instance_mem; -use super::record_lift_memory_; -use super::record_lower_memory_; +use super::record_lift_memory_impl; +use super::record_lower_memory_impl; use super::write_to_instance_mem; use crate::instr_error; diff --git a/wasmer-it/src/interpreter/instructions/arrays/lower_array.rs b/wasmer-it/src/interpreter/instructions/arrays/lower_array.rs index b539878..a5920e9 100644 --- a/wasmer-it/src/interpreter/instructions/arrays/lower_array.rs +++ b/wasmer-it/src/interpreter/instructions/arrays/lower_array.rs @@ -1,4 +1,4 @@ -use super::utils::MemoryWriter; +use super::memory_writer::MemoryWriter; use super::write_to_instance_mem; use crate::{ @@ -75,7 +75,7 @@ where IValue::Record(values) => { let record_offset = - super::record_lower_memory_(instance, instruction.clone(), values)?; + super::record_lower_memory_impl(instance, instruction.clone(), values)?; writer.write_array(record_offset.to_le_bytes()); } } diff --git a/wasmer-it/src/interpreter/instructions/arrays/utils.rs b/wasmer-it/src/interpreter/instructions/arrays/memory_writer.rs similarity index 100% rename from wasmer-it/src/interpreter/instructions/arrays/utils.rs rename to wasmer-it/src/interpreter/instructions/arrays/memory_writer.rs diff --git a/wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs b/wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs index 5870732..d4df139 100644 --- a/wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs +++ b/wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs @@ -397,7 +397,7 @@ where let mut result = Vec::with_capacity(data.len()); for record_offset in data { - result.push(super::record_lift_memory_( + result.push(super::record_lift_memory_impl( instance, record_type, *record_offset as _, diff --git a/wasmer-it/src/interpreter/instructions/records.rs b/wasmer-it/src/interpreter/instructions/records.rs index 27f7621..daf5eb1 100644 --- a/wasmer-it/src/interpreter/instructions/records.rs +++ b/wasmer-it/src/interpreter/instructions/records.rs @@ -1,169 +1,23 @@ +mod lift_record; +mod lower_record; +mod value_reader; + +pub(crate) use lift_record::record_lift_memory_impl; +pub(crate) use lower_record::record_lower_memory_impl; + +use super::array_lift_memory_impl; +use super::array_lower_memory_impl; use super::read_from_instance_mem; use super::write_to_instance_mem; use crate::instr_error; use crate::interpreter::instructions::{is_record_fields_compatible_to_type, to_native}; -use crate::IRecordType; use crate::IType; use crate::IValue; -use crate::NEVec; -use crate::{ - errors::{InstructionError, InstructionErrorKind}, - interpreter::Instruction, -}; +use crate::{errors::InstructionError, errors::InstructionErrorKind, interpreter::Instruction}; use std::convert::TryInto; -pub(super) fn record_lift_memory_<'instance, Instance, Export, LocalImport, Memory, MemoryView>( - instance: &'instance Instance, - record_type: &IRecordType, - offset: usize, - instruction: Instruction, -) -> Result -where - Export: crate::interpreter::wasm::structures::Export, - LocalImport: crate::interpreter::wasm::structures::LocalImport, - Memory: crate::interpreter::wasm::structures::Memory, - MemoryView: crate::interpreter::wasm::structures::MemoryView, - Instance: crate::interpreter::wasm::structures::Instance - + 'instance, -{ - let length = record_type.fields.len(); - let mut values = Vec::with_capacity(length); - let size = record_size(record_type); - let data = read_from_instance_mem(instance, instruction.clone(), offset, size)?; - - let mut field_id = 0; - for field in (*record_type.fields).iter() { - let value = data[field_id]; - match &field.ty { - IType::Boolean => { - values.push(IValue::Boolean(value as _)); - } - IType::S8 => { - values.push(IValue::S8(value as _)); - } - IType::S16 => { - values.push(IValue::S16(value as _)); - } - IType::S32 => { - values.push(IValue::S32(value as _)); - } - IType::S64 => { - values.push(IValue::S64(value as _)); - } - IType::I32 => { - values.push(IValue::I32(value as _)); - } - IType::I64 => { - values.push(IValue::I64(value as _)); - } - IType::U8 => { - values.push(IValue::U8(value as _)); - } - IType::U16 => { - values.push(IValue::U16(value as _)); - } - IType::U32 => { - values.push(IValue::U32(value as _)); - } - IType::U64 => { - values.push(IValue::U64(value as _)); - } - IType::F32 => { - values.push(IValue::F32(value as _)); - } - IType::F64 => values.push(IValue::F64(f64::from_bits(value))), - IType::String => { - let string_offset = value; - field_id += 1; - let string_size = data[field_id]; - - if string_size != 0 { - let string_mem = read_from_instance_mem( - instance, - instruction.clone(), - string_offset as _, - string_size as _, - )?; - - // TODO: check - let string = String::from_utf8(string_mem).unwrap(); - values.push(IValue::String(string)); - } else { - values.push(IValue::String(String::new())); - } - } - IType::Array(ty) => { - let array_offset = value; - field_id += 1; - let array_size = data[field_id]; - - if array_size != 0 { - let array = super::array_lift_memory_impl( - instance, - &**ty, - array_offset as _, - array_size as _, - instruction.clone(), - )?; - values.push(array); - } else { - values.push(IValue::Array(vec![])); - } - } - IType::Record(record_type_id) => { - let offset = value; - - let record_type = instance.wit_record_by_id(*record_type_id).ok_or_else(|| { - InstructionError::new( - instruction.clone(), - InstructionErrorKind::RecordTypeByNameIsMissing { - record_type_id: *record_type_id, - }, - ) - })?; - - values.push(record_lift_memory_( - instance, - record_type, - offset as _, - instruction.clone(), - )?) - } - } - field_id += 1; - } - - Ok(IValue::Record( - NEVec::new(values.into_iter().collect()) - .expect("Record must have at least one field, zero given"), - )) -} - -/// Returns record size in bytes. -fn record_size(record_type: &IRecordType) -> usize { - let mut record_size = 0; - - for field_type in record_type.fields.iter() { - record_size += match field_type.ty { - IType::Boolean | IType::S8 | IType::U8 => 1, - IType::S16 | IType::U16 => 2, - IType::S32 - | IType::U32 - | IType::I32 - | IType::F32 - | IType::String - | IType::ByteArray - | IType::Array(_) - | IType::Record(_) => 32, - IType::S64 | IType::U64 | IType::I64 | IType::F64 => 64, - }; - } - - record_size -} - pub(crate) fn record_lift_memory( record_type_id: u64, instruction: Instruction, @@ -208,7 +62,7 @@ where ); let record = - record_lift_memory_(&**instance, record_type, offset, instruction.clone())?; + record_lift_memory_impl(&**instance, record_type, offset, instruction.clone())?; log::debug!("record.lift_memory: pushing {:?} on the stack", record); runtime.stack.push(record); @@ -218,71 +72,6 @@ where }) } -pub(super) fn record_lower_memory_( - instance: &mut Instance, - instruction: Instruction, - values: NEVec, -) -> Result -where - Export: crate::interpreter::wasm::structures::Export, - LocalImport: crate::interpreter::wasm::structures::LocalImport, - Memory: crate::interpreter::wasm::structures::Memory, - MemoryView: crate::interpreter::wasm::structures::MemoryView, - Instance: - crate::interpreter::wasm::structures::Instance, -{ - let mut result: Vec = Vec::with_capacity(values.len()); - - for value in values.into_vec() { - match value { - IValue::Boolean(value) => result.push(value as _), - IValue::S8(value) => result.push(value as _), - IValue::S16(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::S32(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::S64(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::U8(value) => result.push(value), - IValue::U16(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::U32(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::U64(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::I32(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::I64(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::F32(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::F64(value) => result.extend_from_slice(&value.to_le_bytes()), - IValue::String(value) => { - let string_pointer = - write_to_instance_mem(instance, instruction.clone(), value.as_bytes())?; - - result.extend_from_slice(&string_pointer.to_le_bytes()); - result.extend_from_slice(&value.len().to_le_bytes()); - } - IValue::ByteArray(value) => { - let array_pointer = write_to_instance_mem(instance, instruction.clone(), &value)?; - - result.extend_from_slice(&array_pointer.to_le_bytes()); - result.extend_from_slice(&value.len().to_le_bytes()); - } - - IValue::Array(values) => { - let (offset, size) = - super::array_lower_memory_impl(instance, instruction.clone(), values)?; - - result.extend_from_slice(&offset.to_le_bytes()); - result.extend_from_slice(&size.to_le_bytes()); - } - - IValue::Record(values) => { - let record_ptr = record_lower_memory_(instance, instruction.clone(), values)?; - - result.extend_from_slice(&record_ptr.to_le_bytes()); - } - } - } - - let result_pointer = write_to_instance_mem(instance, instruction, &result)?; - - Ok(result_pointer as _) -} - pub(crate) fn record_lower_memory( record_type_id: u64, instruction: Instruction, @@ -313,7 +102,7 @@ where log::debug!("record.lower_memory: obtained {:?} values on the stack for record type = {}", record_fields, record_type_id); let offset = - record_lower_memory_(*instance, instruction.clone(), record_fields)?; + record_lower_memory_impl(*instance, instruction.clone(), record_fields)?; log::debug!("record.lower_memory: pushing {} on the stack", offset); runtime.stack.push(IValue::I32(offset)); diff --git a/wasmer-it/src/interpreter/instructions/records/lift_record.rs b/wasmer-it/src/interpreter/instructions/records/lift_record.rs index e69de29..1989067 100644 --- a/wasmer-it/src/interpreter/instructions/records/lift_record.rs +++ b/wasmer-it/src/interpreter/instructions/records/lift_record.rs @@ -0,0 +1,192 @@ +use super::read_from_instance_mem; + +use super::value_reader::ValueReader; +use crate::IRecordType; +use crate::IType; +use crate::IValue; +use crate::NEVec; +use crate::{ + errors::{InstructionError, InstructionErrorKind}, + interpreter::Instruction, +}; + +#[rustfmt::skip] +pub(crate) fn record_lift_memory_impl<'instance, Instance, Export, LocalImport, Memory, MemoryView>( + instance: &'instance Instance, + record_type: &IRecordType, + offset: usize, + instruction: Instruction, +) -> Result +where + Export: crate::interpreter::wasm::structures::Export, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance + 'instance, +{ + let mut values = Vec::with_capacity(record_type.fields.len()); + + let size = record_size(record_type); + let data = read_from_instance_mem(instance, instruction.clone(), offset, size)?; + let reader = ValueReader::new(data); + + for field in (*record_type.fields).iter() { + match &field.ty { + IType::Boolean => values.push(IValue::Boolean(reader.read_u8() == 1)), + IType::S8 => values.push(IValue::S8(reader.read_i8())), + IType::S16 => values.push(IValue::S16(reader.read_i16())), + IType::S32 => values.push(IValue::S32(reader.read_i32())), + IType::S64 => values.push(IValue::S64(reader.read_i64())), + IType::I32 => values.push(IValue::I32(reader.read_i32())), + IType::I64 => values.push(IValue::I64(reader.read_i64())), + IType::U8 => values.push(IValue::U8(reader.read_u8())), + IType::U16 => values.push(IValue::U16(reader.read_u16())), + IType::U32 => values.push(IValue::U32(reader.read_u32())), + IType::U64 => values.push(IValue::U64(reader.read_u64())), + IType::F32 => values.push(IValue::F32(reader.read_f32())), + IType::F64 => values.push(IValue::F64(reader.read_f64())), + IType::String => values.push(IValue::String(read_string(instance, instruction.clone(), &reader)?)), + IType::ByteArray => values.push(read_byte_array(instance, instruction.clone(), &reader)?), + IType::Array(ty) => values.push(read_array(instance, instruction.clone(), &reader, &**ty)?), + IType::Record(record_type_id) => values.push(read_record(instance, instruction.clone(), &reader, *record_type_id)?), + } + } + + Ok(IValue::Record( + NEVec::new(values.into_iter().collect()) + .expect("Record must have at least one field, zero given"), + )) +} + +/// Returns record size in bytes. +fn record_size(record_type: &IRecordType) -> usize { + let mut record_size = 0; + + for field_type in record_type.fields.iter() { + record_size += match field_type.ty { + IType::Boolean | IType::S8 | IType::U8 => 1, + IType::S16 | IType::U16 => 2, + IType::S32 + | IType::U32 + | IType::I32 + | IType::F32 + | IType::String + | IType::ByteArray + | IType::Array(_) + | IType::Record(_) => 32, + IType::S64 | IType::U64 | IType::I64 | IType::F64 => 64, + }; + } + + record_size +} + +fn read_string<'instance, Instance, Export, LocalImport, Memory, MemoryView>( + instance: &Instance, + instruction: Instruction, + reader: &ValueReader, +) -> Result +where + Export: crate::interpreter::wasm::structures::Export, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance + + 'instance, +{ + let string_offset = reader.read_u32(); + let string_size = reader.read_u32(); + + let string_mem = read_from_instance_mem( + instance, + instruction.clone(), + string_offset as _, + string_size as _, + )?; + + // TODO: check + let string = String::from_utf8(string_mem).unwrap(); + + Ok(string) +} + +fn read_byte_array<'instance, Instance, Export, LocalImport, Memory, MemoryView>( + instance: &Instance, + instruction: Instruction, + reader: &ValueReader, +) -> Result +where + Export: crate::interpreter::wasm::structures::Export, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance + + 'instance, +{ + let offset = reader.read_u32(); + let elements_count = reader.read_u32(); + + let array = read_from_instance_mem( + instance, + instruction.clone(), + offset as _, + elements_count as _, + )?; + let byte_array = IValue::ByteArray(array); + + Ok(byte_array) +} + +fn read_array<'instance, Instance, Export, LocalImport, Memory, MemoryView>( + instance: &Instance, + instruction: Instruction, + reader: &ValueReader, + ty: &IType, +) -> Result +where + Export: crate::interpreter::wasm::structures::Export, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance + + 'instance, +{ + let array_offset = reader.read_u32(); + let elements_count = reader.read_u32(); + + super::array_lift_memory_impl( + instance, + ty, + array_offset as _, + elements_count as _, + instruction.clone(), + ) +} + +fn read_record<'instance, Instance, Export, LocalImport, Memory, MemoryView>( + instance: &Instance, + instruction: Instruction, + reader: &ValueReader, + record_type_id: u64, +) -> Result +where + Export: crate::interpreter::wasm::structures::Export, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance + + 'instance, +{ + let offset = reader.read_u32(); + + let record_type = instance.wit_record_by_id(record_type_id).ok_or_else(|| { + InstructionError::new( + instruction.clone(), + InstructionErrorKind::RecordTypeByNameIsMissing { + record_type_id, + }, + ) + })?; + + record_lift_memory_impl(instance, record_type, offset as _, instruction.clone()) +} diff --git a/wasmer-it/src/interpreter/instructions/records/lower_record.rs b/wasmer-it/src/interpreter/instructions/records/lower_record.rs index e69de29..66b1f7e 100644 --- a/wasmer-it/src/interpreter/instructions/records/lower_record.rs +++ b/wasmer-it/src/interpreter/instructions/records/lower_record.rs @@ -0,0 +1,70 @@ +use super::write_to_instance_mem; + +use crate::IValue; +use crate::NEVec; +use crate::{errors::InstructionError, interpreter::Instruction}; + +pub(crate) fn record_lower_memory_impl( + instance: &mut Instance, + instruction: Instruction, + values: NEVec, +) -> Result +where + Export: crate::interpreter::wasm::structures::Export, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: + crate::interpreter::wasm::structures::Instance, +{ + let mut result: Vec = Vec::with_capacity(values.len()); + + for value in values.into_vec() { + match value { + IValue::Boolean(value) => result.push(value as _), + IValue::S8(value) => result.push(value as _), + IValue::S16(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::S32(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::S64(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::U8(value) => result.push(value), + IValue::U16(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::U32(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::U64(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::I32(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::I64(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::F32(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::F64(value) => result.extend_from_slice(&value.to_le_bytes()), + IValue::String(value) => { + let string_pointer = + write_to_instance_mem(instance, instruction.clone(), value.as_bytes())?; + + result.extend_from_slice(&string_pointer.to_le_bytes()); + result.extend_from_slice(&value.len().to_le_bytes()); + } + IValue::ByteArray(value) => { + let array_pointer = write_to_instance_mem(instance, instruction.clone(), &value)?; + + result.extend_from_slice(&array_pointer.to_le_bytes()); + result.extend_from_slice(&value.len().to_le_bytes()); + } + + IValue::Array(values) => { + let (offset, size) = + super::array_lower_memory_impl(instance, instruction.clone(), values)?; + + result.extend_from_slice(&offset.to_le_bytes()); + result.extend_from_slice(&size.to_le_bytes()); + } + + IValue::Record(values) => { + let record_ptr = record_lower_memory_impl(instance, instruction.clone(), values)?; + + result.extend_from_slice(&record_ptr.to_le_bytes()); + } + } + } + + let result_pointer = write_to_instance_mem(instance, instruction, &result)?; + + Ok(result_pointer as _) +} diff --git a/wasmer-it/src/interpreter/instructions/records/value_reader.rs b/wasmer-it/src/interpreter/instructions/records/value_reader.rs new file mode 100644 index 0000000..d74ec6b --- /dev/null +++ b/wasmer-it/src/interpreter/instructions/records/value_reader.rs @@ -0,0 +1,89 @@ +use std::cell::Cell; + +pub(super) struct ValueReader { + stream: Vec, + offset: Cell, +} + +macro_rules! value_der { + ($self:expr, $offset:expr, @seq_start $($ids:tt),* @seq_end) => { + [$($self.stream[$offset + $ids]),+] + }; + + ($self:expr, $offset:expr, 1) => { + value_der!($self, $offset, @seq_start 0 @seq_end); + }; + + ($self:expr, $offset:expr, 2) => { + value_der!($self, $offset, @seq_start 0, 1 @seq_end); + }; + + ($self:expr, $offset:expr, 4) => { + value_der!($self, $offset, @seq_start 0, 1, 2, 3 @seq_end); + }; + + ($self:expr, $offset:expr, 8) => { + value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7 @seq_end); + }; +} + +macro_rules! read_ty { + ($func_name:ident, $ty:ty, 1) => { + pub(super) fn $func_name(&self) -> $ty { + let offset = self.offset.get(); + let result = <$ty>::from_le_bytes(value_der!(self, offset, 1)); + + self.offset.set(offset + 1); + result + } + }; + + ($func_name:ident, $ty:ty, 2) => { + pub(super) fn $func_name(&self) -> $ty { + let offset = self.offset.get(); + let result = <$ty>::from_le_bytes(value_der!(self, offset, 2)); + + self.offset.set(offset + 2); + result + } + }; + + ($func_name:ident, $ty:ty, 4) => { + pub(super) fn $func_name(&self) -> $ty { + let offset = self.offset.get(); + let result = <$ty>::from_le_bytes(value_der!(self, offset, 4)); + + self.offset.set(offset + 4); + result + } + }; + + ($func_name:ident, $ty:ty, 8) => { + pub(super) fn $func_name(&self) -> $ty { + let offset = self.offset.get(); + let result = <$ty>::from_le_bytes(value_der!(self, offset, 8)); + + self.offset.set(offset + 8); + result + } + }; +} + +// TODO: rewrite this with macros +impl ValueReader { + pub(super) fn new(stream: Vec) -> Self { + let offset = Cell::new(0); + Self { stream, offset } + } + + read_ty!(read_u8, u8, 1); + read_ty!(read_i8, i8, 1); + read_ty!(read_u16, u16, 2); + read_ty!(read_i16, i16, 2); + read_ty!(read_u32, u32, 4); + read_ty!(read_i32, i32, 4); + read_ty!(read_f32, f32, 4); + read_ty!(read_u64, u64, 8); + read_ty!(read_i64, i64, 8); + read_ty!(read_f64, f64, 8); +} diff --git a/wasmer-it/src/interpreter/instructions/utils.rs b/wasmer-it/src/interpreter/instructions/utils.rs index f743357..0544b40 100644 --- a/wasmer-it/src/interpreter/instructions/utils.rs +++ b/wasmer-it/src/interpreter/instructions/utils.rs @@ -24,6 +24,10 @@ where MemoryView: wasm::structures::MemoryView, Instance: wasm::structures::Instance, { + if size == 0 { + return Ok(vec![]); + } + let memory_index = 0; let memory_view = instance .memory(memory_index) diff --git a/wasmer-it/src/lib.rs b/wasmer-it/src/lib.rs index c540a41..800c58a 100644 --- a/wasmer-it/src/lib.rs +++ b/wasmer-it/src/lib.rs @@ -52,6 +52,7 @@ // #![forbid(unsafe_code)] #![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")] #![doc(html_logo_url = "https://github.com/wasmerio.png")] +#![recursion_limit = "512"] pub mod ast; #[macro_use]