From 06e0dd40d6955bcc06c2cbdfee3d0b161527ac16 Mon Sep 17 00:00:00 2001 From: Valery Antopol Date: Tue, 14 Feb 2023 17:48:09 +0300 Subject: [PATCH] feat!: pass a context object through the API to the wasm engine functions (#34) --- crates/it-lilo/src/lifter/lift_array.rs | 97 +++++++++++-------- crates/it-lilo/src/lifter/lift_record.rs | 95 ++++++++++-------- crates/it-lilo/src/lifter/macros.rs | 94 ++++++++++++------ crates/it-lilo/src/lifter/memory_reader.rs | 57 +++++++---- crates/it-lilo/src/lifter/mod.rs | 13 ++- crates/it-lilo/src/lowerer/lower_array.rs | 63 ++++++------ crates/it-lilo/src/lowerer/lower_record.rs | 20 ++-- crates/it-lilo/src/lowerer/memory_writer.rs | 82 ++++++++++++---- crates/it-lilo/src/lowerer/mod.rs | 15 ++- crates/it-lilo/src/traits/allocatable.rs | 9 +- crates/it-memory-traits/src/lib.rs | 50 +++++++--- wasmer-it/src/ast.rs | 8 +- wasmer-it/src/decoders/binary.rs | 9 +- wasmer-it/src/decoders/wat.rs | 10 +- .../src/interpreter/instructions/arrays.rs | 71 +++++++++----- .../interpreter/instructions/byte_arrays.rs | 8 +- .../src/interpreter/instructions/call_core.rs | 2 +- .../instructions/lilo/li_helper.rs | 39 ++++---- .../instructions/lilo/lo_helper.rs | 48 +++++---- wasmer-it/src/interpreter/instructions/mod.rs | 32 +++--- .../src/interpreter/instructions/records.rs | 69 +++++++++---- .../src/interpreter/instructions/strings.rs | 8 +- wasmer-it/src/interpreter/mod.rs | 80 +++++++++------ wasmer-it/src/interpreter/wasm/structures.rs | 77 ++++++++++----- wasmer-it/src/macros.rs | 13 +-- 25 files changed, 687 insertions(+), 382 deletions(-) diff --git a/crates/it-lilo/src/lifter/lift_array.rs b/crates/it-lilo/src/lifter/lift_array.rs index ae8d381..2759ddd 100644 --- a/crates/it-lilo/src/lifter/lift_array.rs +++ b/crates/it-lilo/src/lifter/lift_array.rs @@ -24,8 +24,13 @@ use crate::IValue; use it_memory_traits::MemoryView; -pub fn array_lift_memory( - lifter: &ILifter<'_, R, MV>, +pub fn array_lift_memory< + R: RecordResolvable, + MV: MemoryView, + Store: it_memory_traits::Store, +>( + store: &mut ::ActualStore<'_>, + lifter: &ILifter<'_, R, MV, Store>, value_type: &IType, offset: u32, elements_count: u32, @@ -37,45 +42,48 @@ pub fn array_lift_memory( let reader = &lifter.reader; let ivalues = match value_type { - IType::Boolean => reader.read_bool_array(offset, elements_count)?, - IType::S8 => reader.read_s8_array(offset, elements_count)?, - IType::S16 => reader.read_s16_array(offset, elements_count)?, - IType::S32 => reader.read_s32_array(offset, elements_count)?, - IType::S64 => reader.read_s64_array(offset, elements_count)?, - IType::I32 => reader.read_i32_array(offset, elements_count)?, - IType::I64 => reader.read_i64_array(offset, elements_count)?, - IType::U8 => reader.read_u8_array(offset, elements_count)?, - IType::U16 => reader.read_u16_array(offset, elements_count)?, - IType::U32 => reader.read_u32_array(offset, elements_count)?, - IType::U64 => reader.read_u64_array(offset, elements_count)?, - IType::F32 => reader.read_f32_array(offset, elements_count)?, - IType::F64 => reader.read_f64_array(offset, elements_count)?, - IType::String => read_string_array(lifter, offset, elements_count)?, - IType::ByteArray => read_array_array(lifter, &IType::U8, offset, elements_count)?, - IType::Array(ty) => read_array_array(lifter, &ty, offset, elements_count)?, + IType::Boolean => reader.read_bool_array(store, offset, elements_count)?, + IType::S8 => reader.read_s8_array(store, offset, elements_count)?, + IType::S16 => reader.read_s16_array(store, offset, elements_count)?, + IType::S32 => reader.read_s32_array(store, offset, elements_count)?, + IType::S64 => reader.read_s64_array(store, offset, elements_count)?, + IType::I32 => reader.read_i32_array(store, offset, elements_count)?, + IType::I64 => reader.read_i64_array(store, offset, elements_count)?, + IType::U8 => reader.read_u8_array(store, offset, elements_count)?, + IType::U16 => reader.read_u16_array(store, offset, elements_count)?, + IType::U32 => reader.read_u32_array(store, offset, elements_count)?, + IType::U64 => reader.read_u64_array(store, offset, elements_count)?, + IType::F32 => reader.read_f32_array(store, offset, elements_count)?, + IType::F64 => reader.read_f64_array(store, offset, elements_count)?, + IType::String => read_string_array(store, lifter, offset, elements_count)?, + IType::ByteArray => read_array_array(store, lifter, &IType::U8, offset, elements_count)?, + IType::Array(ty) => read_array_array(store, lifter, &ty, offset, elements_count)?, IType::Record(record_type_id) => { - read_record_array(lifter, *record_type_id, offset, elements_count)? + read_record_array(store, lifter, *record_type_id, offset, elements_count)? } }; Ok(IValue::Array(ivalues)) } -fn read_string_array( - lifter: &ILifter<'_, R, MV>, +fn read_string_array, Store: it_memory_traits::Store>( + store: &mut ::ActualStore<'_>, + lifter: &ILifter<'_, R, MV, Store>, offset: u32, elements_count: u32, ) -> LiResult> { let mut result = Vec::with_capacity(elements_count as usize); - let seq_reader = lifter - .reader - .sequential_reader(offset, ser_type_size(&IType::String) * elements_count)?; + let seq_reader = lifter.reader.sequential_reader( + store, + offset, + ser_type_size(&IType::String) * elements_count, + )?; for _ in 0..elements_count { - let offset = seq_reader.read_u32(); - let size = seq_reader.read_u32(); + let offset = seq_reader.read_u32(store); + let size = seq_reader.read_u32(store); - let raw_str = lifter.reader.read_raw_u8_array(offset, size)?; + let raw_str = lifter.reader.read_raw_u8_array(store, offset, size)?; let str = String::from_utf8(raw_str)?; result.push(IValue::String(str)); } @@ -83,44 +91,49 @@ fn read_string_array( Ok(result) } -fn read_array_array( - lifter: &ILifter<'_, R, MV>, +fn read_array_array, Store: it_memory_traits::Store>( + store: &mut ::ActualStore<'_>, + lifter: &ILifter<'_, R, MV, Store>, ty: &IType, offset: u32, elements_count: u32, ) -> LiResult> { let mut result = Vec::with_capacity(elements_count as usize); - let seq_reader = lifter - .reader - .sequential_reader(offset, ser_type_size(ty) * elements_count)?; + let seq_reader = + lifter + .reader + .sequential_reader(store, offset, ser_type_size(ty) * elements_count)?; for _ in 0..elements_count { - let offset = seq_reader.read_u32(); - let size = seq_reader.read_u32(); + let offset = seq_reader.read_u32(store); + let size = seq_reader.read_u32(store); - let array = array_lift_memory(lifter, ty, offset, size)?; + let array = array_lift_memory(store, lifter, ty, offset, size)?; result.push(array); } Ok(result) } -fn read_record_array( - lifter: &ILifter<'_, R, MV>, +fn read_record_array, Store: it_memory_traits::Store>( + store: &mut ::ActualStore<'_>, + lifter: &ILifter<'_, R, MV, Store>, record_type_id: u64, offset: u32, elements_count: u32, ) -> LiResult> { let mut result = Vec::with_capacity(elements_count as usize); - let seq_reader = lifter - .reader - .sequential_reader(offset, ser_type_size(&IType::Record(0)) * elements_count)?; + let seq_reader = lifter.reader.sequential_reader( + store, + offset, + ser_type_size(&IType::Record(0)) * elements_count, + )?; for _ in 0..elements_count { - let offset = seq_reader.read_u32(); + let offset = seq_reader.read_u32(store); let record_ty = lifter.resolver.resolve_record(record_type_id)?; - let record = record_lift_memory(lifter, &record_ty, offset)?; + let record = record_lift_memory(store, lifter, &record_ty, offset)?; result.push(record); } diff --git a/crates/it-lilo/src/lifter/lift_record.rs b/crates/it-lilo/src/lifter/lift_record.rs index 396077a..3d3eb6c 100644 --- a/crates/it-lilo/src/lifter/lift_record.rs +++ b/crates/it-lilo/src/lifter/lift_record.rs @@ -28,8 +28,13 @@ use crate::NEVec; use it_memory_traits::MemoryView; -pub fn record_lift_memory( - lifter: &ILifter<'_, R, MV>, +pub fn record_lift_memory< + R: RecordResolvable, + MV: MemoryView, + Store: it_memory_traits::Store, +>( + store: &mut ::ActualStore<'_>, + lifter: &ILifter<'_, R, MV, Store>, record_type: &IRecordType, offset: u32, ) -> LiResult { @@ -37,28 +42,28 @@ pub fn record_lift_memory( let size = record_size(record_type); let reader = &lifter.reader; - let seq_reader = reader.sequential_reader(offset, size)?; + let seq_reader = reader.sequential_reader(store, offset, size)?; for field in (*record_type.fields).iter() { match &field.ty { - IType::Boolean => values.push(IValue::Boolean(seq_reader.read_u8() != 0)), - IType::S8 => values.push(IValue::S8(seq_reader.read_i8())), - IType::S16 => values.push(IValue::S16(seq_reader.read_i16())), - IType::S32 => values.push(IValue::S32(seq_reader.read_i32())), - IType::S64 => values.push(IValue::S64(seq_reader.read_i64())), - IType::I32 => values.push(IValue::I32(seq_reader.read_i32())), - IType::I64 => values.push(IValue::I64(seq_reader.read_i64())), - IType::U8 => values.push(IValue::U8(seq_reader.read_u8())), - IType::U16 => values.push(IValue::U16(seq_reader.read_u16())), - IType::U32 => values.push(IValue::U32(seq_reader.read_u32())), - IType::U64 => values.push(IValue::U64(seq_reader.read_u64())), - IType::F32 => values.push(IValue::F32(seq_reader.read_f32())), - IType::F64 => values.push(IValue::F64(seq_reader.read_f64())), - IType::String => values.push(IValue::String(read_string(reader, &seq_reader)?)), - IType::ByteArray => values.push(read_byte_array(reader, &seq_reader)?), - IType::Array(ty) => values.push(read_array(&lifter, &seq_reader, &**ty)?), + IType::Boolean => values.push(IValue::Boolean(seq_reader.read_u8(store) != 0)), + IType::S8 => values.push(IValue::S8(seq_reader.read_i8(store))), + IType::S16 => values.push(IValue::S16(seq_reader.read_i16(store))), + IType::S32 => values.push(IValue::S32(seq_reader.read_i32(store))), + IType::S64 => values.push(IValue::S64(seq_reader.read_i64(store))), + IType::I32 => values.push(IValue::I32(seq_reader.read_i32(store))), + IType::I64 => values.push(IValue::I64(seq_reader.read_i64(store))), + IType::U8 => values.push(IValue::U8(seq_reader.read_u8(store))), + IType::U16 => values.push(IValue::U16(seq_reader.read_u16(store))), + IType::U32 => values.push(IValue::U32(seq_reader.read_u32(store))), + IType::U64 => values.push(IValue::U64(seq_reader.read_u64(store))), + IType::F32 => values.push(IValue::F32(seq_reader.read_f32(store))), + IType::F64 => values.push(IValue::F64(seq_reader.read_f64(store))), + IType::String => values.push(IValue::String(read_string(store, reader, &seq_reader)?)), + IType::ByteArray => values.push(read_byte_array(store, reader, &seq_reader)?), + IType::Array(ty) => values.push(read_array(store, &lifter, &seq_reader, &**ty)?), IType::Record(record_type_id) => { - values.push(read_record(lifter, &seq_reader, *record_type_id)?) + values.push(read_record(store, lifter, &seq_reader, *record_type_id)?) } } } @@ -69,50 +74,54 @@ pub fn record_lift_memory( Ok(IValue::Record(record)) } -fn read_string( - reader: &MemoryReader, - seq_reader: &SequentialReader<'_, MV>, +fn read_string, Store: it_memory_traits::Store>( + store: &mut ::ActualStore<'_>, + reader: &MemoryReader, + seq_reader: &SequentialReader<'_, MV, Store>, ) -> LiResult { - let offset = seq_reader.read_u32(); - let size = seq_reader.read_u32(); + let offset = seq_reader.read_u32(store); + let size = seq_reader.read_u32(store); - let string_mem = reader.read_raw_u8_array(offset, size)?; + let string_mem = reader.read_raw_u8_array(store, offset, size)?; let string = String::from_utf8(string_mem)?; Ok(string) } -fn read_byte_array( - reader: &MemoryReader, - seq_reader: &SequentialReader<'_, MV>, +fn read_byte_array, Store: it_memory_traits::Store>( + store: &mut ::ActualStore<'_>, + reader: &MemoryReader, + seq_reader: &SequentialReader<'_, MV, Store>, ) -> LiResult { - let offset = seq_reader.read_u32(); - let size = seq_reader.read_u32(); + let offset = seq_reader.read_u32(store); + let size = seq_reader.read_u32(store); - let array = reader.read_raw_u8_array(offset, size)?; + let array = reader.read_raw_u8_array(store, offset, size)?; Ok(IValue::ByteArray(array)) } -fn read_array( - lifter: &ILifter<'_, R, MV>, - seq_reader: &SequentialReader<'_, MV>, +fn read_array, Store: it_memory_traits::Store>( + store: &mut ::ActualStore<'_>, + lifter: &ILifter<'_, R, MV, Store>, + seq_reader: &SequentialReader<'_, MV, Store>, value_type: &IType, ) -> LiResult { - let offset = seq_reader.read_u32(); - let size = seq_reader.read_u32(); + let offset = seq_reader.read_u32(store); + let size = seq_reader.read_u32(store); - super::array_lift_memory(lifter, value_type, offset, size) + super::array_lift_memory(store, lifter, value_type, offset, size) } -fn read_record( - lifter: &ILifter<'_, R, MV>, - seq_reader: &SequentialReader<'_, MV>, +fn read_record, Store: it_memory_traits::Store>( + store: &mut ::ActualStore<'_>, + lifter: &ILifter<'_, R, MV, Store>, + seq_reader: &SequentialReader<'_, MV, Store>, record_type_id: u64, ) -> LiResult { - let offset = seq_reader.read_u32(); + let offset = seq_reader.read_u32(store); let record_type = lifter.resolver.resolve_record(record_type_id)?; - record_lift_memory(lifter, &record_type, offset) + record_lift_memory(store, lifter, &record_type, offset) } diff --git a/crates/it-lilo/src/lifter/macros.rs b/crates/it-lilo/src/lifter/macros.rs index d78a293..3eacf85 100644 --- a/crates/it-lilo/src/lifter/macros.rs +++ b/crates/it-lilo/src/lifter/macros.rs @@ -16,37 +16,40 @@ #[macro_export] macro_rules! value_der { - ($self:expr, $offset:expr, @seq_start $($ids:tt),* @seq_end) => { - [$($self.reader.view.read_byte($offset + $ids)),+] + ($self:expr, $store:expr, $offset:expr, @seq_start $($ids:tt),* @seq_end) => { + [$($self.reader.view.read_byte($store, $offset + $ids)),+] }; - ($self:expr, $offset:expr, 1) => { - crate::value_der!($self, $offset, @seq_start 0 @seq_end) + ($self:expr, $store:expr, $offset:expr, 1) => { + crate::value_der!($self, $store, $offset, @seq_start 0 @seq_end) }; - ($self:expr, $offset:expr, 2) => { - crate::value_der!($self, $offset, @seq_start 0, 1 @seq_end) + ($self:expr, $store:expr, $offset:expr, 2) => { + crate::value_der!($self, $store, $offset, @seq_start 0, 1 @seq_end) }; - ($self:expr, $offset:expr, 4) => { - crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3 @seq_end) + ($self:expr, $store:expr, $offset:expr, 4) => { + crate::value_der!($self, $store, $offset, @seq_start 0, 1, 2, 3 @seq_end) }; - ($self:expr, $offset:expr, 8) => { - crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7 @seq_end) + ($self:expr, $store:expr, $offset:expr, 8) => { + crate::value_der!($self, $store, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7 @seq_end) }; - ($self:expr, $offset:expr, 16) => { - crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 @seq_end) + ($self:expr, $store:expr, $offset:expr, 16) => { + crate::value_der!($self, $store, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 @seq_end) }; } #[macro_export] macro_rules! read_ty { ($func_name:ident, $ty:ty, 1) => { - pub fn $func_name(&self) -> $ty { + pub fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty { let offset = self.offset.get(); - let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 1)); + let result = <$ty>::from_le_bytes(crate::value_der!(self, store, offset, 1)); self.offset.set(offset + 1); result @@ -54,9 +57,12 @@ macro_rules! read_ty { }; ($func_name:ident, $ty:ty, 2) => { - pub fn $func_name(&self) -> $ty { + pub fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty { let offset = self.offset.get(); - let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 2)); + let result = <$ty>::from_le_bytes(crate::value_der!(self, store, offset, 2)); self.offset.set(offset + 2); result @@ -64,9 +70,12 @@ macro_rules! read_ty { }; ($func_name:ident, $ty:ty, 4) => { - pub fn $func_name(&self) -> $ty { + pub fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty { let offset = self.offset.get(); - let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 4)); + let result = <$ty>::from_le_bytes(crate::value_der!(self, store, offset, 4)); self.offset.set(offset + 4); result @@ -74,9 +83,12 @@ macro_rules! read_ty { }; ($func_name:ident, $ty:ty, 8) => { - pub fn $func_name(&self) -> $ty { + pub fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty { let offset = self.offset.get(); - let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 8)); + let result = <$ty>::from_le_bytes(crate::value_der!(self, store, offset, 8)); self.offset.set(offset + 8); result @@ -84,9 +96,12 @@ macro_rules! read_ty { }; ($func_name:ident, $ty:ty, 16) => { - pub fn $func_name(&self) -> $ty { + pub fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty { let offset = self.offset.get(); - let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 16)); + let result = <$ty>::from_le_bytes(crate::value_der!(self, store, offset, 16)); self.offset.set(offset + 16); result @@ -97,23 +112,38 @@ macro_rules! read_ty { #[macro_export] macro_rules! read_ty_decl { ($func_name:ident, $ty:ty, 1) => { - fn $func_name(&self) -> $ty; + fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty; }; ($func_name:ident, $ty:ty, 2) => { - fn $func_name(&self) -> $ty; + fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty; }; ($func_name:ident, $ty:ty, 4) => { - fn $func_name(&self) -> $ty; + fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty; }; ($func_name:ident, $ty:ty, 8) => { - fn $func_name(&self) -> $ty; + fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty; }; ($func_name:ident, $ty:ty, 16) => { - fn $func_name(&self) -> $ty; + fn $func_name( + &self, + store: &mut ::ActualStore<'_>, + ) -> $ty; }; } @@ -122,15 +152,19 @@ macro_rules! read_array_ty { ($func_name:ident, $ty:ident, $ity:ident) => { pub fn $func_name( &self, + store: &mut ::ActualStore<'_>, offset: u32, elements_count: u32, ) -> super::LiResult> { - let reader = self - .sequential_reader(offset, (std::mem::size_of::<$ty>() as u32) * elements_count)?; + let reader = self.sequential_reader( + store, + offset, + (std::mem::size_of::<$ty>() as u32) * elements_count, + )?; let mut result = Vec::with_capacity(elements_count as usize); for _ in 0..elements_count { - let value = paste::paste! { reader.[]()}; + let value = paste::paste! { reader.[](store)}; result.push(IValue::$ity(value)); } diff --git a/crates/it-lilo/src/lifter/memory_reader.rs b/crates/it-lilo/src/lifter/memory_reader.rs index a616adf..d745f2a 100644 --- a/crates/it-lilo/src/lifter/memory_reader.rs +++ b/crates/it-lilo/src/lifter/memory_reader.rs @@ -22,43 +22,63 @@ use crate::IValue; use it_memory_traits::MemoryView; use std::cell::Cell; +use std::marker::PhantomData; -pub struct MemoryReader { +pub struct MemoryReader, Store: it_memory_traits::Store> { pub(self) view: MV, + _phantom: PhantomData, } -impl MemoryReader { +impl, Store: it_memory_traits::Store> MemoryReader { pub fn new(view: MV) -> Self { - Self { view } + Self { + view, + _phantom: PhantomData, + } } /// Returns reader that allows read sequentially. It's important that memory limit is checked /// only inside this function. All others functions of the returned reader don't have any /// checks assuming that reader is well-formed. - pub fn sequential_reader(&self, offset: u32, size: u32) -> LiResult> { - self.view.check_bounds(offset, size)?; + pub fn sequential_reader( + &self, + store: &mut ::ActualStore<'_>, + offset: u32, + size: u32, + ) -> LiResult> { + self.view.check_bounds(store, offset, size)?; let seq_reader = SequentialReader::new(&self, offset); Ok(seq_reader) } - pub fn read_raw_u8_array(&self, offset: u32, elements_count: u32) -> LiResult> { - let reader = self.sequential_reader(offset, elements_count)?; + pub fn read_raw_u8_array( + &self, + store: &mut ::ActualStore<'_>, + offset: u32, + elements_count: u32, + ) -> LiResult> { + let reader = self.sequential_reader(store, offset, elements_count)?; let mut result = Vec::with_capacity(elements_count as usize); for _ in 0..elements_count { - let value = reader.read_u8(); + let value = reader.read_u8(store); result.push(value); } Ok(result) } - pub fn read_bool_array(&self, offset: u32, elements_count: u32) -> LiResult> { - let reader = self.sequential_reader(offset, elements_count)?; + pub fn read_bool_array( + &self, + store: &mut ::ActualStore<'_>, + offset: u32, + elements_count: u32, + ) -> LiResult> { + let reader = self.sequential_reader(store, offset, elements_count)?; let mut result = Vec::with_capacity(elements_count as usize); for _ in 0..elements_count { - let value = reader.read_u8(); + let value = reader.read_u8(store); result.push(IValue::Boolean(value != 0)); } @@ -79,21 +99,24 @@ impl MemoryReader { read_array_ty!(read_f64_array, f64, F64); } -pub struct SequentialReader<'r, MV: MemoryView> { - reader: &'r MemoryReader, +pub struct SequentialReader<'r, MV: MemoryView, Store: it_memory_traits::Store> { + reader: &'r MemoryReader, offset: Cell, } -impl<'r, MV: MemoryView> SequentialReader<'r, MV> { - fn new(reader: &'r MemoryReader, offset: u32) -> Self { +impl<'r, MV: MemoryView, Store: it_memory_traits::Store> SequentialReader<'r, MV, Store> { + fn new(reader: &'r MemoryReader, offset: u32) -> Self { Self { reader, offset: Cell::new(offset), } } - pub fn read_bool(&self) -> bool { - self.read_u8() != 0 + pub fn read_bool( + &self, + store: &mut ::ActualStore<'_>, + ) -> bool { + self.read_u8(store) != 0 } read_ty!(read_u8, u8, 1); diff --git a/crates/it-lilo/src/lifter/mod.rs b/crates/it-lilo/src/lifter/mod.rs index 83c822e..d48d261 100644 --- a/crates/it-lilo/src/lifter/mod.rs +++ b/crates/it-lilo/src/lifter/mod.rs @@ -31,14 +31,19 @@ pub use it_memory_traits::MemoryView; pub type LiResult = std::result::Result; -pub struct ILifter<'r, R: RecordResolvable, MV> { - pub reader: MemoryReader, +pub struct ILifter<'r, R: RecordResolvable, MV: MemoryView, Store: it_memory_traits::Store> { + pub reader: MemoryReader, pub resolver: &'r R, } -impl<'r, R: RecordResolvable, MV: MemoryView> ILifter<'r, R, MV> { +impl<'r, R: RecordResolvable, MV: MemoryView, Store: it_memory_traits::Store> + ILifter<'r, R, MV, Store> +{ pub fn new(view: MV, resolver: &'r R) -> Self { let reader = MemoryReader::new(view); - Self { reader, resolver } + Self { + reader, + resolver, + } } } diff --git a/crates/it-lilo/src/lowerer/lower_array.rs b/crates/it-lilo/src/lowerer/lower_array.rs index 3563e82..e75db1a 100644 --- a/crates/it-lilo/src/lowerer/lower_array.rs +++ b/crates/it-lilo/src/lowerer/lower_array.rs @@ -38,8 +38,13 @@ impl LoweredArray { } } -pub fn array_lower_memory, MV: MemoryView>( - lowerer: &ILowerer<'_, A, MV>, +pub fn array_lower_memory< + A: Allocatable, + MV: MemoryView, + Store: it_memory_traits::Store, +>( + store: &mut ::ActualStore<'_>, + lowerer: &mut ILowerer<'_, A, MV, Store>, array_values: Vec, ) -> LoResult { if array_values.is_empty() { @@ -49,45 +54,49 @@ pub fn array_lower_memory, MV: MemoryView>( let elements_count = array_values.len() as u32; let size = ser_value_size(&array_values[0]) * elements_count; let type_tag = type_tag_form_ivalue(&array_values[0]); - let seq_writer = lowerer.writer.sequential_writer(size, type_tag)?; + let seq_writer = lowerer.writer.sequential_writer(store, size, type_tag)?; // here it's known that all interface values have the same type for value in array_values { match value { - IValue::Boolean(value) => seq_writer.write_u8(&lowerer.writer, value as _), - IValue::S8(value) => seq_writer.write_u8(&lowerer.writer, value as _), - IValue::S16(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::S32(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::S64(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::U8(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::U16(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::U32(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::U64(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::I32(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::I64(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::F32(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), - IValue::F64(value) => seq_writer.write_bytes(&lowerer.writer, &value.to_le_bytes()), + IValue::Boolean(value) => seq_writer.write_u8(store, &lowerer.writer, value as _), + IValue::S8(value) => seq_writer.write_u8(store, &lowerer.writer, value as _), + IValue::S16(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::S32(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::S64(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::U8(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::U16(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::U32(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::U64(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::I32(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::I64(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::F32(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), + IValue::F64(value) => seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes()), IValue::String(value) => { - let offset = lowerer.writer.write_bytes(&value.as_bytes())? as u32; + let offset = lowerer.writer.write_bytes(store, &value.as_bytes())? as u32; - seq_writer.write_bytes(&lowerer.writer, &offset.to_le_bytes()); - seq_writer.write_bytes(&lowerer.writer, &(value.len() as u32).to_le_bytes()); + seq_writer.write_bytes(store, &lowerer.writer, &offset.to_le_bytes()); + seq_writer.write_bytes(store, &lowerer.writer, &(value.len() as u32).to_le_bytes()); } IValue::ByteArray(values) => { - let offset = lowerer.writer.write_bytes(&values)? as u32; + let offset = lowerer.writer.write_bytes(store, &values)? as u32; - seq_writer.write_bytes(&lowerer.writer, &offset.to_le_bytes()); - seq_writer.write_bytes(&lowerer.writer, &(values.len() as u32).to_le_bytes()); + seq_writer.write_bytes(store, &lowerer.writer, &offset.to_le_bytes()); + seq_writer.write_bytes( + store, + &lowerer.writer, + &(values.len() as u32).to_le_bytes(), + ); } IValue::Array(values) => { - let LoweredArray { offset, size } = array_lower_memory(lowerer, values)?; + let LoweredArray { offset, size } = array_lower_memory(store, lowerer, values)?; - seq_writer.write_bytes(&lowerer.writer, &(offset as u32).to_le_bytes()); - seq_writer.write_bytes(&lowerer.writer, &(size as u32).to_le_bytes()); + seq_writer.write_bytes(store, &lowerer.writer, &(offset as u32).to_le_bytes()); + seq_writer.write_bytes(store, &lowerer.writer, &(size as u32).to_le_bytes()); } IValue::Record(values) => { - let offset = super::record_lower_memory(lowerer, values)? as u32; - seq_writer.write_bytes(&lowerer.writer, &offset.to_le_bytes()); + let offset = super::record_lower_memory(store, lowerer, values)? as u32; + seq_writer.write_bytes(store, &lowerer.writer, &offset.to_le_bytes()); } } } diff --git a/crates/it-lilo/src/lowerer/lower_record.rs b/crates/it-lilo/src/lowerer/lower_record.rs index b52534e..1098978 100644 --- a/crates/it-lilo/src/lowerer/lower_record.rs +++ b/crates/it-lilo/src/lowerer/lower_record.rs @@ -23,8 +23,13 @@ use crate::NEVec; use it_memory_traits::MemoryView; -pub fn record_lower_memory, MV: MemoryView>( - lowerer: &ILowerer<'_, A, MV>, +pub fn record_lower_memory< + A: Allocatable, + MV: MemoryView, + Store: it_memory_traits::Store, +>( + store: &mut ::ActualStore<'_>, + lowerer: &mut ILowerer<'_, A, MV, Store>, values: NEVec, ) -> LoResult { let average_field_size = 4; @@ -47,34 +52,35 @@ pub fn record_lower_memory, MV: MemoryView>( 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 offset = lowerer.writer.write_bytes(value.as_bytes())?; + let offset = lowerer.writer.write_bytes(store, value.as_bytes())?; result.extend_from_slice(&offset.to_le_bytes()); result.extend_from_slice(&(value.len() as u32).to_le_bytes()); } IValue::ByteArray(value) => { - let offset = lowerer.writer.write_bytes(&value)?; + let offset = lowerer.writer.write_bytes(store, &value)?; result.extend_from_slice(&offset.to_le_bytes()); result.extend_from_slice(&(value.len() as u32).to_le_bytes()); } IValue::Array(values) => { - let LoweredArray { offset, size } = super::array_lower_memory(lowerer, values)?; + let LoweredArray { offset, size } = + super::array_lower_memory(store, lowerer, values)?; result.extend_from_slice(&(offset).to_le_bytes()); result.extend_from_slice(&(size).to_le_bytes()); } IValue::Record(values) => { - let offset = record_lower_memory(lowerer, values)?; + let offset = record_lower_memory(store, lowerer, values)?; result.extend_from_slice(&offset.to_le_bytes()); } } } - let result_pointer = lowerer.writer.write_bytes(&result)?; + let result_pointer = lowerer.writer.write_bytes(store, &result)?; Ok(result_pointer) } diff --git a/crates/it-lilo/src/lowerer/memory_writer.rs b/crates/it-lilo/src/lowerer/memory_writer.rs index c186be6..d3075c5 100644 --- a/crates/it-lilo/src/lowerer/memory_writer.rs +++ b/crates/it-lilo/src/lowerer/memory_writer.rs @@ -21,31 +21,50 @@ use crate::utils::type_tag_form_itype; use it_memory_traits::MemoryView; use std::cell::{Cell, RefCell}; +use std::marker::PhantomData; -pub struct MemoryWriter<'i, R: Allocatable, MV: MemoryView> { - heap_manager: &'i R, +pub struct MemoryWriter< + 'i, + R: Allocatable, + MV: MemoryView, + Store: it_memory_traits::Store, +> { + heap_manager: &'i mut R, view: RefCell, + _store: PhantomData, } -impl<'i, A: Allocatable, MV: MemoryView> MemoryWriter<'i, A, MV> { - pub fn new(view: MV, heap_manager: &'i A) -> LoResult { +impl<'i, A: Allocatable, MV: MemoryView, Store: it_memory_traits::Store> + MemoryWriter<'i, A, MV, Store> +{ + pub fn new(view: MV, heap_manager: &'i mut A) -> LoResult { let writer = Self { heap_manager, view: RefCell::new(view), + _store: PhantomData, }; Ok(writer) } - pub fn write_bytes(&self, bytes: &[u8]) -> LoResult { + pub fn write_bytes( + &mut self, + store: &mut ::ActualStore<'_>, + bytes: &[u8], + ) -> LoResult { let byte_type_tag = type_tag_form_itype(&crate::IType::U8); - let seq_writer = self.sequential_writer(bytes.len() as u32, byte_type_tag)?; - seq_writer.write_bytes(&self, bytes); + let seq_writer = self.sequential_writer(store, bytes.len() as u32, byte_type_tag)?; + seq_writer.write_bytes(store, &self, bytes); Ok(seq_writer.start_offset()) } - pub fn sequential_writer(&self, size: u32, type_tag: u32) -> LoResult { - let (offset, view) = self.heap_manager.allocate(size, type_tag)?; + pub fn sequential_writer( + &mut self, + store: &mut ::ActualStore<'_>, + size: u32, + type_tag: u32, + ) -> LoResult { + let (offset, view) = self.heap_manager.allocate(store, size, type_tag)?; self.view.replace(view); let seq_writer = SequentialWriter::new(offset); Ok(seq_writer) @@ -69,51 +88,72 @@ impl SequentialWriter { self.start_offset } - pub fn write_array, const N: usize>( + pub fn write_array< + MV: MemoryView, + Store: it_memory_traits::Store, + A: Allocatable, + const N: usize, + >( &self, - writer: &MemoryWriter<'_, A, MV>, + store: &mut ::ActualStore<'_>, + writer: &MemoryWriter<'_, A, MV, Store>, values: [u8; N], ) { let offset = self.offset.get(); - writer.view.borrow().write_bytes(offset, &values); + writer.view.borrow().write_bytes(store, offset, &values); self.offset.set(offset + N as u32); } - pub fn write_u8>( + pub fn write_u8< + MV: MemoryView, + Store: it_memory_traits::Store, + A: Allocatable, + >( &self, - writer: &MemoryWriter<'_, A, MV>, + store: &mut ::ActualStore<'_>, + writer: &MemoryWriter<'_, A, MV, Store>, value: u8, ) { let offset = self.offset.get(); - writer.view.borrow().write_byte(offset, value); + writer.view.borrow().write_byte(store, offset, value); self.offset.set(offset + 1); } - pub fn write_u32>( + pub fn write_u32< + MV: MemoryView, + Store: it_memory_traits::Store, + A: Allocatable, + >( &self, - writer: &MemoryWriter<'_, A, MV>, + store: &mut ::ActualStore<'_>, + writer: &MemoryWriter<'_, A, MV, Store>, value: u32, ) { let offset = self.offset.get(); let value = value.to_le_bytes(); - writer.view.borrow().write_bytes(offset, &value); + writer.view.borrow().write_bytes(store, offset, &value); self.offset.set(offset + 4); } - pub fn write_bytes>( + pub fn write_bytes< + MV: MemoryView, + Store: it_memory_traits::Store, + A: Allocatable, + >( &self, - writer: &MemoryWriter<'_, A, MV>, + store: &mut ::ActualStore<'_>, + writer: &MemoryWriter<'_, A, MV, Store>, bytes: &[u8], ) { let offset = self.offset.get(); - writer.view.borrow().write_bytes(offset, bytes); + writer.view.borrow().write_bytes(store, offset, bytes); self.offset.set(offset + bytes.len() as u32); } diff --git a/crates/it-lilo/src/lowerer/mod.rs b/crates/it-lilo/src/lowerer/mod.rs index 575d321..f945c8c 100644 --- a/crates/it-lilo/src/lowerer/mod.rs +++ b/crates/it-lilo/src/lowerer/mod.rs @@ -31,12 +31,19 @@ pub use it_memory_traits::MemoryView; pub type LoResult = std::result::Result; -pub struct ILowerer<'m, A: Allocatable, MV: MemoryView> { - pub writer: MemoryWriter<'m, A, MV>, +pub struct ILowerer< + 'm, + A: Allocatable, + MV: MemoryView, + Store: it_memory_traits::Store, +> { + pub writer: MemoryWriter<'m, A, MV, Store>, } -impl<'m, A: Allocatable, MV: MemoryView> ILowerer<'m, A, MV> { - pub fn new(view: MV, allocatable: &'m A) -> LoResult { +impl<'m, A: Allocatable, MV: MemoryView, Store: it_memory_traits::Store> + ILowerer<'m, A, MV, Store> +{ + pub fn new(view: MV, allocatable: &'m mut A) -> LoResult { let writer = MemoryWriter::new(view, allocatable)?; let lowerer = Self { writer }; diff --git a/crates/it-lilo/src/traits/allocatable.rs b/crates/it-lilo/src/traits/allocatable.rs index 986d64d..6e94578 100644 --- a/crates/it-lilo/src/traits/allocatable.rs +++ b/crates/it-lilo/src/traits/allocatable.rs @@ -19,8 +19,13 @@ use thiserror::Error as ThisError; pub const DEFAULT_MEMORY_INDEX: usize = 0; -pub trait Allocatable { - fn allocate(&self, size: u32, type_tag: u32) -> Result<(u32, MV), AllocatableError>; +pub trait Allocatable, Store: it_memory_traits::Store> { + fn allocate( + &mut self, + store: &mut ::ActualStore<'_>, + size: u32, + type_tag: u32, + ) -> Result<(u32, MV), AllocatableError>; } #[derive(Debug, ThisError)] diff --git a/crates/it-memory-traits/src/lib.rs b/crates/it-memory-traits/src/lib.rs index b38e03a..6045dab 100644 --- a/crates/it-memory-traits/src/lib.rs +++ b/crates/it-memory-traits/src/lib.rs @@ -18,44 +18,72 @@ mod errors; pub use errors::MemoryAccessError; -pub trait MemoryReadable { +pub trait Store { + type ActualStore<'c>; +} + +pub trait MemoryReadable { /// This function will panic if the `offset` is out of bounds. /// It is caller's responsibility to check if the offset is in bounds /// using `MemoryView::check_bounds` function - fn read_byte(&self, offset: u32) -> u8; + fn read_byte(&self, store: &mut ::ActualStore<'_>, offset: u32) -> u8; /// This function will panic if `[offset..offset + COUNT]` is out of bounds. /// It is caller's responsibility to check if the offset is in bounds /// using `MemoryView::check_bounds` function. - fn read_array(&self, offset: u32) -> [u8; COUNT]; + fn read_array( + &self, + store: &mut ::ActualStore<'_>, + offset: u32, + ) -> [u8; COUNT]; /// This function will panic if `[offset..offset + size]` is out of bounds. /// It is caller's responsibility to check if the offset is in bounds /// using `MemoryView::check_bounds` function. - fn read_vec(&self, offset: u32, size: u32) -> Vec; + fn read_vec( + &self, + store: &mut ::ActualStore<'_>, + offset: u32, + size: u32, + ) -> Vec; } -pub trait MemoryWritable { +pub trait MemoryWritable { /// This function will panic if `offset` is out of bounds. /// It is caller's responsibility to check if the offset is in bounds /// using `MemoryView::check_bounds` function. - fn write_byte(&self, offset: u32, value: u8); + fn write_byte( + &self, + store: &mut ::ActualStore<'_>, + offset: u32, + value: u8, + ); /// This function will panic if `[offset..offset + bytes.len()]`.is out of bounds. /// It is caller's responsibility to check if the offset is in bounds /// using `MemoryView::check_bounds` function. - fn write_bytes(&self, offset: u32, bytes: &[u8]); + fn write_bytes( + &self, + store: &mut ::ActualStore<'_>, + offset: u32, + bytes: &[u8], + ); } -pub trait MemoryView: MemoryWritable + MemoryReadable { +pub trait MemoryView: MemoryWritable + MemoryReadable { /// For optimization purposes, user must check bounds first, then try read-write to memory /// `MemoryWritable` and `MemoryReadable` functions will panic in case of out of bounds access` - fn check_bounds(&self, offset: u32, size: u32) -> Result<(), MemoryAccessError>; + fn check_bounds( + &self, + store: &mut ::ActualStore<'_>, + offset: u32, + size: u32, + ) -> Result<(), MemoryAccessError>; } -pub trait Memory +pub trait Memory where - View: MemoryView, + View: MemoryView, { fn view(&self) -> View; } diff --git a/wasmer-it/src/ast.rs b/wasmer-it/src/ast.rs index 4be9751..b6e8862 100644 --- a/wasmer-it/src/ast.rs +++ b/wasmer-it/src/ast.rs @@ -5,8 +5,8 @@ use crate::{interpreter::Instruction, IRecordType, IType}; use serde::Deserialize; use serde::Serialize; -use std::rc::Rc; use std::str; +use std::sync::Arc; /// Represents the kind of type. #[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)] @@ -38,10 +38,10 @@ pub enum Type { /// ``` Function { /// Types for the parameters (`(param (name i32))`). - arguments: Rc>, + arguments: Arc>, /// Types for the results (`(result …)`). - output_types: Rc>, + output_types: Arc>, }, /// A record type, like: @@ -49,7 +49,7 @@ pub enum Type { /// ```wasm,ignore /// (@interface type (record string i32)) /// ``` - Record(Rc), + Record(Arc), } /// Represents an imported function. diff --git a/wasmer-it/src/decoders/binary.rs b/wasmer-it/src/decoders/binary.rs index 309d518..01e273d 100644 --- a/wasmer-it/src/decoders/binary.rs +++ b/wasmer-it/src/decoders/binary.rs @@ -8,8 +8,7 @@ use nom::{ error::{make_error, ErrorKind, ParseError}, Err, IResult, }; -use std::rc::Rc; -use std::{convert::TryFrom, str}; +use std::{convert::TryFrom, str, sync::Arc}; /// Parse a type kind. impl TryFrom for TypeKind { @@ -386,15 +385,15 @@ fn types<'input, E: ParseError<&'input [u8]>>( consume!((input, output_types) = list(input, ty)?); types.push(Type::Function { - arguments: Rc::new(arguments), - output_types: Rc::new(output_types), + arguments: Arc::new(arguments), + output_types: Arc::new(output_types), }); } TypeKind::Record => { consume!((input, record_type) = record_type(input)?); - types.push(Type::Record(Rc::new(record_type))); + types.push(Type::Record(Arc::new(record_type))); } } } diff --git a/wasmer-it/src/decoders/wat.rs b/wasmer-it/src/decoders/wat.rs index 8561b09..1313626 100644 --- a/wasmer-it/src/decoders/wat.rs +++ b/wasmer-it/src/decoders/wat.rs @@ -2,11 +2,13 @@ use crate::IType; use crate::{ast::*, interpreter::Instruction}; -use std::rc::Rc; + pub use wast::parser::ParseBuffer as Buffer; use wast::parser::{self, Cursor, Parse, Parser, Peek, Result}; pub use wast::Error; +use std::sync::Arc; + mod keyword { pub use wast::{ custom_keyword, @@ -491,11 +493,11 @@ impl<'a> Parse<'a> for Type { } Ok(Type::Function { - arguments: Rc::new(arguments), - output_types: Rc::new(output_types), + arguments: Arc::new(arguments), + output_types: Arc::new(output_types), }) } else if lookahead.peek::() { - Ok(Type::Record(Rc::new(parser.parse()?))) + Ok(Type::Record(Arc::new(parser.parse()?))) } else { Err(lookahead.error()) } diff --git a/wasmer-it/src/interpreter/instructions/arrays.rs b/wasmer-it/src/interpreter/instructions/arrays.rs index c52b2a9..ca8cf1f 100644 --- a/wasmer-it/src/interpreter/instructions/arrays.rs +++ b/wasmer-it/src/interpreter/instructions/arrays.rs @@ -12,17 +12,30 @@ use it_lilo::lowerer::ILowerer; use it_lilo::lowerer::LoweredArray; use it_lilo::traits::DEFAULT_MEMORY_INDEX; -pub(crate) fn array_lift_memory( +pub(crate) fn array_lift_memory( instruction: Instruction, value_type: IType, -) -> crate::interpreter::ExecutableInstruction +) -> crate::interpreter::ExecutableInstruction< + Instance, + Export, + LocalImport, + Memory, + MemoryView, + Store, +> 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, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance< + Export, + LocalImport, + Memory, + MemoryView, + Store, + >, + Store: crate::interpreter::wasm::structures::Store, { #[allow(unused_imports)] use crate::interpreter::stack::Stackable; @@ -61,8 +74,9 @@ where let li_helper = lilo::LiHelper::new(&**instance); let lifter = ILifter::new(memory_view, &li_helper); - let array = it_lilo::lifter::array_lift_memory(&lifter, &value_type, offset, size) - .map_err(|e| InstructionError::from_li(instruction.clone(), e))?; + let array = + it_lilo::lifter::array_lift_memory(runtime.store, &lifter, &value_type, offset, size) + .map_err(|e| InstructionError::from_li(instruction.clone(), e))?; log::trace!("array.lift_memory: pushing {:?} on the stack", array); runtime.stack.push(array); @@ -72,17 +86,30 @@ where }) } -pub(crate) fn array_lower_memory( +pub(crate) fn array_lower_memory( instruction: Instruction, value_type: IType, -) -> crate::interpreter::ExecutableInstruction +) -> crate::interpreter::ExecutableInstruction< + Instance, + Export, + LocalImport, + Memory, + MemoryView, + Store, +> 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, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance< + Export, + LocalImport, + Memory, + MemoryView, + Store, + >, + Store: crate::interpreter::wasm::structures::Store, { #[allow(unused_imports)] use crate::interpreter::stack::Stackable; @@ -117,12 +144,12 @@ where })? .view(); - let lo_helper = lilo::LoHelper::new(&**instance); - let lowerer = ILowerer::new(memory_view, &lo_helper) + let mut lo_helper = lilo::LoHelper::new(&**instance); + let mut lowerer = ILowerer::new(memory_view, &mut lo_helper) .map_err(|e| InstructionError::from_lo(instruction.clone(), e))?; let LoweredArray { offset, size } = - it_lilo::lowerer::array_lower_memory(&lowerer, values) + it_lilo::lowerer::array_lower_memory(runtime.store, &mut lowerer, values) .map_err(|e| InstructionError::from_lo(instruction.clone(), e))?; log::trace!( @@ -136,7 +163,7 @@ where Ok(()) } IValue::ByteArray(bytearray) => { - let lo_helper = lilo::LoHelper::new(&**instance); + let mut lo_helper = lilo::LoHelper::new(&**instance); let memory_index = DEFAULT_MEMORY_INDEX; let memory_view = instance .memory(memory_index) @@ -148,12 +175,12 @@ where })? .view(); - let lowerer = ILowerer::new(memory_view, &lo_helper) + let mut lowerer = ILowerer::new(memory_view, &mut lo_helper) .map_err(|e| InstructionError::from_lo(instruction.clone(), e))?; let offset = lowerer .writer - .write_bytes(&bytearray) + .write_bytes(runtime.store, &bytearray) .map_err(|e| InstructionError::from_lo(instruction.clone(), e))?; let size = bytearray.len(); diff --git a/wasmer-it/src/interpreter/instructions/byte_arrays.rs b/wasmer-it/src/interpreter/instructions/byte_arrays.rs index 5600f03..2c7be43 100644 --- a/wasmer-it/src/interpreter/instructions/byte_arrays.rs +++ b/wasmer-it/src/interpreter/instructions/byte_arrays.rs @@ -42,10 +42,10 @@ executable_instruction!( } memory_view - .check_bounds(pointer, length) + .check_bounds(runtime.store, pointer, length) .map_err(|e| InstructionError::from_memory_access(instruction.clone(), e))?; - let data = memory_view.read_vec(pointer, length); + let data = memory_view.read_vec(runtime.store, pointer, length); log::debug!("byte_array.lift_memory: pushing {:?} on the stack", data); runtime.stack.push(IValue::ByteArray(data)); @@ -82,10 +82,10 @@ executable_instruction!( .view(); memory_view - .check_bounds(array_pointer, array.len() as u32) + .check_bounds(runtime.store, array_pointer, array.len() as u32) .map_err(|e| InstructionError::from_memory_access(instruction.clone(), e))?; - memory_view.write_bytes(array_pointer, &array); + memory_view.write_bytes(runtime.store, array_pointer, &array); log::debug!("string.lower_memory: pushing {}, {} on the stack", array_pointer, length); runtime.stack.push(IValue::I32(array_pointer as i32)); diff --git a/wasmer-it/src/interpreter/instructions/call_core.rs b/wasmer-it/src/interpreter/instructions/call_core.rs index faf2f1b..729d8ca 100644 --- a/wasmer-it/src/interpreter/instructions/call_core.rs +++ b/wasmer-it/src/interpreter/instructions/call_core.rs @@ -34,7 +34,7 @@ executable_instruction!( log::debug!("call-core: calling {} with arguments: {:?}", local_or_import.name(), inputs); - let outputs = local_or_import.call(&inputs).map_err(|_| { + let outputs = local_or_import.call(runtime.store, &inputs).map_err(|_| { InstructionError::from_error_kind( instruction.clone(), InstructionErrorKind::LocalOrImportCall { diff --git a/wasmer-it/src/interpreter/instructions/lilo/li_helper.rs b/wasmer-it/src/interpreter/instructions/lilo/li_helper.rs index 2a605ca..0857b9b 100644 --- a/wasmer-it/src/interpreter/instructions/lilo/li_helper.rs +++ b/wasmer-it/src/interpreter/instructions/lilo/li_helper.rs @@ -6,29 +6,32 @@ use it_lilo::traits::RecordResolvableError; use std::marker::PhantomData; -pub struct LiHelper<'i, Instance, Export, LocalImport, Memory, MemoryView> +pub struct LiHelper<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> where Export: wasm::structures::Export + 'i, - LocalImport: wasm::structures::LocalImport + 'i, - Memory: wasm::structures::Memory + 'i, - MemoryView: wasm::structures::MemoryView + 'i, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport + 'i, + Memory: wasm::structures::Memory + 'i, + MemoryView: wasm::structures::MemoryView + 'i, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { pub(crate) instance: &'i Instance, _export: PhantomData, _local_import: PhantomData, _memory: PhantomData, _memory_view: PhantomData, + _store: PhantomData, } -impl<'i, Instance, Export, LocalImport, Memory, MemoryView> - LiHelper<'i, Instance, Export, LocalImport, Memory, MemoryView> +impl<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> + LiHelper<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> where Export: wasm::structures::Export + 'i, - LocalImport: wasm::structures::LocalImport + 'i, - Memory: wasm::structures::Memory + 'i, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport + 'i, + Memory: wasm::structures::Memory + 'i, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { pub(crate) fn new(instance: &'i Instance) -> Self { Self { @@ -37,18 +40,20 @@ where _local_import: PhantomData, _memory: PhantomData, _memory_view: PhantomData, + _store: PhantomData, } } } -impl<'i, Instance, Export, LocalImport, Memory, MemoryView> RecordResolvable - for LiHelper<'i, Instance, Export, LocalImport, Memory, MemoryView> +impl<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> RecordResolvable + for LiHelper<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> where Export: wasm::structures::Export + 'i, - LocalImport: wasm::structures::LocalImport + 'i, - Memory: wasm::structures::Memory + 'i, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport + 'i, + Memory: wasm::structures::Memory + 'i, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { fn resolve_record(&self, record_type_id: u64) -> Result<&IRecordType, RecordResolvableError> { let record = self diff --git a/wasmer-it/src/interpreter/instructions/lilo/lo_helper.rs b/wasmer-it/src/interpreter/instructions/lilo/lo_helper.rs index c7b45cf..c1556df 100644 --- a/wasmer-it/src/interpreter/instructions/lilo/lo_helper.rs +++ b/wasmer-it/src/interpreter/instructions/lilo/lo_helper.rs @@ -8,29 +8,32 @@ use it_lilo::traits::DEFAULT_MEMORY_INDEX; use std::marker::PhantomData; -pub struct LoHelper<'i, Instance, Export, LocalImport, Memory, MemoryView> +pub struct LoHelper<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> where Export: wasm::structures::Export + 'i, - LocalImport: wasm::structures::LocalImport + 'i, - Memory: wasm::structures::Memory + 'i, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport + 'i, + Memory: wasm::structures::Memory + 'i, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { pub(crate) instance: &'i Instance, _export: PhantomData, _local_import: PhantomData, _memory: PhantomData, _memory_view: PhantomData, + _store: PhantomData, } -impl<'i, Instance, Export, LocalImport, Memory, MemoryView> - LoHelper<'i, Instance, Export, LocalImport, Memory, MemoryView> +impl<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> + LoHelper<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> where Export: wasm::structures::Export + 'i, - LocalImport: wasm::structures::LocalImport + 'i, - Memory: wasm::structures::Memory + 'i, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport + 'i, + Memory: wasm::structures::Memory + 'i, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { pub(crate) fn new(instance: &'i Instance) -> Self { Self { @@ -39,20 +42,27 @@ where _local_import: PhantomData, _memory: PhantomData, _memory_view: PhantomData, + _store: PhantomData, } } } -impl<'i, Instance, Export, LocalImport, Memory, MemoryView> Allocatable - for LoHelper<'i, Instance, Export, LocalImport, Memory, MemoryView> +impl<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> Allocatable + for LoHelper<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> where Export: wasm::structures::Export + 'i, - LocalImport: wasm::structures::LocalImport + 'i, - Memory: wasm::structures::Memory + 'i, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport + 'i, + Memory: wasm::structures::Memory + 'i, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { - fn allocate(&self, size: u32, type_tag: u32) -> Result<(u32, MemoryView), AllocatableError> { + fn allocate( + &mut self, + store: &mut ::ActualStore<'_>, + size: u32, + type_tag: u32, + ) -> Result<(u32, MemoryView), AllocatableError> { use AllocatableError::*; use crate::interpreter::instructions::ALLOCATE_FUNC_INDEX; @@ -76,7 +86,7 @@ where .map_err(|_| AllocateFuncIncompatibleSignature)?; let outcome = local_or_import - .call(&inputs) + .call(store, &inputs) .map_err(|_| AllocateCallFailed)?; if outcome.len() != 1 { diff --git a/wasmer-it/src/interpreter/instructions/mod.rs b/wasmer-it/src/interpreter/instructions/mod.rs index b396f7f..d3d186a 100644 --- a/wasmer-it/src/interpreter/instructions/mod.rs +++ b/wasmer-it/src/interpreter/instructions/mod.rs @@ -233,6 +233,7 @@ pub(crate) fn check_function_signature< LocalImport, Memory, MemoryView, + Store, >( instance: &'instance Instance, local_import: &LocalImport, @@ -240,10 +241,11 @@ pub(crate) fn check_function_signature< ) -> Result<(), InstructionErrorKind> where Export: wasm::structures::Export + 'instance, - LocalImport: wasm::structures::LocalImport + 'instance, - Memory: wasm::structures::Memory + 'instance, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport + 'instance, + Memory: wasm::structures::Memory + 'instance, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { let func_inputs = local_import.arguments(); @@ -262,6 +264,7 @@ pub(crate) fn is_value_compatible_to_type< LocalImport, Memory, MemoryView, + Store, >( instance: &'instance Instance, interface_type: &IType, @@ -269,10 +272,11 @@ pub(crate) fn is_value_compatible_to_type< ) -> Result<(), InstructionErrorKind> where Export: wasm::structures::Export + 'instance, - LocalImport: wasm::structures::LocalImport + 'instance, - Memory: wasm::structures::Memory + 'instance, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport + 'instance, + Memory: wasm::structures::Memory + 'instance, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { match (&interface_type, interface_value) { (IType::Boolean, IValue::Boolean(_)) => Ok(()), @@ -333,6 +337,7 @@ pub(crate) fn is_record_fields_compatible_to_type< LocalImport, Memory, MemoryView, + Store, >( instance: &'instance Instance, record_type_id: u64, @@ -340,10 +345,11 @@ pub(crate) fn is_record_fields_compatible_to_type< ) -> Result<(), InstructionErrorKind> where Export: wasm::structures::Export + 'instance, - LocalImport: wasm::structures::LocalImport + 'instance, - Memory: wasm::structures::Memory + 'instance, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport + 'instance, + Memory: wasm::structures::Memory + 'instance, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { let record_type = instance .wit_record_by_id(record_type_id) @@ -453,7 +459,7 @@ pub(crate) mod tests { } } - impl wasm::structures::Memory for Memory { + impl wasm::structures::Memory for Memory { fn view(&self) -> MemoryView { self.view.clone() } diff --git a/wasmer-it/src/interpreter/instructions/records.rs b/wasmer-it/src/interpreter/instructions/records.rs index ebdb76b..6d5c064 100644 --- a/wasmer-it/src/interpreter/instructions/records.rs +++ b/wasmer-it/src/interpreter/instructions/records.rs @@ -9,17 +9,30 @@ use it_lilo::lifter::ILifter; use it_lilo::lowerer::ILowerer; use it_lilo::traits::DEFAULT_MEMORY_INDEX; -pub(crate) fn record_lift_memory( +pub(crate) fn record_lift_memory( record_type_id: u64, instruction: Instruction, -) -> crate::interpreter::ExecutableInstruction +) -> crate::interpreter::ExecutableInstruction< + Instance, + Export, + LocalImport, + Memory, + MemoryView, + Store, +> 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, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance< + Export, + LocalImport, + Memory, + MemoryView, + Store, + >, + Store: crate::interpreter::wasm::structures::Store, { #[allow(unused_imports)] use crate::interpreter::stack::Stackable; @@ -62,7 +75,7 @@ where let li_helper = lilo::LiHelper::new(&**instance); let lifter = ILifter::new(memory_view, &li_helper); - let record = it_lilo::lifter::record_lift_memory(&lifter, record_type, offset) + let record = it_lilo::lifter::record_lift_memory(runtime.store, &lifter, record_type, offset) .map_err(|e| InstructionError::from_li(instruction.clone(), e))?; log::debug!("record.lift_memory: pushing {:?} on the stack", record); @@ -73,17 +86,30 @@ where }) } -pub(crate) fn record_lower_memory( +pub(crate) fn record_lower_memory( record_type_id: u64, instruction: Instruction, -) -> crate::interpreter::ExecutableInstruction +) -> crate::interpreter::ExecutableInstruction< + Instance, + Export, + LocalImport, + Memory, + MemoryView, + Store, +> 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, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance< + Export, + LocalImport, + Memory, + MemoryView, + Store, + >, + Store: crate::interpreter::wasm::structures::Store, { #[allow(unused_imports)] use crate::interpreter::stack::Stackable; @@ -113,12 +139,15 @@ where })? .view(); - let lo_helper = lilo::LoHelper::new(&**instance); - let memory_writer = ILowerer::new(memory_view, &lo_helper) + let mut lo_helper = lilo::LoHelper::new(&**instance); + let mut memory_writer = ILowerer::new(memory_view, &mut lo_helper) .map_err(|e| InstructionError::from_lo(instruction.clone(), e))?; - let offset = - it_lilo::lowerer::record_lower_memory(&memory_writer, record_fields) - .map_err(|e| InstructionError::from_lo(instruction.clone(), e))?; + let offset = it_lilo::lowerer::record_lower_memory( + runtime.store, + &mut memory_writer, + record_fields, + ) + .map_err(|e| InstructionError::from_lo(instruction.clone(), e))?; log::debug!("record.lower_memory: pushing {} on the stack", offset); runtime.stack.push(IValue::I32(offset as i32)); diff --git a/wasmer-it/src/interpreter/instructions/strings.rs b/wasmer-it/src/interpreter/instructions/strings.rs index 730f6b2..972702e 100644 --- a/wasmer-it/src/interpreter/instructions/strings.rs +++ b/wasmer-it/src/interpreter/instructions/strings.rs @@ -41,10 +41,10 @@ executable_instruction!( } memory_view - .check_bounds(pointer, length) + .check_bounds(runtime.store, pointer, length) .map_err(|e| InstructionError::from_memory_access(instruction.clone(), e))?; - let data = memory_view.read_vec(pointer, length); + let data = memory_view.read_vec(runtime.store, pointer, length); let string = String::from_utf8(data) .map_err(|error| InstructionError::from_error_kind(instruction.clone(), InstructionErrorKind::String(error)))?; @@ -83,10 +83,10 @@ executable_instruction!( })?; memory_view - .check_bounds(string_pointer, string_length) + .check_bounds(runtime.store, string_pointer, string_length) .map_err(|e| InstructionError::from_memory_access(instruction.clone(), e))?; - memory_view.write_bytes(string_pointer, string_bytes); + memory_view.write_bytes(runtime.store, string_pointer, string_bytes); log::debug!("string.lower_memory: pushing {}, {} on the stack", string_pointer, string_length); runtime.stack.push(IValue::I32(string_pointer as i32)); diff --git a/wasmer-it/src/interpreter/mod.rs b/wasmer-it/src/interpreter/mod.rs index 4fbcbdb..0f611fe 100644 --- a/wasmer-it/src/interpreter/mod.rs +++ b/wasmer-it/src/interpreter/mod.rs @@ -13,13 +13,25 @@ use std::{convert::TryFrom, marker::PhantomData}; /// Represents the `Runtime`, which is used by an adapter to execute /// its instructions. -pub(crate) struct Runtime<'invocation, 'instance, Instance, Export, LocalImport, Memory, MemoryView> -where +pub(crate) struct Runtime< + 'invocation, + 'instance, + 'store_ref, + 'store_param, + Instance, + Export, + LocalImport, + Memory, + MemoryView, + Store, +> where Export: wasm::structures::Export + 'instance, - LocalImport: wasm::structures::LocalImport + 'instance, - Memory: wasm::structures::Memory + 'instance, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance + 'instance, + LocalImport: wasm::structures::LocalImport + 'instance, + Memory: wasm::structures::Memory + 'instance, + MemoryView: wasm::structures::MemoryView, + Instance: + wasm::structures::Instance + 'instance, + Store: wasm::structures::Store, { /// The invocation inputs are all the arguments received by an /// adapter. @@ -31,17 +43,20 @@ where /// The WebAssembly module instance. It is used by adapter's /// instructions. wasm_instance: &'instance mut Instance, + store: &'store_ref mut ::ActualStore<'store_param>, /// Phantom data. - _phantom: PhantomData<(Export, LocalImport, Memory, MemoryView)>, + _phantom: PhantomData<(Export, LocalImport, Memory, MemoryView, Store)>, } /// Type alias for an executable instruction. It's an implementation /// details, but an instruction is a boxed closure instance. -pub(crate) type ExecutableInstruction = Box< - dyn Fn(&mut Runtime) -> InstructionResult<()> - + Send, ->; +pub(crate) type ExecutableInstruction = + Box< + dyn Fn(&mut Runtime, ) -> InstructionResult<()> + + Send + + Sync, + >; /// An interpreter is the central piece of this crate. It is a set of /// executable instructions. Each instruction takes the runtime as @@ -121,31 +136,33 @@ pub(crate) type ExecutableInstruction +pub struct Interpreter where Export: wasm::structures::Export, - LocalImport: wasm::structures::LocalImport, - Memory: wasm::structures::Memory, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport, + Memory: wasm::structures::Memory, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { executable_instructions: - Vec>, + Vec>, } -impl - Interpreter +impl + Interpreter where Export: wasm::structures::Export, - LocalImport: wasm::structures::LocalImport, - Memory: wasm::structures::Memory, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport, + Memory: wasm::structures::Memory, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { fn iter( &self, ) -> impl Iterator< - Item = &ExecutableInstruction, + Item = &ExecutableInstruction, > + '_ { self.executable_instructions.iter() } @@ -159,11 +176,13 @@ where &self, invocation_inputs: &[IValue], wasm_instance: &mut Instance, + wasm_store: &mut ::ActualStore<'_>, ) -> InterpreterResult> { let mut runtime = Runtime { invocation_inputs, stack: Stack::new(), wasm_instance, + store: wasm_store, _phantom: PhantomData, }; @@ -176,14 +195,15 @@ where } /// Transforms a `Vec` into an `Interpreter`. -impl TryFrom> - for Interpreter +impl TryFrom> + for Interpreter where Export: wasm::structures::Export, - LocalImport: wasm::structures::LocalImport, - Memory: wasm::structures::Memory, - MemoryView: wasm::structures::MemoryView, - Instance: wasm::structures::Instance, + LocalImport: wasm::structures::LocalImport, + Memory: wasm::structures::Memory, + MemoryView: wasm::structures::MemoryView, + Instance: wasm::structures::Instance, + Store: wasm::structures::Store, { type Error = (); diff --git a/wasmer-it/src/interpreter/wasm/structures.rs b/wasmer-it/src/interpreter/wasm/structures.rs index be50a4e..d0f8ad3 100644 --- a/wasmer-it/src/interpreter/wasm/structures.rs +++ b/wasmer-it/src/interpreter/wasm/structures.rs @@ -4,7 +4,7 @@ use crate::ast::FunctionArg; use crate::IRecordType; use crate::IType; use crate::IValue; -use std::rc::Rc; +use std::sync::Arc; pub use it_memory_traits::{Memory, MemoryAccessError, MemoryView}; use it_memory_traits::{MemoryReadable, MemoryWritable}; @@ -54,27 +54,34 @@ pub trait Export { fn call(&self, arguments: &[IValue]) -> Result, ()>; } -pub trait LocalImport { +pub trait LocalImport { fn name(&self) -> &str; fn inputs_cardinality(&self) -> usize; fn outputs_cardinality(&self) -> usize; fn arguments(&self) -> &[FunctionArg]; fn outputs(&self) -> &[IType]; - fn call(&self, arguments: &[IValue]) -> Result, ()>; + fn call( + &self, + store: &mut ::ActualStore<'_>, + arguments: &[IValue], + ) -> Result, ()>; } -pub trait Instance +pub use it_memory_traits::Store; + +pub trait Instance where E: Export, - LI: LocalImport, - M: Memory, - MV: MemoryView, + LI: LocalImport, + M: Memory, + MV: MemoryView, + S: Store, { fn export(&self, export_name: &str) -> Option<&E>; fn local_or_import(&self, index: I) -> Option<&LI>; fn memory(&self, index: usize) -> Option<&M>; fn memory_view(&self, index: usize) -> Option; - fn wit_record_by_id(&self, index: u64) -> Option<&Rc>; + fn wit_record_by_id(&self, index: u64) -> Option<&Arc>; } impl Export for () { @@ -103,7 +110,7 @@ impl Export for () { } } -impl LocalImport for () { +impl LocalImport for () { fn name(&self) -> &str { "" } @@ -124,35 +131,54 @@ impl LocalImport for () { &[] } - fn call(&self, _arguments: &[IValue]) -> Result, ()> { + fn call( + &self, + _store: &mut ::ActualStore<'_>, + _arguments: &[IValue], + ) -> Result, ()> { Err(()) } } pub(crate) struct EmptyMemoryView; -impl MemoryWritable for EmptyMemoryView { - fn write_byte(&self, _offset: u32, _value: u8) {} +impl MemoryWritable for EmptyMemoryView { + fn write_byte(&self, _store: &mut ::ActualStore<'_>, _offset: u32, _value: u8) {} - fn write_bytes(&self, _offset: u32, _bytes: &[u8]) {} + fn write_bytes(&self, _store: &mut ::ActualStore<'_>, _offset: u32, _bytes: &[u8]) { + } } -impl MemoryReadable for EmptyMemoryView { - fn read_byte(&self, _offset: u32) -> u8 { +impl MemoryReadable for EmptyMemoryView { + fn read_byte(&self, _store: &mut ::ActualStore<'_>, _offset: u32) -> u8 { 0 } - fn read_array(&self, _offset: u32) -> [u8; COUNT] { + fn read_array( + &self, + _store: &mut ::ActualStore<'_>, + _offset: u32, + ) -> [u8; COUNT] { [0; COUNT] } - fn read_vec(&self, _offset: u32, _size: u32) -> Vec { + fn read_vec( + &self, + _store: &mut ::ActualStore<'_>, + _offset: u32, + _size: u32, + ) -> Vec { Vec::default() } } -impl MemoryView for EmptyMemoryView { - fn check_bounds(&self, offset: u32, size: u32) -> Result<(), MemoryAccessError> { +impl MemoryView for EmptyMemoryView { + fn check_bounds( + &self, + _store: &mut ::ActualStore<'_>, + offset: u32, + size: u32, + ) -> Result<(), MemoryAccessError> { Err(MemoryAccessError::OutOfBounds { size, offset, @@ -161,18 +187,19 @@ impl MemoryView for EmptyMemoryView { } } -impl Memory for () { +impl Memory for () { fn view(&self) -> EmptyMemoryView { EmptyMemoryView } } -impl Instance for () +impl Instance for () where E: Export, - LI: LocalImport, - M: Memory, - MV: MemoryView, + LI: LocalImport, + M: Memory, + MV: MemoryView, + S: Store, { fn export(&self, _export_name: &str) -> Option<&E> { None @@ -190,7 +217,7 @@ where None } - fn wit_record_by_id(&self, _index: u64) -> Option<&Rc> { + fn wit_record_by_id(&self, _index: u64) -> Option<&Arc> { None } } diff --git a/wasmer-it/src/macros.rs b/wasmer-it/src/macros.rs index 897fad7..b791fe0 100644 --- a/wasmer-it/src/macros.rs +++ b/wasmer-it/src/macros.rs @@ -67,15 +67,16 @@ macro_rules! consume { /// Check the existing executable instruction to get more examples. macro_rules! executable_instruction { ($name:ident ( $($argument_name:ident: $argument_type:ty),* ) -> _ $implementation:block ) => { - pub(crate) fn $name( + pub(crate) fn $name( $($argument_name: $argument_type),* - ) -> crate::interpreter::ExecutableInstruction + ) -> crate::interpreter::ExecutableInstruction 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, + LocalImport: crate::interpreter::wasm::structures::LocalImport, + Memory: crate::interpreter::wasm::structures::Memory, + MemoryView: crate::interpreter::wasm::structures::MemoryView, + Instance: crate::interpreter::wasm::structures::Instance, + Store: crate::interpreter::wasm::structures::Store, { #[allow(unused_imports)] use crate::interpreter::{stack::Stackable};