mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 07:10:21 +00:00
feat!: pass a context object through the API to the wasm engine functions (#34)
This commit is contained in:
parent
da020b8c6a
commit
06e0dd40d6
@ -24,8 +24,13 @@ use crate::IValue;
|
||||
|
||||
use it_memory_traits::MemoryView;
|
||||
|
||||
pub fn array_lift_memory<R: RecordResolvable, MV: MemoryView>(
|
||||
lifter: &ILifter<'_, R, MV>,
|
||||
pub fn array_lift_memory<
|
||||
R: RecordResolvable,
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
lifter: &ILifter<'_, R, MV, Store>,
|
||||
value_type: &IType,
|
||||
offset: u32,
|
||||
elements_count: u32,
|
||||
@ -37,45 +42,48 @@ pub fn array_lift_memory<R: RecordResolvable, MV: MemoryView>(
|
||||
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<R: RecordResolvable, MV: MemoryView>(
|
||||
lifter: &ILifter<'_, R, MV>,
|
||||
fn read_string_array<R: RecordResolvable, MV: MemoryView<Store>, Store: it_memory_traits::Store>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
lifter: &ILifter<'_, R, MV, Store>,
|
||||
offset: u32,
|
||||
elements_count: u32,
|
||||
) -> LiResult<Vec<IValue>> {
|
||||
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<R: RecordResolvable, MV: MemoryView>(
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn read_array_array<R: RecordResolvable, MV: MemoryView>(
|
||||
lifter: &ILifter<'_, R, MV>,
|
||||
fn read_array_array<R: RecordResolvable, MV: MemoryView<Store>, Store: it_memory_traits::Store>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
lifter: &ILifter<'_, R, MV, Store>,
|
||||
ty: &IType,
|
||||
offset: u32,
|
||||
elements_count: u32,
|
||||
) -> LiResult<Vec<IValue>> {
|
||||
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<R: RecordResolvable, MV: MemoryView>(
|
||||
lifter: &ILifter<'_, R, MV>,
|
||||
fn read_record_array<R: RecordResolvable, MV: MemoryView<Store>, Store: it_memory_traits::Store>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
lifter: &ILifter<'_, R, MV, Store>,
|
||||
record_type_id: u64,
|
||||
offset: u32,
|
||||
elements_count: u32,
|
||||
) -> LiResult<Vec<IValue>> {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,13 @@ use crate::NEVec;
|
||||
|
||||
use it_memory_traits::MemoryView;
|
||||
|
||||
pub fn record_lift_memory<R: RecordResolvable, MV: MemoryView>(
|
||||
lifter: &ILifter<'_, R, MV>,
|
||||
pub fn record_lift_memory<
|
||||
R: RecordResolvable,
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
lifter: &ILifter<'_, R, MV, Store>,
|
||||
record_type: &IRecordType,
|
||||
offset: u32,
|
||||
) -> LiResult<IValue> {
|
||||
@ -37,28 +42,28 @@ pub fn record_lift_memory<R: RecordResolvable, MV: MemoryView>(
|
||||
|
||||
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<R: RecordResolvable, MV: MemoryView>(
|
||||
Ok(IValue::Record(record))
|
||||
}
|
||||
|
||||
fn read_string<MV: MemoryView>(
|
||||
reader: &MemoryReader<MV>,
|
||||
seq_reader: &SequentialReader<'_, MV>,
|
||||
fn read_string<MV: MemoryView<Store>, Store: it_memory_traits::Store>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
reader: &MemoryReader<MV, Store>,
|
||||
seq_reader: &SequentialReader<'_, MV, Store>,
|
||||
) -> LiResult<String> {
|
||||
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<MV: MemoryView>(
|
||||
reader: &MemoryReader<MV>,
|
||||
seq_reader: &SequentialReader<'_, MV>,
|
||||
fn read_byte_array<MV: MemoryView<Store>, Store: it_memory_traits::Store>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
reader: &MemoryReader<MV, Store>,
|
||||
seq_reader: &SequentialReader<'_, MV, Store>,
|
||||
) -> LiResult<IValue> {
|
||||
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<R: RecordResolvable, MV: MemoryView>(
|
||||
lifter: &ILifter<'_, R, MV>,
|
||||
seq_reader: &SequentialReader<'_, MV>,
|
||||
fn read_array<R: RecordResolvable, MV: MemoryView<Store>, Store: it_memory_traits::Store>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
lifter: &ILifter<'_, R, MV, Store>,
|
||||
seq_reader: &SequentialReader<'_, MV, Store>,
|
||||
value_type: &IType,
|
||||
) -> LiResult<IValue> {
|
||||
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<R: RecordResolvable, MV: MemoryView>(
|
||||
lifter: &ILifter<'_, R, MV>,
|
||||
seq_reader: &SequentialReader<'_, MV>,
|
||||
fn read_record<R: RecordResolvable, MV: MemoryView<Store>, Store: it_memory_traits::Store>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
lifter: &ILifter<'_, R, MV, Store>,
|
||||
seq_reader: &SequentialReader<'_, MV, Store>,
|
||||
record_type_id: u64,
|
||||
) -> LiResult<IValue> {
|
||||
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)
|
||||
}
|
||||
|
@ -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 <Store as it_memory_traits::Store>::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 <Store as it_memory_traits::Store>::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 <Store as it_memory_traits::Store>::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 <Store as it_memory_traits::Store>::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 <Store as it_memory_traits::Store>::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 <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
) -> $ty;
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 2) => {
|
||||
fn $func_name(&self) -> $ty;
|
||||
fn $func_name(
|
||||
&self,
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
) -> $ty;
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 4) => {
|
||||
fn $func_name(&self) -> $ty;
|
||||
fn $func_name(
|
||||
&self,
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
) -> $ty;
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 8) => {
|
||||
fn $func_name(&self) -> $ty;
|
||||
fn $func_name(
|
||||
&self,
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
) -> $ty;
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 16) => {
|
||||
fn $func_name(&self) -> $ty;
|
||||
fn $func_name(
|
||||
&self,
|
||||
store: &mut <Store as it_memory_traits::Store>::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 <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
offset: u32,
|
||||
elements_count: u32,
|
||||
) -> super::LiResult<Vec<crate::IValue>> {
|
||||
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.[<read_ $ty>]()};
|
||||
let value = paste::paste! { reader.[<read_ $ty>](store)};
|
||||
result.push(IValue::$ity(value));
|
||||
}
|
||||
|
||||
|
@ -22,43 +22,63 @@ use crate::IValue;
|
||||
use it_memory_traits::MemoryView;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct MemoryReader<MV> {
|
||||
pub struct MemoryReader<MV: MemoryView<Store>, Store: it_memory_traits::Store> {
|
||||
pub(self) view: MV,
|
||||
_phantom: PhantomData<Store>,
|
||||
}
|
||||
|
||||
impl<MV: MemoryView> MemoryReader<MV> {
|
||||
impl<MV: MemoryView<Store>, Store: it_memory_traits::Store> MemoryReader<MV, Store> {
|
||||
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<SequentialReader<'_, MV>> {
|
||||
self.view.check_bounds(offset, size)?;
|
||||
pub fn sequential_reader(
|
||||
&self,
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
offset: u32,
|
||||
size: u32,
|
||||
) -> LiResult<SequentialReader<'_, MV, Store>> {
|
||||
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<Vec<u8>> {
|
||||
let reader = self.sequential_reader(offset, elements_count)?;
|
||||
pub fn read_raw_u8_array(
|
||||
&self,
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
offset: u32,
|
||||
elements_count: u32,
|
||||
) -> LiResult<Vec<u8>> {
|
||||
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<Vec<IValue>> {
|
||||
let reader = self.sequential_reader(offset, elements_count)?;
|
||||
pub fn read_bool_array(
|
||||
&self,
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
offset: u32,
|
||||
elements_count: u32,
|
||||
) -> LiResult<Vec<IValue>> {
|
||||
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<MV: MemoryView> MemoryReader<MV> {
|
||||
read_array_ty!(read_f64_array, f64, F64);
|
||||
}
|
||||
|
||||
pub struct SequentialReader<'r, MV: MemoryView> {
|
||||
reader: &'r MemoryReader<MV>,
|
||||
pub struct SequentialReader<'r, MV: MemoryView<Store>, Store: it_memory_traits::Store> {
|
||||
reader: &'r MemoryReader<MV, Store>,
|
||||
offset: Cell<u32>,
|
||||
}
|
||||
|
||||
impl<'r, MV: MemoryView> SequentialReader<'r, MV> {
|
||||
fn new(reader: &'r MemoryReader<MV>, offset: u32) -> Self {
|
||||
impl<'r, MV: MemoryView<Store>, Store: it_memory_traits::Store> SequentialReader<'r, MV, Store> {
|
||||
fn new(reader: &'r MemoryReader<MV, Store>, 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 <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
) -> bool {
|
||||
self.read_u8(store) != 0
|
||||
}
|
||||
|
||||
read_ty!(read_u8, u8, 1);
|
||||
|
@ -31,14 +31,19 @@ pub use it_memory_traits::MemoryView;
|
||||
|
||||
pub type LiResult<T> = std::result::Result<T, error::LiError>;
|
||||
|
||||
pub struct ILifter<'r, R: RecordResolvable, MV> {
|
||||
pub reader: MemoryReader<MV>,
|
||||
pub struct ILifter<'r, R: RecordResolvable, MV: MemoryView<Store>, Store: it_memory_traits::Store> {
|
||||
pub reader: MemoryReader<MV, Store>,
|
||||
pub resolver: &'r R,
|
||||
}
|
||||
|
||||
impl<'r, R: RecordResolvable, MV: MemoryView> ILifter<'r, R, MV> {
|
||||
impl<'r, R: RecordResolvable, MV: MemoryView<Store>, 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,8 +38,13 @@ impl LoweredArray {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn array_lower_memory<A: Allocatable<MV>, MV: MemoryView>(
|
||||
lowerer: &ILowerer<'_, A, MV>,
|
||||
pub fn array_lower_memory<
|
||||
A: Allocatable<MV, Store>,
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
lowerer: &mut ILowerer<'_, A, MV, Store>,
|
||||
array_values: Vec<IValue>,
|
||||
) -> LoResult<LoweredArray> {
|
||||
if array_values.is_empty() {
|
||||
@ -49,45 +54,49 @@ pub fn array_lower_memory<A: Allocatable<MV>, 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,13 @@ use crate::NEVec;
|
||||
|
||||
use it_memory_traits::MemoryView;
|
||||
|
||||
pub fn record_lower_memory<A: Allocatable<MV>, MV: MemoryView>(
|
||||
lowerer: &ILowerer<'_, A, MV>,
|
||||
pub fn record_lower_memory<
|
||||
A: Allocatable<MV, Store>,
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
>(
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
lowerer: &mut ILowerer<'_, A, MV, Store>,
|
||||
values: NEVec<IValue>,
|
||||
) -> LoResult<u32> {
|
||||
let average_field_size = 4;
|
||||
@ -47,34 +52,35 @@ pub fn record_lower_memory<A: Allocatable<MV>, 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)
|
||||
}
|
||||
|
@ -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>, MV: MemoryView> {
|
||||
heap_manager: &'i R,
|
||||
pub struct MemoryWriter<
|
||||
'i,
|
||||
R: Allocatable<MV, Store>,
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
> {
|
||||
heap_manager: &'i mut R,
|
||||
view: RefCell<MV>,
|
||||
_store: PhantomData<Store>,
|
||||
}
|
||||
|
||||
impl<'i, A: Allocatable<MV>, MV: MemoryView> MemoryWriter<'i, A, MV> {
|
||||
pub fn new(view: MV, heap_manager: &'i A) -> LoResult<Self> {
|
||||
impl<'i, A: Allocatable<MV, Store>, MV: MemoryView<Store>, Store: it_memory_traits::Store>
|
||||
MemoryWriter<'i, A, MV, Store>
|
||||
{
|
||||
pub fn new(view: MV, heap_manager: &'i mut A) -> LoResult<Self> {
|
||||
let writer = Self {
|
||||
heap_manager,
|
||||
view: RefCell::new(view),
|
||||
_store: PhantomData,
|
||||
};
|
||||
Ok(writer)
|
||||
}
|
||||
|
||||
pub fn write_bytes(&self, bytes: &[u8]) -> LoResult<u32> {
|
||||
pub fn write_bytes(
|
||||
&mut self,
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
bytes: &[u8],
|
||||
) -> LoResult<u32> {
|
||||
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<SequentialWriter> {
|
||||
let (offset, view) = self.heap_manager.allocate(size, type_tag)?;
|
||||
pub fn sequential_writer(
|
||||
&mut self,
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
size: u32,
|
||||
type_tag: u32,
|
||||
) -> LoResult<SequentialWriter> {
|
||||
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<MV: MemoryView, A: Allocatable<MV>, const N: usize>(
|
||||
pub fn write_array<
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
A: Allocatable<MV, Store>,
|
||||
const N: usize,
|
||||
>(
|
||||
&self,
|
||||
writer: &MemoryWriter<'_, A, MV>,
|
||||
store: &mut <Store as it_memory_traits::Store>::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<MV: MemoryView, A: Allocatable<MV>>(
|
||||
pub fn write_u8<
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
A: Allocatable<MV, Store>,
|
||||
>(
|
||||
&self,
|
||||
writer: &MemoryWriter<'_, A, MV>,
|
||||
store: &mut <Store as it_memory_traits::Store>::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<MV: MemoryView, A: Allocatable<MV>>(
|
||||
pub fn write_u32<
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
A: Allocatable<MV, Store>,
|
||||
>(
|
||||
&self,
|
||||
writer: &MemoryWriter<'_, A, MV>,
|
||||
store: &mut <Store as it_memory_traits::Store>::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<MV: MemoryView, A: Allocatable<MV>>(
|
||||
pub fn write_bytes<
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
A: Allocatable<MV, Store>,
|
||||
>(
|
||||
&self,
|
||||
writer: &MemoryWriter<'_, A, MV>,
|
||||
store: &mut <Store as it_memory_traits::Store>::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);
|
||||
}
|
||||
|
@ -31,12 +31,19 @@ pub use it_memory_traits::MemoryView;
|
||||
|
||||
pub type LoResult<T> = std::result::Result<T, error::LoError>;
|
||||
|
||||
pub struct ILowerer<'m, A: Allocatable<MV>, MV: MemoryView> {
|
||||
pub writer: MemoryWriter<'m, A, MV>,
|
||||
pub struct ILowerer<
|
||||
'm,
|
||||
A: Allocatable<MV, Store>,
|
||||
MV: MemoryView<Store>,
|
||||
Store: it_memory_traits::Store,
|
||||
> {
|
||||
pub writer: MemoryWriter<'m, A, MV, Store>,
|
||||
}
|
||||
|
||||
impl<'m, A: Allocatable<MV>, MV: MemoryView> ILowerer<'m, A, MV> {
|
||||
pub fn new(view: MV, allocatable: &'m A) -> LoResult<Self> {
|
||||
impl<'m, A: Allocatable<MV, Store>, MV: MemoryView<Store>, Store: it_memory_traits::Store>
|
||||
ILowerer<'m, A, MV, Store>
|
||||
{
|
||||
pub fn new(view: MV, allocatable: &'m mut A) -> LoResult<Self> {
|
||||
let writer = MemoryWriter::new(view, allocatable)?;
|
||||
let lowerer = Self { writer };
|
||||
|
||||
|
@ -19,8 +19,13 @@ use thiserror::Error as ThisError;
|
||||
|
||||
pub const DEFAULT_MEMORY_INDEX: usize = 0;
|
||||
|
||||
pub trait Allocatable<MV: MemoryView> {
|
||||
fn allocate(&self, size: u32, type_tag: u32) -> Result<(u32, MV), AllocatableError>;
|
||||
pub trait Allocatable<MV: MemoryView<Store>, Store: it_memory_traits::Store> {
|
||||
fn allocate(
|
||||
&mut self,
|
||||
store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
|
||||
size: u32,
|
||||
type_tag: u32,
|
||||
) -> Result<(u32, MV), AllocatableError>;
|
||||
}
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
|
@ -18,44 +18,72 @@ mod errors;
|
||||
|
||||
pub use errors::MemoryAccessError;
|
||||
|
||||
pub trait MemoryReadable {
|
||||
pub trait Store {
|
||||
type ActualStore<'c>;
|
||||
}
|
||||
|
||||
pub trait MemoryReadable<Store: self::Store> {
|
||||
/// 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 <Store as self::Store>::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<const COUNT: usize>(&self, offset: u32) -> [u8; COUNT];
|
||||
fn read_array<const COUNT: usize>(
|
||||
&self,
|
||||
store: &mut <Store as self::Store>::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<u8>;
|
||||
fn read_vec(
|
||||
&self,
|
||||
store: &mut <Store as self::Store>::ActualStore<'_>,
|
||||
offset: u32,
|
||||
size: u32,
|
||||
) -> Vec<u8>;
|
||||
}
|
||||
|
||||
pub trait MemoryWritable {
|
||||
pub trait MemoryWritable<Store: self::Store> {
|
||||
/// 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 <Store as self::Store>::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 <Store as self::Store>::ActualStore<'_>,
|
||||
offset: u32,
|
||||
bytes: &[u8],
|
||||
);
|
||||
}
|
||||
|
||||
pub trait MemoryView: MemoryWritable + MemoryReadable {
|
||||
pub trait MemoryView<Store: self::Store>: MemoryWritable<Store> + MemoryReadable<Store> {
|
||||
/// 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 <Store as self::Store>::ActualStore<'_>,
|
||||
offset: u32,
|
||||
size: u32,
|
||||
) -> Result<(), MemoryAccessError>;
|
||||
}
|
||||
|
||||
pub trait Memory<View>
|
||||
pub trait Memory<View, Store: self::Store>
|
||||
where
|
||||
View: MemoryView,
|
||||
View: MemoryView<Store>,
|
||||
{
|
||||
fn view(&self) -> View;
|
||||
}
|
||||
|
@ -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<Vec<FunctionArg>>,
|
||||
arguments: Arc<Vec<FunctionArg>>,
|
||||
|
||||
/// Types for the results (`(result …)`).
|
||||
output_types: Rc<Vec<IType>>,
|
||||
output_types: Arc<Vec<IType>>,
|
||||
},
|
||||
|
||||
/// A record type, like:
|
||||
@ -49,7 +49,7 @@ pub enum Type {
|
||||
/// ```wasm,ignore
|
||||
/// (@interface type (record string i32))
|
||||
/// ```
|
||||
Record(Rc<IRecordType>),
|
||||
Record(Arc<IRecordType>),
|
||||
}
|
||||
|
||||
/// Represents an imported function.
|
||||
|
@ -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<u8> 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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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::<keyword::record>() {
|
||||
Ok(Type::Record(Rc::new(parser.parse()?)))
|
||||
Ok(Type::Record(Arc::new(parser.parse()?)))
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
|
@ -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<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
pub(crate) fn array_lift_memory<Instance, Export, LocalImport, Memory, MemoryView, Store>(
|
||||
instruction: Instruction,
|
||||
value_type: IType,
|
||||
) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
) -> 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>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView,
|
||||
Instance:
|
||||
crate::interpreter::wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: crate::interpreter::wasm::structures::LocalImport<Store>,
|
||||
Memory: crate::interpreter::wasm::structures::Memory<MemoryView, Store>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView<Store>,
|
||||
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<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
pub(crate) fn array_lower_memory<Instance, Export, LocalImport, Memory, MemoryView, Store>(
|
||||
instruction: Instruction,
|
||||
value_type: IType,
|
||||
) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
) -> 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>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView,
|
||||
Instance:
|
||||
crate::interpreter::wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: crate::interpreter::wasm::structures::LocalImport<Store>,
|
||||
Memory: crate::interpreter::wasm::structures::Memory<MemoryView, Store>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView<Store>,
|
||||
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();
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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 {
|
||||
|
@ -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<MemoryView> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView + 'i,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'i,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView<Store> + 'i,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
Store: wasm::structures::Store,
|
||||
{
|
||||
pub(crate) instance: &'i Instance,
|
||||
_export: PhantomData<Export>,
|
||||
_local_import: PhantomData<LocalImport>,
|
||||
_memory: PhantomData<Memory>,
|
||||
_memory_view: PhantomData<MemoryView>,
|
||||
_store: PhantomData<Store>,
|
||||
}
|
||||
|
||||
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<MemoryView> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'i,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
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<MemoryView> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'i,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
Store: wasm::structures::Store,
|
||||
{
|
||||
fn resolve_record(&self, record_type_id: u64) -> Result<&IRecordType, RecordResolvableError> {
|
||||
let record = self
|
||||
|
@ -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<MemoryView> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'i,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
Store: wasm::structures::Store,
|
||||
{
|
||||
pub(crate) instance: &'i Instance,
|
||||
_export: PhantomData<Export>,
|
||||
_local_import: PhantomData<LocalImport>,
|
||||
_memory: PhantomData<Memory>,
|
||||
_memory_view: PhantomData<MemoryView>,
|
||||
_store: PhantomData<Store>,
|
||||
}
|
||||
|
||||
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<MemoryView> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'i,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
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<MemoryView>
|
||||
for LoHelper<'i, Instance, Export, LocalImport, Memory, MemoryView>
|
||||
impl<'i, Instance, Export, LocalImport, Memory, MemoryView, Store> Allocatable<MemoryView, Store>
|
||||
for LoHelper<'i, Instance, Export, LocalImport, Memory, MemoryView, Store>
|
||||
where
|
||||
Export: wasm::structures::Export + 'i,
|
||||
LocalImport: wasm::structures::LocalImport + 'i,
|
||||
Memory: wasm::structures::Memory<MemoryView> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'i,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'i,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
Store: wasm::structures::Store,
|
||||
{
|
||||
fn allocate(&self, size: u32, type_tag: u32) -> Result<(u32, MemoryView), AllocatableError> {
|
||||
fn allocate(
|
||||
&mut self,
|
||||
store: &mut <Store as wasm::structures::Store>::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 {
|
||||
|
@ -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<MemoryView> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'instance,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
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<MemoryView> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'instance,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
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<MemoryView> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'instance,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
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<MemoryView> for Memory {
|
||||
impl wasm::structures::Memory<MemoryView, Store> for Memory {
|
||||
fn view(&self) -> MemoryView {
|
||||
self.view.clone()
|
||||
}
|
||||
|
@ -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<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
pub(crate) fn record_lift_memory<Instance, Export, LocalImport, Memory, MemoryView, Store>(
|
||||
record_type_id: u64,
|
||||
instruction: Instruction,
|
||||
) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
) -> 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>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView,
|
||||
Instance:
|
||||
crate::interpreter::wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: crate::interpreter::wasm::structures::LocalImport<Store>,
|
||||
Memory: crate::interpreter::wasm::structures::Memory<MemoryView, Store>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView<Store>,
|
||||
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<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
pub(crate) fn record_lower_memory<Instance, Export, LocalImport, Memory, MemoryView, Store>(
|
||||
record_type_id: u64,
|
||||
instruction: Instruction,
|
||||
) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
) -> 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>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView,
|
||||
Instance:
|
||||
crate::interpreter::wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: crate::interpreter::wasm::structures::LocalImport<Store>,
|
||||
Memory: crate::interpreter::wasm::structures::Memory<MemoryView, Store>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView<Store>,
|
||||
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));
|
||||
|
@ -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));
|
||||
|
@ -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<MemoryView> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView> + 'instance,
|
||||
LocalImport: wasm::structures::LocalImport<Store> + 'instance,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance:
|
||||
wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store> + '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 <Store as it_memory_traits::Store>::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<Instance, Export, LocalImport, Memory, MemoryView> = Box<
|
||||
dyn Fn(&mut Runtime<Instance, Export, LocalImport, Memory, MemoryView>) -> InstructionResult<()>
|
||||
+ Send,
|
||||
>;
|
||||
pub(crate) type ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView, Store> =
|
||||
Box<
|
||||
dyn Fn(&mut Runtime<Instance, Export, LocalImport, Memory, MemoryView, Store>, ) -> 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<Instance, Export, LocalImport, Memory, Mem
|
||||
/// // 5. Read the stack to get the result.
|
||||
/// assert_eq!(stack.as_slice(), &[IValue::I32(7)]);
|
||||
/// ```
|
||||
pub struct Interpreter<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
pub struct Interpreter<Instance, Export, LocalImport, Memory, MemoryView, Store>
|
||||
where
|
||||
Export: wasm::structures::Export,
|
||||
LocalImport: wasm::structures::LocalImport,
|
||||
Memory: wasm::structures::Memory<MemoryView>,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store>,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store>,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
Store: wasm::structures::Store,
|
||||
{
|
||||
executable_instructions:
|
||||
Vec<ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>>,
|
||||
Vec<ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView, Store>>,
|
||||
}
|
||||
|
||||
impl<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
Interpreter<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
impl<Instance, Export, LocalImport, Memory, MemoryView, Store>
|
||||
Interpreter<Instance, Export, LocalImport, Memory, MemoryView, Store>
|
||||
where
|
||||
Export: wasm::structures::Export,
|
||||
LocalImport: wasm::structures::LocalImport,
|
||||
Memory: wasm::structures::Memory<MemoryView>,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store>,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store>,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
Store: wasm::structures::Store,
|
||||
{
|
||||
fn iter(
|
||||
&self,
|
||||
) -> impl Iterator<
|
||||
Item = &ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>,
|
||||
Item = &ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView, Store>,
|
||||
> + '_ {
|
||||
self.executable_instructions.iter()
|
||||
}
|
||||
@ -159,11 +176,13 @@ where
|
||||
&self,
|
||||
invocation_inputs: &[IValue],
|
||||
wasm_instance: &mut Instance,
|
||||
wasm_store: &mut <Store as wasm::structures::Store>::ActualStore<'_>,
|
||||
) -> InterpreterResult<Stack<IValue>> {
|
||||
let mut runtime = Runtime {
|
||||
invocation_inputs,
|
||||
stack: Stack::new(),
|
||||
wasm_instance,
|
||||
store: wasm_store,
|
||||
_phantom: PhantomData,
|
||||
};
|
||||
|
||||
@ -176,14 +195,15 @@ where
|
||||
}
|
||||
|
||||
/// Transforms a `Vec<Instruction>` into an `Interpreter`.
|
||||
impl<Instance, Export, LocalImport, Memory, MemoryView> TryFrom<Vec<Instruction>>
|
||||
for Interpreter<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
impl<Instance, Export, LocalImport, Memory, MemoryView, Store> TryFrom<Vec<Instruction>>
|
||||
for Interpreter<Instance, Export, LocalImport, Memory, MemoryView, Store>
|
||||
where
|
||||
Export: wasm::structures::Export,
|
||||
LocalImport: wasm::structures::LocalImport,
|
||||
Memory: wasm::structures::Memory<MemoryView>,
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: wasm::structures::LocalImport<Store>,
|
||||
Memory: wasm::structures::Memory<MemoryView, Store>,
|
||||
MemoryView: wasm::structures::MemoryView<Store>,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView, Store>,
|
||||
Store: wasm::structures::Store,
|
||||
{
|
||||
type Error = ();
|
||||
|
||||
|
@ -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<Vec<IValue>, ()>;
|
||||
}
|
||||
|
||||
pub trait LocalImport {
|
||||
pub trait LocalImport<Store: self::Store> {
|
||||
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<Vec<IValue>, ()>;
|
||||
fn call(
|
||||
&self,
|
||||
store: &mut <Store as self::Store>::ActualStore<'_>,
|
||||
arguments: &[IValue],
|
||||
) -> Result<Vec<IValue>, ()>;
|
||||
}
|
||||
|
||||
pub trait Instance<E, LI, M, MV>
|
||||
pub use it_memory_traits::Store;
|
||||
|
||||
pub trait Instance<E, LI, M, MV, S>
|
||||
where
|
||||
E: Export,
|
||||
LI: LocalImport,
|
||||
M: Memory<MV>,
|
||||
MV: MemoryView,
|
||||
LI: LocalImport<S>,
|
||||
M: Memory<MV, S>,
|
||||
MV: MemoryView<S>,
|
||||
S: Store,
|
||||
{
|
||||
fn export(&self, export_name: &str) -> Option<&E>;
|
||||
fn local_or_import<I: TypedIndex + LocalImportIndex>(&self, index: I) -> Option<&LI>;
|
||||
fn memory(&self, index: usize) -> Option<&M>;
|
||||
fn memory_view(&self, index: usize) -> Option<MV>;
|
||||
fn wit_record_by_id(&self, index: u64) -> Option<&Rc<IRecordType>>;
|
||||
fn wit_record_by_id(&self, index: u64) -> Option<&Arc<IRecordType>>;
|
||||
}
|
||||
|
||||
impl Export for () {
|
||||
@ -103,7 +110,7 @@ impl Export for () {
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalImport for () {
|
||||
impl<Store: self::Store> LocalImport<Store> for () {
|
||||
fn name(&self) -> &str {
|
||||
""
|
||||
}
|
||||
@ -124,35 +131,54 @@ impl LocalImport for () {
|
||||
&[]
|
||||
}
|
||||
|
||||
fn call(&self, _arguments: &[IValue]) -> Result<Vec<IValue>, ()> {
|
||||
fn call(
|
||||
&self,
|
||||
_store: &mut <Store as self::Store>::ActualStore<'_>,
|
||||
_arguments: &[IValue],
|
||||
) -> Result<Vec<IValue>, ()> {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct EmptyMemoryView;
|
||||
|
||||
impl MemoryWritable for EmptyMemoryView {
|
||||
fn write_byte(&self, _offset: u32, _value: u8) {}
|
||||
impl<S: Store> MemoryWritable<S> for EmptyMemoryView {
|
||||
fn write_byte(&self, _store: &mut <S as Store>::ActualStore<'_>, _offset: u32, _value: u8) {}
|
||||
|
||||
fn write_bytes(&self, _offset: u32, _bytes: &[u8]) {}
|
||||
fn write_bytes(&self, _store: &mut <S as Store>::ActualStore<'_>, _offset: u32, _bytes: &[u8]) {
|
||||
}
|
||||
}
|
||||
|
||||
impl MemoryReadable for EmptyMemoryView {
|
||||
fn read_byte(&self, _offset: u32) -> u8 {
|
||||
impl<S: Store> MemoryReadable<S> for EmptyMemoryView {
|
||||
fn read_byte(&self, _store: &mut <S as Store>::ActualStore<'_>, _offset: u32) -> u8 {
|
||||
0
|
||||
}
|
||||
|
||||
fn read_array<const COUNT: usize>(&self, _offset: u32) -> [u8; COUNT] {
|
||||
fn read_array<const COUNT: usize>(
|
||||
&self,
|
||||
_store: &mut <S as Store>::ActualStore<'_>,
|
||||
_offset: u32,
|
||||
) -> [u8; COUNT] {
|
||||
[0; COUNT]
|
||||
}
|
||||
|
||||
fn read_vec(&self, _offset: u32, _size: u32) -> Vec<u8> {
|
||||
fn read_vec(
|
||||
&self,
|
||||
_store: &mut <S as Store>::ActualStore<'_>,
|
||||
_offset: u32,
|
||||
_size: u32,
|
||||
) -> Vec<u8> {
|
||||
Vec::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl MemoryView for EmptyMemoryView {
|
||||
fn check_bounds(&self, offset: u32, size: u32) -> Result<(), MemoryAccessError> {
|
||||
impl<S: Store> MemoryView<S> for EmptyMemoryView {
|
||||
fn check_bounds(
|
||||
&self,
|
||||
_store: &mut <S as Store>::ActualStore<'_>,
|
||||
offset: u32,
|
||||
size: u32,
|
||||
) -> Result<(), MemoryAccessError> {
|
||||
Err(MemoryAccessError::OutOfBounds {
|
||||
size,
|
||||
offset,
|
||||
@ -161,18 +187,19 @@ impl MemoryView for EmptyMemoryView {
|
||||
}
|
||||
}
|
||||
|
||||
impl Memory<EmptyMemoryView> for () {
|
||||
impl<S: Store> Memory<EmptyMemoryView, S> for () {
|
||||
fn view(&self) -> EmptyMemoryView {
|
||||
EmptyMemoryView
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, LI, M, MV> Instance<E, LI, M, MV> for ()
|
||||
impl<E, LI, M, MV, S> Instance<E, LI, M, MV, S> for ()
|
||||
where
|
||||
E: Export,
|
||||
LI: LocalImport,
|
||||
M: Memory<MV>,
|
||||
MV: MemoryView,
|
||||
LI: LocalImport<S>,
|
||||
M: Memory<MV, S>,
|
||||
MV: MemoryView<S>,
|
||||
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<IRecordType>> {
|
||||
fn wit_record_by_id(&self, _index: u64) -> Option<&Arc<IRecordType>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -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<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
pub(crate) fn $name<Instance, Export, LocalImport, Memory, MemoryView, Store>(
|
||||
$($argument_name: $argument_type),*
|
||||
) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
|
||||
) -> 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>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView,
|
||||
Instance: crate::interpreter::wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
LocalImport: crate::interpreter::wasm::structures::LocalImport<Store>,
|
||||
Memory: crate::interpreter::wasm::structures::Memory<MemoryView, Store>,
|
||||
MemoryView: crate::interpreter::wasm::structures::MemoryView<Store>,
|
||||
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};
|
||||
|
Loading…
Reference in New Issue
Block a user