mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 15:20:20 +00:00
refactor reader
This commit is contained in:
parent
51af2df63e
commit
532043a884
@ -1,7 +1,7 @@
|
||||
mod lift_array;
|
||||
mod lower_array;
|
||||
mod memory_writer;
|
||||
mod read_arrays;
|
||||
mod utils;
|
||||
mod write_arrays;
|
||||
|
||||
pub(crate) use lift_array::array_lift_memory_impl;
|
||||
@ -9,8 +9,8 @@ pub(crate) use lower_array::array_lower_memory_impl;
|
||||
|
||||
use super::allocate;
|
||||
use super::read_from_instance_mem;
|
||||
use super::record_lift_memory_;
|
||||
use super::record_lower_memory_;
|
||||
use super::record_lift_memory_impl;
|
||||
use super::record_lower_memory_impl;
|
||||
use super::write_to_instance_mem;
|
||||
|
||||
use crate::instr_error;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::utils::MemoryWriter;
|
||||
use super::memory_writer::MemoryWriter;
|
||||
use super::write_to_instance_mem;
|
||||
|
||||
use crate::{
|
||||
@ -75,7 +75,7 @@ where
|
||||
|
||||
IValue::Record(values) => {
|
||||
let record_offset =
|
||||
super::record_lower_memory_(instance, instruction.clone(), values)?;
|
||||
super::record_lower_memory_impl(instance, instruction.clone(), values)?;
|
||||
writer.write_array(record_offset.to_le_bytes());
|
||||
}
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ where
|
||||
let mut result = Vec::with_capacity(data.len());
|
||||
|
||||
for record_offset in data {
|
||||
result.push(super::record_lift_memory_(
|
||||
result.push(super::record_lift_memory_impl(
|
||||
instance,
|
||||
record_type,
|
||||
*record_offset as _,
|
||||
|
@ -1,169 +1,23 @@
|
||||
mod lift_record;
|
||||
mod lower_record;
|
||||
mod value_reader;
|
||||
|
||||
pub(crate) use lift_record::record_lift_memory_impl;
|
||||
pub(crate) use lower_record::record_lower_memory_impl;
|
||||
|
||||
use super::array_lift_memory_impl;
|
||||
use super::array_lower_memory_impl;
|
||||
use super::read_from_instance_mem;
|
||||
use super::write_to_instance_mem;
|
||||
|
||||
use crate::instr_error;
|
||||
use crate::interpreter::instructions::{is_record_fields_compatible_to_type, to_native};
|
||||
use crate::IRecordType;
|
||||
use crate::IType;
|
||||
use crate::IValue;
|
||||
use crate::NEVec;
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::Instruction,
|
||||
};
|
||||
use crate::{errors::InstructionError, errors::InstructionErrorKind, interpreter::Instruction};
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
pub(super) fn record_lift_memory_<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &'instance Instance,
|
||||
record_type: &IRecordType,
|
||||
offset: usize,
|
||||
instruction: Instruction,
|
||||
) -> Result<IValue, InstructionError>
|
||||
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>
|
||||
+ 'instance,
|
||||
{
|
||||
let length = record_type.fields.len();
|
||||
let mut values = Vec::with_capacity(length);
|
||||
let size = record_size(record_type);
|
||||
let data = read_from_instance_mem(instance, instruction.clone(), offset, size)?;
|
||||
|
||||
let mut field_id = 0;
|
||||
for field in (*record_type.fields).iter() {
|
||||
let value = data[field_id];
|
||||
match &field.ty {
|
||||
IType::Boolean => {
|
||||
values.push(IValue::Boolean(value as _));
|
||||
}
|
||||
IType::S8 => {
|
||||
values.push(IValue::S8(value as _));
|
||||
}
|
||||
IType::S16 => {
|
||||
values.push(IValue::S16(value as _));
|
||||
}
|
||||
IType::S32 => {
|
||||
values.push(IValue::S32(value as _));
|
||||
}
|
||||
IType::S64 => {
|
||||
values.push(IValue::S64(value as _));
|
||||
}
|
||||
IType::I32 => {
|
||||
values.push(IValue::I32(value as _));
|
||||
}
|
||||
IType::I64 => {
|
||||
values.push(IValue::I64(value as _));
|
||||
}
|
||||
IType::U8 => {
|
||||
values.push(IValue::U8(value as _));
|
||||
}
|
||||
IType::U16 => {
|
||||
values.push(IValue::U16(value as _));
|
||||
}
|
||||
IType::U32 => {
|
||||
values.push(IValue::U32(value as _));
|
||||
}
|
||||
IType::U64 => {
|
||||
values.push(IValue::U64(value as _));
|
||||
}
|
||||
IType::F32 => {
|
||||
values.push(IValue::F32(value as _));
|
||||
}
|
||||
IType::F64 => values.push(IValue::F64(f64::from_bits(value))),
|
||||
IType::String => {
|
||||
let string_offset = value;
|
||||
field_id += 1;
|
||||
let string_size = data[field_id];
|
||||
|
||||
if string_size != 0 {
|
||||
let string_mem = read_from_instance_mem(
|
||||
instance,
|
||||
instruction.clone(),
|
||||
string_offset as _,
|
||||
string_size as _,
|
||||
)?;
|
||||
|
||||
// TODO: check
|
||||
let string = String::from_utf8(string_mem).unwrap();
|
||||
values.push(IValue::String(string));
|
||||
} else {
|
||||
values.push(IValue::String(String::new()));
|
||||
}
|
||||
}
|
||||
IType::Array(ty) => {
|
||||
let array_offset = value;
|
||||
field_id += 1;
|
||||
let array_size = data[field_id];
|
||||
|
||||
if array_size != 0 {
|
||||
let array = super::array_lift_memory_impl(
|
||||
instance,
|
||||
&**ty,
|
||||
array_offset as _,
|
||||
array_size as _,
|
||||
instruction.clone(),
|
||||
)?;
|
||||
values.push(array);
|
||||
} else {
|
||||
values.push(IValue::Array(vec![]));
|
||||
}
|
||||
}
|
||||
IType::Record(record_type_id) => {
|
||||
let offset = value;
|
||||
|
||||
let record_type = instance.wit_record_by_id(*record_type_id).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::RecordTypeByNameIsMissing {
|
||||
record_type_id: *record_type_id,
|
||||
},
|
||||
)
|
||||
})?;
|
||||
|
||||
values.push(record_lift_memory_(
|
||||
instance,
|
||||
record_type,
|
||||
offset as _,
|
||||
instruction.clone(),
|
||||
)?)
|
||||
}
|
||||
}
|
||||
field_id += 1;
|
||||
}
|
||||
|
||||
Ok(IValue::Record(
|
||||
NEVec::new(values.into_iter().collect())
|
||||
.expect("Record must have at least one field, zero given"),
|
||||
))
|
||||
}
|
||||
|
||||
/// Returns record size in bytes.
|
||||
fn record_size(record_type: &IRecordType) -> usize {
|
||||
let mut record_size = 0;
|
||||
|
||||
for field_type in record_type.fields.iter() {
|
||||
record_size += match field_type.ty {
|
||||
IType::Boolean | IType::S8 | IType::U8 => 1,
|
||||
IType::S16 | IType::U16 => 2,
|
||||
IType::S32
|
||||
| IType::U32
|
||||
| IType::I32
|
||||
| IType::F32
|
||||
| IType::String
|
||||
| IType::ByteArray
|
||||
| IType::Array(_)
|
||||
| IType::Record(_) => 32,
|
||||
IType::S64 | IType::U64 | IType::I64 | IType::F64 => 64,
|
||||
};
|
||||
}
|
||||
|
||||
record_size
|
||||
}
|
||||
|
||||
pub(crate) fn record_lift_memory<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
record_type_id: u64,
|
||||
instruction: Instruction,
|
||||
@ -208,7 +62,7 @@ where
|
||||
);
|
||||
|
||||
let record =
|
||||
record_lift_memory_(&**instance, record_type, offset, instruction.clone())?;
|
||||
record_lift_memory_impl(&**instance, record_type, offset, instruction.clone())?;
|
||||
|
||||
log::debug!("record.lift_memory: pushing {:?} on the stack", record);
|
||||
runtime.stack.push(record);
|
||||
@ -218,71 +72,6 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn record_lower_memory_<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &mut Instance,
|
||||
instruction: Instruction,
|
||||
values: NEVec<IValue>,
|
||||
) -> Result<i32, InstructionError>
|
||||
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>,
|
||||
{
|
||||
let mut result: Vec<u8> = Vec::with_capacity(values.len());
|
||||
|
||||
for value in values.into_vec() {
|
||||
match value {
|
||||
IValue::Boolean(value) => result.push(value as _),
|
||||
IValue::S8(value) => result.push(value as _),
|
||||
IValue::S16(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::S32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::S64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::U8(value) => result.push(value),
|
||||
IValue::U16(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::U32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::U64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::I32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::I64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::F32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::F64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::String(value) => {
|
||||
let string_pointer =
|
||||
write_to_instance_mem(instance, instruction.clone(), value.as_bytes())?;
|
||||
|
||||
result.extend_from_slice(&string_pointer.to_le_bytes());
|
||||
result.extend_from_slice(&value.len().to_le_bytes());
|
||||
}
|
||||
IValue::ByteArray(value) => {
|
||||
let array_pointer = write_to_instance_mem(instance, instruction.clone(), &value)?;
|
||||
|
||||
result.extend_from_slice(&array_pointer.to_le_bytes());
|
||||
result.extend_from_slice(&value.len().to_le_bytes());
|
||||
}
|
||||
|
||||
IValue::Array(values) => {
|
||||
let (offset, size) =
|
||||
super::array_lower_memory_impl(instance, instruction.clone(), values)?;
|
||||
|
||||
result.extend_from_slice(&offset.to_le_bytes());
|
||||
result.extend_from_slice(&size.to_le_bytes());
|
||||
}
|
||||
|
||||
IValue::Record(values) => {
|
||||
let record_ptr = record_lower_memory_(instance, instruction.clone(), values)?;
|
||||
|
||||
result.extend_from_slice(&record_ptr.to_le_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result_pointer = write_to_instance_mem(instance, instruction, &result)?;
|
||||
|
||||
Ok(result_pointer as _)
|
||||
}
|
||||
|
||||
pub(crate) fn record_lower_memory<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
record_type_id: u64,
|
||||
instruction: Instruction,
|
||||
@ -313,7 +102,7 @@ where
|
||||
log::debug!("record.lower_memory: obtained {:?} values on the stack for record type = {}", record_fields, record_type_id);
|
||||
|
||||
let offset =
|
||||
record_lower_memory_(*instance, instruction.clone(), record_fields)?;
|
||||
record_lower_memory_impl(*instance, instruction.clone(), record_fields)?;
|
||||
|
||||
log::debug!("record.lower_memory: pushing {} on the stack", offset);
|
||||
runtime.stack.push(IValue::I32(offset));
|
||||
|
@ -0,0 +1,192 @@
|
||||
use super::read_from_instance_mem;
|
||||
|
||||
use super::value_reader::ValueReader;
|
||||
use crate::IRecordType;
|
||||
use crate::IType;
|
||||
use crate::IValue;
|
||||
use crate::NEVec;
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::Instruction,
|
||||
};
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub(crate) fn record_lift_memory_impl<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &'instance Instance,
|
||||
record_type: &IRecordType,
|
||||
offset: usize,
|
||||
instruction: Instruction,
|
||||
) -> Result<IValue, InstructionError>
|
||||
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> + 'instance,
|
||||
{
|
||||
let mut values = Vec::with_capacity(record_type.fields.len());
|
||||
|
||||
let size = record_size(record_type);
|
||||
let data = read_from_instance_mem(instance, instruction.clone(), offset, size)?;
|
||||
let reader = ValueReader::new(data);
|
||||
|
||||
for field in (*record_type.fields).iter() {
|
||||
match &field.ty {
|
||||
IType::Boolean => values.push(IValue::Boolean(reader.read_u8() == 1)),
|
||||
IType::S8 => values.push(IValue::S8(reader.read_i8())),
|
||||
IType::S16 => values.push(IValue::S16(reader.read_i16())),
|
||||
IType::S32 => values.push(IValue::S32(reader.read_i32())),
|
||||
IType::S64 => values.push(IValue::S64(reader.read_i64())),
|
||||
IType::I32 => values.push(IValue::I32(reader.read_i32())),
|
||||
IType::I64 => values.push(IValue::I64(reader.read_i64())),
|
||||
IType::U8 => values.push(IValue::U8(reader.read_u8())),
|
||||
IType::U16 => values.push(IValue::U16(reader.read_u16())),
|
||||
IType::U32 => values.push(IValue::U32(reader.read_u32())),
|
||||
IType::U64 => values.push(IValue::U64(reader.read_u64())),
|
||||
IType::F32 => values.push(IValue::F32(reader.read_f32())),
|
||||
IType::F64 => values.push(IValue::F64(reader.read_f64())),
|
||||
IType::String => values.push(IValue::String(read_string(instance, instruction.clone(), &reader)?)),
|
||||
IType::ByteArray => values.push(read_byte_array(instance, instruction.clone(), &reader)?),
|
||||
IType::Array(ty) => values.push(read_array(instance, instruction.clone(), &reader, &**ty)?),
|
||||
IType::Record(record_type_id) => values.push(read_record(instance, instruction.clone(), &reader, *record_type_id)?),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(IValue::Record(
|
||||
NEVec::new(values.into_iter().collect())
|
||||
.expect("Record must have at least one field, zero given"),
|
||||
))
|
||||
}
|
||||
|
||||
/// Returns record size in bytes.
|
||||
fn record_size(record_type: &IRecordType) -> usize {
|
||||
let mut record_size = 0;
|
||||
|
||||
for field_type in record_type.fields.iter() {
|
||||
record_size += match field_type.ty {
|
||||
IType::Boolean | IType::S8 | IType::U8 => 1,
|
||||
IType::S16 | IType::U16 => 2,
|
||||
IType::S32
|
||||
| IType::U32
|
||||
| IType::I32
|
||||
| IType::F32
|
||||
| IType::String
|
||||
| IType::ByteArray
|
||||
| IType::Array(_)
|
||||
| IType::Record(_) => 32,
|
||||
IType::S64 | IType::U64 | IType::I64 | IType::F64 => 64,
|
||||
};
|
||||
}
|
||||
|
||||
record_size
|
||||
}
|
||||
|
||||
fn read_string<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &Instance,
|
||||
instruction: Instruction,
|
||||
reader: &ValueReader,
|
||||
) -> Result<String, InstructionError>
|
||||
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>
|
||||
+ 'instance,
|
||||
{
|
||||
let string_offset = reader.read_u32();
|
||||
let string_size = reader.read_u32();
|
||||
|
||||
let string_mem = read_from_instance_mem(
|
||||
instance,
|
||||
instruction.clone(),
|
||||
string_offset as _,
|
||||
string_size as _,
|
||||
)?;
|
||||
|
||||
// TODO: check
|
||||
let string = String::from_utf8(string_mem).unwrap();
|
||||
|
||||
Ok(string)
|
||||
}
|
||||
|
||||
fn read_byte_array<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &Instance,
|
||||
instruction: Instruction,
|
||||
reader: &ValueReader,
|
||||
) -> Result<IValue, InstructionError>
|
||||
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>
|
||||
+ 'instance,
|
||||
{
|
||||
let offset = reader.read_u32();
|
||||
let elements_count = reader.read_u32();
|
||||
|
||||
let array = read_from_instance_mem(
|
||||
instance,
|
||||
instruction.clone(),
|
||||
offset as _,
|
||||
elements_count as _,
|
||||
)?;
|
||||
let byte_array = IValue::ByteArray(array);
|
||||
|
||||
Ok(byte_array)
|
||||
}
|
||||
|
||||
fn read_array<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &Instance,
|
||||
instruction: Instruction,
|
||||
reader: &ValueReader,
|
||||
ty: &IType,
|
||||
) -> Result<IValue, InstructionError>
|
||||
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>
|
||||
+ 'instance,
|
||||
{
|
||||
let array_offset = reader.read_u32();
|
||||
let elements_count = reader.read_u32();
|
||||
|
||||
super::array_lift_memory_impl(
|
||||
instance,
|
||||
ty,
|
||||
array_offset as _,
|
||||
elements_count as _,
|
||||
instruction.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
fn read_record<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &Instance,
|
||||
instruction: Instruction,
|
||||
reader: &ValueReader,
|
||||
record_type_id: u64,
|
||||
) -> Result<IValue, InstructionError>
|
||||
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>
|
||||
+ 'instance,
|
||||
{
|
||||
let offset = reader.read_u32();
|
||||
|
||||
let record_type = instance.wit_record_by_id(record_type_id).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::RecordTypeByNameIsMissing {
|
||||
record_type_id,
|
||||
},
|
||||
)
|
||||
})?;
|
||||
|
||||
record_lift_memory_impl(instance, record_type, offset as _, instruction.clone())
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
use super::write_to_instance_mem;
|
||||
|
||||
use crate::IValue;
|
||||
use crate::NEVec;
|
||||
use crate::{errors::InstructionError, interpreter::Instruction};
|
||||
|
||||
pub(crate) fn record_lower_memory_impl<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &mut Instance,
|
||||
instruction: Instruction,
|
||||
values: NEVec<IValue>,
|
||||
) -> Result<i32, InstructionError>
|
||||
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>,
|
||||
{
|
||||
let mut result: Vec<u8> = Vec::with_capacity(values.len());
|
||||
|
||||
for value in values.into_vec() {
|
||||
match value {
|
||||
IValue::Boolean(value) => result.push(value as _),
|
||||
IValue::S8(value) => result.push(value as _),
|
||||
IValue::S16(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::S32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::S64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::U8(value) => result.push(value),
|
||||
IValue::U16(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::U32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::U64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::I32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::I64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::F32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::F64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::String(value) => {
|
||||
let string_pointer =
|
||||
write_to_instance_mem(instance, instruction.clone(), value.as_bytes())?;
|
||||
|
||||
result.extend_from_slice(&string_pointer.to_le_bytes());
|
||||
result.extend_from_slice(&value.len().to_le_bytes());
|
||||
}
|
||||
IValue::ByteArray(value) => {
|
||||
let array_pointer = write_to_instance_mem(instance, instruction.clone(), &value)?;
|
||||
|
||||
result.extend_from_slice(&array_pointer.to_le_bytes());
|
||||
result.extend_from_slice(&value.len().to_le_bytes());
|
||||
}
|
||||
|
||||
IValue::Array(values) => {
|
||||
let (offset, size) =
|
||||
super::array_lower_memory_impl(instance, instruction.clone(), values)?;
|
||||
|
||||
result.extend_from_slice(&offset.to_le_bytes());
|
||||
result.extend_from_slice(&size.to_le_bytes());
|
||||
}
|
||||
|
||||
IValue::Record(values) => {
|
||||
let record_ptr = record_lower_memory_impl(instance, instruction.clone(), values)?;
|
||||
|
||||
result.extend_from_slice(&record_ptr.to_le_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result_pointer = write_to_instance_mem(instance, instruction, &result)?;
|
||||
|
||||
Ok(result_pointer as _)
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
use std::cell::Cell;
|
||||
|
||||
pub(super) struct ValueReader {
|
||||
stream: Vec<u8>,
|
||||
offset: Cell<usize>,
|
||||
}
|
||||
|
||||
macro_rules! value_der {
|
||||
($self:expr, $offset:expr, @seq_start $($ids:tt),* @seq_end) => {
|
||||
[$($self.stream[$offset + $ids]),+]
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 1) => {
|
||||
value_der!($self, $offset, @seq_start 0 @seq_end);
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 2) => {
|
||||
value_der!($self, $offset, @seq_start 0, 1 @seq_end);
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 4) => {
|
||||
value_der!($self, $offset, @seq_start 0, 1, 2, 3 @seq_end);
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 8) => {
|
||||
value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7 @seq_end);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! read_ty {
|
||||
($func_name:ident, $ty:ty, 1) => {
|
||||
pub(super) fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(value_der!(self, offset, 1));
|
||||
|
||||
self.offset.set(offset + 1);
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 2) => {
|
||||
pub(super) fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(value_der!(self, offset, 2));
|
||||
|
||||
self.offset.set(offset + 2);
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 4) => {
|
||||
pub(super) fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(value_der!(self, offset, 4));
|
||||
|
||||
self.offset.set(offset + 4);
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 8) => {
|
||||
pub(super) fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(value_der!(self, offset, 8));
|
||||
|
||||
self.offset.set(offset + 8);
|
||||
result
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: rewrite this with macros
|
||||
impl ValueReader {
|
||||
pub(super) fn new(stream: Vec<u8>) -> Self {
|
||||
let offset = Cell::new(0);
|
||||
Self { stream, offset }
|
||||
}
|
||||
|
||||
read_ty!(read_u8, u8, 1);
|
||||
read_ty!(read_i8, i8, 1);
|
||||
read_ty!(read_u16, u16, 2);
|
||||
read_ty!(read_i16, i16, 2);
|
||||
read_ty!(read_u32, u32, 4);
|
||||
read_ty!(read_i32, i32, 4);
|
||||
read_ty!(read_f32, f32, 4);
|
||||
read_ty!(read_u64, u64, 8);
|
||||
read_ty!(read_i64, i64, 8);
|
||||
read_ty!(read_f64, f64, 8);
|
||||
}
|
@ -24,6 +24,10 @@ where
|
||||
MemoryView: wasm::structures::MemoryView,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
{
|
||||
if size == 0 {
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let memory_index = 0;
|
||||
let memory_view = instance
|
||||
.memory(memory_index)
|
||||
|
@ -52,6 +52,7 @@
|
||||
// #![forbid(unsafe_code)]
|
||||
#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
|
||||
#![doc(html_logo_url = "https://github.com/wasmerio.png")]
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
pub mod ast;
|
||||
#[macro_use]
|
||||
|
Loading…
Reference in New Issue
Block a user