refactoring

This commit is contained in:
vms 2021-04-18 22:12:10 +03:00
parent 41555d4d32
commit 51af2df63e
12 changed files with 306 additions and 343 deletions

View File

@ -127,8 +127,8 @@ pub enum InstructionErrorKind {
/// The memory doesn't exist.
MemoryIsMissing {
/// The memory indeX.
memory_index: u32,
/// The memory index.
memory_index: usize,
},
/// Tried to read out of bounds of the memory.

View File

@ -1,9 +1,17 @@
mod lift_array;
mod lower_array;
mod read_arrays;
mod utils;
mod write_arrays;
pub(crate) use lift_array::array_lift_memory_impl;
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::write_to_instance_mem;
use read_arrays::*;
use crate::instr_error;
use crate::interpreter::instructions::to_native;
@ -15,60 +23,6 @@ use crate::{
use std::convert::TryInto;
pub(super) fn array_lift_memory_<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
instance: &'instance Instance,
value_type: &IType,
offset: usize,
elements_count: 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,
{
if elements_count == 0 {
return Ok(IValue::Array(vec![]));
}
match value_type {
IType::Boolean => read_bool_array(instance, instruction.clone(), offset, elements_count),
IType::S8 => read_s8_array(instance, instruction.clone(), offset, elements_count),
IType::S16 => read_s16_array(instance, instruction.clone(), offset, elements_count),
IType::S32 => read_s32_array(instance, instruction.clone(), offset, elements_count),
IType::S64 => read_s64_array(instance, instruction.clone(), offset, elements_count),
IType::I32 => read_i32_array(instance, instruction.clone(), offset, elements_count),
IType::I64 => read_i64_array(instance, instruction.clone(), offset, elements_count),
IType::U8 => read_u8_array(instance, instruction.clone(), offset, elements_count),
IType::U16 => read_u16_array(instance, instruction.clone(), offset, elements_count),
IType::U32 => read_u32_array(instance, instruction.clone(), offset, elements_count),
IType::U64 => read_u64_array(instance, instruction.clone(), offset, elements_count),
IType::F32 => read_f32_array(instance, instruction.clone(), offset, elements_count),
IType::F64 => read_f64_array(instance, instruction.clone(), offset, elements_count),
IType::String => read_string_array(instance, instruction.clone(), offset, elements_count),
IType::Record(record_type_id) => read_record_array(
instance,
instruction.clone(),
*record_type_id,
offset,
elements_count,
),
IType::ByteArray => read_array_array(
instance,
instruction.clone(),
&IType::ByteArray,
offset,
elements_count,
),
IType::Array(ty) => {
read_array_array(instance, instruction.clone(), &ty, offset, elements_count)
}
}
}
pub(crate) fn array_lift_memory<Instance, Export, LocalImport, Memory, MemoryView>(
instruction: Instruction,
value_type: IType,
@ -110,7 +64,7 @@ where
);
let instance = &mut runtime.wasm_instance;
let array = array_lift_memory_(
let array = array_lift_memory_impl(
*instance,
&value_type,
offset as _,
@ -126,72 +80,6 @@ where
})
}
pub(super) fn array_lower_memory_<Instance, Export, LocalImport, Memory, MemoryView>(
instance: &mut Instance,
instruction: Instruction,
array_values: Vec<IValue>,
) -> Result<(usize, usize), 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<u64> = Vec::with_capacity(array_values.len());
// here it's known that all interface values have the same type
for value in array_values {
match value {
IValue::S8(value) => result.push(value as _),
IValue::S16(value) => result.push(value as _),
IValue::S32(value) => result.push(value as _),
IValue::S64(value) => result.push(value as _),
IValue::U8(value) => result.push(value as _),
IValue::U16(value) => result.push(value as _),
IValue::U32(value) => result.push(value as _),
IValue::U64(value) => result.push(value as _),
IValue::I32(value) => result.push(value as _),
IValue::I64(value) => result.push(value as _),
IValue::F32(value) => result.push(value as _),
IValue::F64(value) => result.push(value.to_bits()),
IValue::String(value) => {
let string_pointer = if !value.is_empty() {
write_to_instance_mem(instance, instruction.clone(), value.as_bytes())?
} else {
0
};
result.push(string_pointer as _);
result.push(value.len() as _);
}
IValue::Array(values) => {
let (array_offset, array_size) = if !values.is_empty() {
array_lower_memory_(instance, instruction.clone(), values)?
} else {
(0, 0)
};
result.push(array_offset as _);
result.push(array_size as _);
}
IValue::Record(values) => {
let record_offset =
super::record_lower_memory_(instance, instruction.clone(), values)?;
result.push(record_offset as _);
}
}
}
let result = safe_transmute::transmute_to_bytes::<u64>(&result);
let result_pointer = write_to_instance_mem(instance, instruction, &result)?;
Ok((result_pointer as _, result.len() as _))
}
pub(crate) fn array_lower_memory<Instance, Export, LocalImport, Memory, MemoryView>(
instruction: Instruction,
value_type: IType,
@ -230,7 +118,7 @@ where
}
let (offset, size) =
array_lower_memory_(*instance, instruction.clone(), values)?;
array_lower_memory_impl(*instance, instruction.clone(), values)?;
log::trace!(
"array.lower_memory: pushing {}, {} on the stack",

View File

@ -0,0 +1,57 @@
use super::read_arrays::*;
use crate::{errors::InstructionError, interpreter::Instruction, IType, IValue};
pub(crate) fn array_lift_memory_impl<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
instance: &'instance Instance,
value_type: &IType,
offset: usize,
elements_count: 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,
{
if elements_count == 0 {
return Ok(IValue::Array(vec![]));
}
match value_type {
IType::Boolean => read_bool_array(instance, instruction.clone(), offset, elements_count),
IType::S8 => read_s8_array(instance, instruction.clone(), offset, elements_count),
IType::S16 => read_s16_array(instance, instruction.clone(), offset, elements_count),
IType::S32 => read_s32_array(instance, instruction.clone(), offset, elements_count),
IType::S64 => read_s64_array(instance, instruction.clone(), offset, elements_count),
IType::I32 => read_i32_array(instance, instruction.clone(), offset, elements_count),
IType::I64 => read_i64_array(instance, instruction.clone(), offset, elements_count),
IType::U8 => read_u8_array(instance, instruction.clone(), offset, elements_count),
IType::U16 => read_u16_array(instance, instruction.clone(), offset, elements_count),
IType::U32 => read_u32_array(instance, instruction.clone(), offset, elements_count),
IType::U64 => read_u64_array(instance, instruction.clone(), offset, elements_count),
IType::F32 => read_f32_array(instance, instruction.clone(), offset, elements_count),
IType::F64 => read_f64_array(instance, instruction.clone(), offset, elements_count),
IType::String => read_string_array(instance, instruction.clone(), offset, elements_count),
IType::Record(record_type_id) => read_record_array(
instance,
instruction.clone(),
*record_type_id,
offset,
elements_count,
),
IType::ByteArray => read_array_array(
instance,
instruction.clone(),
&IType::ByteArray,
offset,
elements_count,
),
IType::Array(ty) => {
read_array_array(instance, instruction.clone(), &ty, offset, elements_count)
}
}
}

View File

@ -0,0 +1,107 @@
use super::utils::MemoryWriter;
use super::write_to_instance_mem;
use crate::{
errors::{InstructionError, InstructionErrorKind},
interpreter::Instruction,
IValue,
};
pub(crate) fn array_lower_memory_impl<Instance, Export, LocalImport, Memory, MemoryView>(
instance: &mut Instance,
instruction: Instruction,
array_values: Vec<IValue>,
) -> Result<(usize, usize), 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>,
{
if array_values.is_empty() {
return Ok((0, 0));
}
let size_to_allocate = value_size(&array_values[0]) * array_values.len();
let offset = super::allocate(instance, instruction.clone(), size_to_allocate)?;
let memory_index = 0;
let memory_view = &instance
.memory(memory_index)
.ok_or_else(|| {
InstructionError::new(
instruction.clone(),
InstructionErrorKind::MemoryIsMissing { memory_index },
)
})?
.view();
let writer = MemoryWriter::new(memory_view, offset);
let values_count = array_values.len();
// here it's known that all interface values have the same type
for value in array_values {
match value {
IValue::Boolean(value) => writer.write_u8(value as _),
IValue::S8(value) => writer.write_u8(value as _),
IValue::S16(value) => writer.write_array(value.to_le_bytes()),
IValue::S32(value) => writer.write_array(value.to_le_bytes()),
IValue::S64(value) => writer.write_array(value.to_le_bytes()),
IValue::U8(value) => writer.write_array(value.to_le_bytes()),
IValue::U16(value) => writer.write_array(value.to_le_bytes()),
IValue::U32(value) => writer.write_array(value.to_le_bytes()),
IValue::U64(value) => writer.write_array(value.to_le_bytes()),
IValue::I32(value) => writer.write_array(value.to_le_bytes()),
IValue::I64(value) => writer.write_array(value.to_le_bytes()),
IValue::F32(value) => writer.write_array(value.to_le_bytes()),
IValue::F64(value) => writer.write_array(value.to_le_bytes()),
IValue::String(value) => {
let string_pointer =
write_to_instance_mem(instance, instruction.clone(), value.as_bytes())?;
writer.write_array(string_pointer.to_le_bytes());
writer.write_array(value.len().to_le_bytes());
}
IValue::ByteArray(values) => writer.write_slice(&values),
IValue::Array(values) => {
let (array_offset, array_size) =
array_lower_memory_impl(instance, instruction.clone(), values)?;
writer.write_array(array_offset.to_le_bytes());
writer.write_array(array_size.to_le_bytes());
}
IValue::Record(values) => {
let record_offset =
super::record_lower_memory_(instance, instruction.clone(), values)?;
writer.write_array(record_offset.to_le_bytes());
}
}
}
Ok((offset as _, values_count as _))
}
fn value_size(value: &IValue) -> usize {
match value {
IValue::Boolean(_) => 1,
IValue::S8(_) => 1,
IValue::S16(_) => 2,
IValue::S32(_) => 4,
IValue::S64(_) => 8,
IValue::U8(_) => 1,
IValue::U16(_) => 2,
IValue::U32(_) => 4,
IValue::U64(_) => 8,
IValue::F32(_) => 4,
IValue::F64(_) => 8,
IValue::String(_) => 4,
IValue::ByteArray(_) => 4,
IValue::Array(_) => 4,
IValue::I32(_) => 4,
IValue::I64(_) => 8,
IValue::Record(_) => 4,
}
}

View File

@ -55,9 +55,9 @@ where
MemoryView: wasm::structures::MemoryView + 'instance,
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
{
let memory_index: u32 = 0;
let memory_index = 0;
let memory_view = instance
.memory(memory_index as usize)
.memory(memory_index)
.ok_or_else(|| {
InstructionError::new(
instruction.clone(),
@ -112,7 +112,7 @@ def_read_func!(read_s8_array, (i8, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i8::from_be_bytes([Cell::get(&memory_view[element_id])]);
let value = i8::from_le_bytes([Cell::get(&memory_view[element_id])]);
result.push(IValue::S8(value));
}
@ -124,7 +124,7 @@ def_read_func!(read_u16_array, (u16, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = u16::from_be_bytes([
let value = u16::from_le_bytes([
Cell::get(&memory_view[2 * element_id]),
Cell::get(&memory_view[2 * element_id + 1]),
]);
@ -139,7 +139,7 @@ def_read_func!(read_s16_array, (i16, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i16::from_be_bytes([
let value = i16::from_le_bytes([
Cell::get(&memory_view[2 * element_id]),
Cell::get(&memory_view[2 * element_id + 1]),
]);
@ -154,7 +154,7 @@ def_read_func!(read_u32_array, (u32, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = u32::from_be_bytes([
let value = u32::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
@ -171,7 +171,7 @@ def_read_func!(read_f32_array, (f32, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = f32::from_be_bytes([
let value = f32::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
@ -188,7 +188,7 @@ def_read_func!(read_s32_array, (i32, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i32::from_be_bytes([
let value = i32::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
@ -205,7 +205,7 @@ def_read_func!(read_i32_array, (i32, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i32::from_be_bytes([
let value = i32::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
@ -222,7 +222,7 @@ def_read_func!(read_u64_array, (u64, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = u64::from_be_bytes([
let value = u64::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
@ -243,7 +243,7 @@ def_read_func!(read_f64_array, (f64, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = f64::from_be_bytes([
let value = f64::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
@ -264,7 +264,7 @@ def_read_func!(read_s64_array, (i64, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i64::from_be_bytes([
let value = i64::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
@ -285,7 +285,7 @@ def_read_func!(read_i64_array, (i64, elements_count), {
|memory_view: &[Cell<u8>]| {
let mut result = Vec::with_capacity(elements_count);
for element_id in 0..elements_count {
let value = i64::from_be_bytes([
let value = i64::from_le_bytes([
Cell::get(&memory_view[4 * element_id]),
Cell::get(&memory_view[4 * element_id + 1]),
Cell::get(&memory_view[4 * element_id + 2]),
@ -459,7 +459,7 @@ where
)?;
IValue::ByteArray(value)
}
_ => super::array_lift_memory_(
_ => super::array_lift_memory_impl(
instance,
&*ty,
*array_offset as _,

View File

@ -0,0 +1,47 @@
use std::cell::Cell;
pub(super) struct MemoryWriter<'m> {
memory_view: &'m [Cell<u8>],
offset: Cell<usize>,
}
impl<'m> MemoryWriter<'m> {
pub(crate) fn new(memory_view: &'m [Cell<u8>], offset: usize) -> Self {
let offset = Cell::new(offset);
Self {
memory_view,
offset,
}
}
pub(crate) fn write_u8(&self, value: u8) {
let offset = self.offset.get();
self.memory_view[offset].set(value);
self.offset.set(offset + 1);
}
pub(crate) fn write_slice(&self, values: &[u8]) {
let offset = self.offset.get();
for (id, value) in values.iter().enumerate() {
// don't check for memory overflow here for optimization purposes
// assuming that caller site work well
self.memory_view[offset + id].set(*value);
}
self.offset.set(offset + values.len());
}
pub(crate) fn write_array<const N: usize>(&self, values: [u8; N]) {
let offset = self.offset.get();
for id in 0..N {
// don't check for memory overflow here for optimization purposes
// assuming that caller site work well
self.memory_view[offset + id].set(values[id]);
}
self.offset.set(offset + values.len());
}
}

View File

@ -14,93 +14,6 @@ use crate::{
use std::convert::TryInto;
/*
/// Build an `IValue::Record` based on values on the stack.
///
/// To fill a record, every field `field_1` to `field_n` must get its
/// value from the stack with `value_1` to `value_n`. It is not
/// possible to use `Stack::pop` because the one-pass algorithm does
/// not know exactly the number of values to read from the stack
/// ahead-of-time, so `Stack::pop1` is used. It implies that values
/// are read one after the other from the stack, in a natural reverse
/// order, from `value_n` to `value_1`. Thus, the `values` vector must
/// be filled from the end to the beginning. It is not safely possible
/// to fill the `values` vector with empty values though (so that it
/// is possible to access to last positions). So a `VecDeque` type is
/// used: it is a double-ended queue.
fn record_lift_(
stack: &mut Stack<IValue>,
record_type: &RecordType,
) -> Result<IValue, InstructionErrorKind> {
let length = record_type.fields.len();
let mut values = VecDeque::with_capacity(length);
for field in record_type.fields.iter().rev() {
match field {
IType::Record(record_type) => {
values.push_front(record_lift_(stack, &record_type)?)
}
ty => {
let value = stack.pop1().unwrap();
let value_type = (&value).into();
if ty != &value_type {
return Err(InstructionErrorKind::InvalidValueOnTheStack {
expected_type: ty.clone(),
received_type: value_type,
});
}
values.push_front(value)
}
}
}
Ok(IValue::Record(
NEVec::new(values.into_iter().collect())
.expect("Record must have at least one field, zero given"),
))
}
pub(crate) fn record_lift<Instance, Export, LocalImport, Memory, MemoryView>(
type_index: u32,
instruction: Instruction,
) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
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>,
{
#[allow(unused_imports)]
use crate::interpreter::stack::Stackable;
Box::new({
move |runtime| -> _ {
let instance = &runtime.wasm_instance;
let record_type = match instance.wit_type(type_index).ok_or_else(|| {
InstructionError::new(
instruction.clone(),
InstructionErrorKind::TypeIsMissing { type_index },
)
})? {
Type::Record(record_type) => record_type,
Type::Function { .. } => {
return Err(InstructionError::new(
instruction.clone(),
InstructionErrorKind::InvalidTypeKind {
expected_kind: TypeKind::Record,
received_kind: TypeKind::Function,
},
))
}
};
let record = record_lift_(&mut runtime.stack, &record_type)
.map_err(|k| InstructionError::new(instruction.clone(), k))?;
runtime.stack.push(record);
Ok(())
}
})
}
*/
pub(super) fn record_lift_memory_<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
instance: &'instance Instance,
record_type: &IRecordType,
@ -115,33 +28,18 @@ where
Instance: crate::interpreter::wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>
+ 'instance,
{
fn record_size(record_type: &IRecordType) -> usize {
let mut record_size = 0;
for field_type in record_type.fields.iter() {
let params_count = match field_type.ty {
IType::String | IType::Array(_) => 2,
_ => 1,
};
record_size += std::mem::size_of::<u64>() * params_count;
}
record_size
}
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)?;
// TODO: add error handling
let data =
safe_transmute::transmute_many::<u64, safe_transmute::SingleManyGuard>(&data).unwrap();
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 _));
}
@ -202,7 +100,7 @@ where
let array_size = data[field_id];
if array_size != 0 {
let array = super::array_lift_memory_(
let array = super::array_lift_memory_impl(
instance,
&**ty,
array_offset as _,
@ -243,6 +141,29 @@ where
))
}
/// 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,
@ -310,53 +231,53 @@ where
Instance:
crate::interpreter::wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
{
let mut result: Vec<u64> = Vec::with_capacity(values.len());
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.push(value as _),
IValue::S32(value) => result.push(value as _),
IValue::S64(value) => result.push(value as _),
IValue::U8(value) => result.push(value as _),
IValue::U16(value) => result.push(value as _),
IValue::U32(value) => result.push(value as _),
IValue::U64(value) => result.push(value as _),
IValue::I32(value) => result.push(value as _),
IValue::I64(value) => result.push(value as _),
IValue::F32(value) => result.push(value as _),
IValue::F64(value) => result.push(value.to_bits()),
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 = if !value.is_empty() {
write_to_instance_mem(instance, instruction.clone(), value.as_bytes())?
} else {
0
};
let string_pointer =
write_to_instance_mem(instance, instruction.clone(), value.as_bytes())?;
result.push(string_pointer as _);
result.push(value.len() as _);
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) = if !values.is_empty() {
super::array_lower_memory_(instance, instruction.clone(), values)?
} else {
(0, 0)
};
let (offset, size) =
super::array_lower_memory_impl(instance, instruction.clone(), values)?;
result.push(offset as _);
result.push(size as _);
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.push(record_ptr as _);
result.extend_from_slice(&record_ptr.to_le_bytes());
}
}
}
let result = safe_transmute::transmute_to_bytes::<u64>(&result);
let result_pointer = write_to_instance_mem(instance, instruction, &result)?;
Ok(result_pointer as _)
@ -414,65 +335,3 @@ where
}
})
}
/*
pub(crate) fn record_lower<Instance, Export, LocalImport, Memory, MemoryView>(
type_index: u32,
instruction: Instruction,
) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
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>,
{
#[allow(unused_imports)]
use crate::interpreter::stack::Stackable;
Box::new({
move |runtime| -> _ {
let instance = &runtime.wasm_instance;
let record_type = match instance.wit_type(type_index).ok_or_else(|| {
InstructionError::new(
instruction.clone(),
InstructionErrorKind::TypeIsMissing { type_index },
)
})? {
Type::Record(record_type) => record_type,
Type::Function { .. } => {
return Err(InstructionError::new(
instruction.clone(),
InstructionErrorKind::InvalidTypeKind {
expected_kind: TypeKind::Record,
received_kind: TypeKind::Function,
},
))
}
};
match runtime.stack.pop1() {
Some(IValue::Record(record_values))
if record_type == &(&*record_values).into() =>
{
let values = FlattenIValueIterator::new(&record_values);
for value in values {
runtime.stack.push(value.clone());
}
Ok(())
}
Some(value) => Err(InstructionError::new(
instruction.clone(),
InstructionErrorKind::InvalidValueOnTheStack {
expected_type: IType::Record(record_type.clone()),
received_type: (&value).into(),
},
)),
None => Err(InstructionError::new(
instruction.clone(),
InstructionErrorKind::StackIsTooSmall { needed: 1 },
)),
}
}
})
}
*/

View File

@ -19,10 +19,10 @@ executable_instruction!(
)
})?;
let memory_index: u32 = 0;
let memory_index = 0;
let memory = runtime
.wasm_instance
.memory(memory_index as usize)
.memory(memory_index)
.ok_or_else(|| {
InstructionError::new(
instruction.clone(),
@ -96,9 +96,9 @@ executable_instruction!(
})?;
let instance = &mut runtime.wasm_instance;
let memory_index: u32 = 0;
let memory_index = 0;
let memory_view = instance
.memory(memory_index as usize)
.memory(memory_index)
.ok_or_else(|| {
InstructionError::new(
instruction.clone(),

View File

@ -24,9 +24,9 @@ where
MemoryView: wasm::structures::MemoryView,
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
{
let memory_index: u32 = 0;
let memory_index = 0;
let memory_view = instance
.memory(memory_index as usize)
.memory(memory_index)
.ok_or_else(|| {
InstructionError::new(
instruction.clone(),
@ -66,11 +66,15 @@ where
MemoryView: wasm::structures::MemoryView,
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
{
if bytes.is_empty() {
return Ok(0);
}
let offset = allocate(instance, instruction.clone(), bytes.len() as _)?;
let memory_index: u32 = 0;
let memory_index = 0;
let memory_view = instance
.memory(memory_index as usize)
.memory(memory_index)
.ok_or_else(|| {
InstructionError::new(
instruction.clone(),