mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 15:20:20 +00:00
improve array passing
This commit is contained in:
parent
28114f8cdb
commit
41555d4d32
16
Cargo.lock
generated
16
Cargo.lock
generated
@ -20,6 +20,12 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "fluence-it-types"
|
||||
version = "0.1.1"
|
||||
@ -34,6 +40,15 @@ dependencies = [
|
||||
name = "it-to-bytes"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
@ -214,6 +229,7 @@ version = "0.19.0"
|
||||
dependencies = [
|
||||
"fluence-it-types",
|
||||
"it-to-bytes",
|
||||
"itertools",
|
||||
"log",
|
||||
"nom",
|
||||
"safe-transmute",
|
||||
|
@ -18,6 +18,7 @@ where
|
||||
{
|
||||
fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
|
||||
match self {
|
||||
IType::Boolean => 0x0b_u8.to_bytes(writer),
|
||||
IType::S8 => 0x00_u8.to_bytes(writer),
|
||||
IType::S16 => 0x01_u8.to_bytes(writer),
|
||||
IType::S32 => 0x02_u8.to_bytes(writer),
|
||||
@ -29,11 +30,11 @@ where
|
||||
IType::F32 => 0x08_u8.to_bytes(writer),
|
||||
IType::F64 => 0x09_u8.to_bytes(writer),
|
||||
IType::String => 0x0a_u8.to_bytes(writer),
|
||||
IType::ByteArray => 0x3C_u8.to_bytes(writer),
|
||||
IType::Array(ty) => {
|
||||
0x36_u8.to_bytes(writer)?;
|
||||
ty.to_bytes(writer)
|
||||
}
|
||||
IType::Anyref => 0x0b_u8.to_bytes(writer),
|
||||
IType::I32 => 0x0c_u8.to_bytes(writer),
|
||||
IType::I64 => 0x0d_u8.to_bytes(writer),
|
||||
IType::Record(record_id) => {
|
||||
@ -77,6 +78,7 @@ mod keyword {
|
||||
custom_keyword!(field);
|
||||
|
||||
// New types.
|
||||
custom_keyword!(boolean);
|
||||
custom_keyword!(s8);
|
||||
custom_keyword!(s16);
|
||||
custom_keyword!(s32);
|
||||
@ -92,7 +94,11 @@ mod keyword {
|
||||
impl Parse<'_> for IType {
|
||||
fn parse(parser: Parser<'_>) -> Result<IType, ParseError> {
|
||||
let mut lookahead = parser.lookahead1();
|
||||
if lookahead.peek::<keyword::s8>() {
|
||||
if lookahead.peek::<keyword::boolean>() {
|
||||
parser.parse::<keyword::boolean>()?;
|
||||
|
||||
Ok(IType::Boolean)
|
||||
} else if lookahead.peek::<keyword::s8>() {
|
||||
parser.parse::<keyword::s8>()?;
|
||||
|
||||
Ok(IType::S8)
|
||||
@ -142,10 +148,6 @@ impl Parse<'_> for IType {
|
||||
let array_type = parser.parens(|p| p.parse())?;
|
||||
|
||||
Ok(IType::Array(Box::new(array_type)))
|
||||
} else if lookahead.peek::<keyword::anyref>() {
|
||||
parser.parse::<keyword::anyref>()?;
|
||||
|
||||
Ok(IType::Anyref)
|
||||
} else if lookahead.peek::<keyword::i32>() {
|
||||
parser.parse::<keyword::i32>()?;
|
||||
|
||||
|
@ -8,6 +8,9 @@ use serde::Serialize;
|
||||
/// Represents the types supported by WIT.
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
|
||||
pub enum IType {
|
||||
/// Boolean.
|
||||
Boolean,
|
||||
|
||||
/// A 8-bits signed integer.
|
||||
S8,
|
||||
|
||||
@ -41,12 +44,12 @@ pub enum IType {
|
||||
/// A string.
|
||||
String,
|
||||
|
||||
/// Specialization of arrays for byte vector.
|
||||
ByteArray,
|
||||
|
||||
/// An array of values of the same type.
|
||||
Array(Box<IType>),
|
||||
|
||||
/// An `any` reference.
|
||||
Anyref,
|
||||
|
||||
/// A 32-bits integer (as defined in WebAssembly core).
|
||||
I32,
|
||||
|
||||
@ -98,6 +101,7 @@ impl Default for RecordType {
|
||||
impl ToString for &IType {
|
||||
fn to_string(&self) -> String {
|
||||
match &self {
|
||||
IType::Boolean => "boolean".to_string(),
|
||||
IType::S8 => "s8".to_string(),
|
||||
IType::S16 => "s16".to_string(),
|
||||
IType::S32 => "s32".to_string(),
|
||||
@ -109,8 +113,8 @@ impl ToString for &IType {
|
||||
IType::F32 => "f32".to_string(),
|
||||
IType::F64 => "f64".to_string(),
|
||||
IType::String => "string".to_string(),
|
||||
IType::ByteArray => "array (u8)".to_string(),
|
||||
IType::Array(ty) => format!("array ({})", ty.as_ref().to_string()),
|
||||
IType::Anyref => "anyref".to_string(),
|
||||
IType::I32 => "i32".to_string(),
|
||||
IType::I64 => "i64".to_string(),
|
||||
IType::Record(record_type_id) => format!("record {}", record_type_id),
|
||||
|
@ -5,6 +5,9 @@ use crate::ne_vec::NEVec;
|
||||
/// A WIT value.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum IValue {
|
||||
/// Boolean value.
|
||||
Boolean(bool),
|
||||
|
||||
/// A 8-bits signed integer.
|
||||
S8(i8),
|
||||
|
||||
@ -38,14 +41,16 @@ pub enum IValue {
|
||||
/// A string.
|
||||
String(String),
|
||||
|
||||
/// Specialization of array type for byte vector.
|
||||
ByteArray(Vec<u8>),
|
||||
|
||||
/// A byte array.
|
||||
Array(Vec<IValue>),
|
||||
|
||||
//Anyref(?),
|
||||
/// A 32-bits integer (as defined in WebAssembly core).
|
||||
I32(i32),
|
||||
|
||||
/// A 64-bits integer (as defiend in WebAssembly core).
|
||||
/// A 64-bits integer (as defined in WebAssembly core).
|
||||
I64(i64),
|
||||
|
||||
/// A record.
|
||||
|
@ -21,6 +21,7 @@ serde = { version = "1.0", features = ["derive", "rc"], optional = true }
|
||||
serde_json = "1.0"
|
||||
safe-transmute = "0.11.0"
|
||||
log = "0.4.11"
|
||||
itertools = "0.10.0"
|
||||
|
||||
semver = "0.11.0"
|
||||
|
||||
|
@ -112,6 +112,7 @@ fn ty<'input, E: ParseError<&'input [u8]>>(
|
||||
consume!((input, opcode) = byte(input)?);
|
||||
|
||||
let ty = match opcode {
|
||||
0x0b => IType::Boolean,
|
||||
0x00 => IType::S8,
|
||||
0x01 => IType::S16,
|
||||
0x02 => IType::S32,
|
||||
@ -123,12 +124,12 @@ fn ty<'input, E: ParseError<&'input [u8]>>(
|
||||
0x08 => IType::F32,
|
||||
0x09 => IType::F64,
|
||||
0x0a => IType::String,
|
||||
0x3c => IType::ByteArray,
|
||||
0x36 => {
|
||||
consume!((input, array_value_type) = ty(input)?);
|
||||
|
||||
IType::Array(Box::new(array_value_type))
|
||||
}
|
||||
0x0b => IType::Anyref,
|
||||
0x0c => IType::I32,
|
||||
0x0d => IType::I64,
|
||||
0x0e => {
|
||||
|
@ -354,7 +354,6 @@ mod tests {
|
||||
(&IType::F32).to_string(),
|
||||
(&IType::F64).to_string(),
|
||||
(&IType::String).to_string(),
|
||||
(&IType::Anyref).to_string(),
|
||||
(&IType::I32).to_string(),
|
||||
(&IType::I64).to_string(),
|
||||
(&IType::Record(RecordType {
|
||||
|
@ -41,6 +41,16 @@ impl InstructionError {
|
||||
|
||||
impl Error for InstructionError {}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! instr_error {
|
||||
($instruction:expr, $error_kind:expr) => {
|
||||
Err(crate::errors::InstructionError::new(
|
||||
$instruction,
|
||||
$error_kind,
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
impl Display for InstructionError {
|
||||
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
|
||||
write!(
|
||||
|
@ -1,7 +1,5 @@
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::Instruction,
|
||||
};
|
||||
use crate::instr_error;
|
||||
use crate::{errors::InstructionErrorKind, interpreter::Instruction};
|
||||
|
||||
executable_instruction!(
|
||||
argument_get(index: u32, instruction: Instruction) -> _ {
|
||||
@ -9,10 +7,10 @@ executable_instruction!(
|
||||
let invocation_inputs = runtime.invocation_inputs;
|
||||
|
||||
if (index as usize) >= invocation_inputs.len() {
|
||||
return Err(InstructionError::new(
|
||||
return instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::InvocationInputIsMissing { index },
|
||||
));
|
||||
InstructionErrorKind::InvocationInputIsMissing { index }
|
||||
);
|
||||
}
|
||||
|
||||
log::debug!("arg.get: pushing {:?} on the stack", invocation_inputs[index as usize]);
|
||||
|
@ -1,6 +1,11 @@
|
||||
use super::read_from_instance_mem;
|
||||
use super::write_to_instance_mem;
|
||||
mod read_arrays;
|
||||
|
||||
use super::read_from_instance_mem;
|
||||
use super::record_lift_memory_;
|
||||
use super::write_to_instance_mem;
|
||||
use read_arrays::*;
|
||||
|
||||
use crate::instr_error;
|
||||
use crate::interpreter::instructions::to_native;
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
@ -14,9 +19,9 @@ pub(super) fn array_lift_memory_<'instance, Instance, Export, LocalImport, Memor
|
||||
instance: &'instance Instance,
|
||||
value_type: &IType,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
elements_count: usize,
|
||||
instruction: Instruction,
|
||||
) -> Result<Vec<IValue>, InstructionError>
|
||||
) -> Result<IValue, InstructionError>
|
||||
where
|
||||
Export: crate::interpreter::wasm::structures::Export,
|
||||
LocalImport: crate::interpreter::wasm::structures::LocalImport,
|
||||
@ -25,162 +30,43 @@ where
|
||||
Instance: crate::interpreter::wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>
|
||||
+ 'instance,
|
||||
{
|
||||
use safe_transmute::guard::AllOrNothingGuard;
|
||||
use safe_transmute::transmute_many;
|
||||
use safe_transmute::transmute_vec;
|
||||
|
||||
if size == 0 {
|
||||
return Ok(vec![]);
|
||||
if elements_count == 0 {
|
||||
return Ok(IValue::Array(vec![]));
|
||||
}
|
||||
|
||||
let data = read_from_instance_mem(instance, instruction.clone(), offset, size)?;
|
||||
|
||||
let result_array = match value_type {
|
||||
IType::S8 => {
|
||||
let data = transmute_vec::<u8, i8>(data).unwrap();
|
||||
data.into_iter().map(IValue::S8).collect::<Vec<_>>()
|
||||
}
|
||||
IType::S16 => {
|
||||
let data = transmute_many::<i16, AllOrNothingGuard>(&data).unwrap();
|
||||
|
||||
data.iter().map(|v| IValue::S16(*v)).collect::<Vec<_>>()
|
||||
}
|
||||
IType::S32 => {
|
||||
let data = transmute_many::<i32, AllOrNothingGuard>(&data).unwrap();
|
||||
data.iter().map(|v| IValue::S32(*v)).collect::<Vec<_>>()
|
||||
}
|
||||
IType::S64 => {
|
||||
let data = transmute_many::<i64, AllOrNothingGuard>(&data).unwrap();
|
||||
data.iter().map(|v| IValue::S64(*v)).collect::<Vec<_>>()
|
||||
}
|
||||
IType::I32 => {
|
||||
let data = transmute_many::<i32, AllOrNothingGuard>(&data).unwrap();
|
||||
data.iter().map(|v| IValue::I32(*v)).collect::<Vec<_>>()
|
||||
}
|
||||
IType::I64 => {
|
||||
let data = transmute_many::<i64, AllOrNothingGuard>(&data).unwrap();
|
||||
data.iter().map(|v| IValue::S64(*v)).collect::<Vec<_>>()
|
||||
}
|
||||
IType::U8 => data.into_iter().map(IValue::U8).collect::<Vec<_>>(),
|
||||
IType::U16 => {
|
||||
let data = transmute_many::<u16, AllOrNothingGuard>(&data).unwrap();
|
||||
data.iter().map(|v| IValue::U16(*v)).collect::<Vec<_>>()
|
||||
}
|
||||
IType::U32 => {
|
||||
let data = transmute_many::<u32, AllOrNothingGuard>(&data).unwrap();
|
||||
data.iter().map(|v| IValue::U32(*v)).collect::<Vec<_>>()
|
||||
}
|
||||
IType::U64 => {
|
||||
let data = transmute_many::<u64, AllOrNothingGuard>(&data).unwrap();
|
||||
data.iter().map(|v| IValue::U64(*v)).collect::<Vec<_>>()
|
||||
}
|
||||
IType::F32 => {
|
||||
let data = transmute_many::<u32, AllOrNothingGuard>(&data).unwrap();
|
||||
data.iter()
|
||||
.map(|v| IValue::F32(f32::from_bits(*v)))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
IType::F64 => {
|
||||
let data = transmute_many::<u64, AllOrNothingGuard>(&data).unwrap();
|
||||
data.iter()
|
||||
.map(|v| IValue::F64(f64::from_bits(*v)))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
IType::Anyref => unimplemented!(),
|
||||
IType::String => {
|
||||
let data = transmute_many::<u32, AllOrNothingGuard>(&data).unwrap();
|
||||
|
||||
if data.is_empty() {
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let mut result = Vec::with_capacity(data.len() / 2);
|
||||
let mut data = data.iter();
|
||||
|
||||
while let Some(string_offset) = data.next() {
|
||||
let string_size = data.next().ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::CorruptedArray(String::from(
|
||||
"serialized array must contain even count of elements",
|
||||
)),
|
||||
)
|
||||
})?;
|
||||
|
||||
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();
|
||||
result.push(IValue::String(string));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
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) => {
|
||||
let data = transmute_many::<u32, AllOrNothingGuard>(&data).unwrap();
|
||||
|
||||
if data.is_empty() {
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let mut result = Vec::with_capacity(data.len() / 2);
|
||||
let mut data = data.iter();
|
||||
|
||||
while let Some(array_offset) = data.next() {
|
||||
let array_size = data.next().ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::CorruptedArray(String::from(
|
||||
"serialized array must contain even count of elements",
|
||||
)),
|
||||
)
|
||||
})?;
|
||||
|
||||
let value = array_lift_memory_(
|
||||
instance,
|
||||
&*ty,
|
||||
*array_offset as _,
|
||||
*array_size as _,
|
||||
instruction.clone(),
|
||||
)?;
|
||||
|
||||
result.push(IValue::Array(value));
|
||||
}
|
||||
|
||||
result
|
||||
read_array_array(instance, instruction.clone(), &ty, offset, elements_count)
|
||||
}
|
||||
IType::Record(record_type_id) => {
|
||||
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,
|
||||
},
|
||||
)
|
||||
})?;
|
||||
|
||||
let data = transmute_many::<u32, AllOrNothingGuard>(&data).unwrap();
|
||||
|
||||
let mut result = Vec::with_capacity(data.len());
|
||||
|
||||
for record_offset in data {
|
||||
result.push(super::record_lift_memory_(
|
||||
instance,
|
||||
record_type,
|
||||
*record_offset as _,
|
||||
instruction.clone(),
|
||||
)?);
|
||||
}
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
Ok(result_array)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn array_lift_memory<Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
@ -233,7 +119,7 @@ where
|
||||
)?;
|
||||
|
||||
log::trace!("array.lift_memory: pushing {:?} on the stack", array);
|
||||
runtime.stack.push(IValue::Array(array));
|
||||
runtime.stack.push(array);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -356,13 +242,13 @@ where
|
||||
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(InstructionError::new(
|
||||
_ => instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: IType::Array(Box::new(value_type.clone())),
|
||||
received_value: stack_value.clone(),
|
||||
},
|
||||
)),
|
||||
received_value: stack_value.clone()
|
||||
}
|
||||
),
|
||||
}
|
||||
}
|
||||
})
|
||||
|
476
wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs
Normal file
476
wasmer-it/src/interpreter/instructions/arrays/read_arrays.rs
Normal file
@ -0,0 +1,476 @@
|
||||
use crate::instr_error;
|
||||
use crate::interpreter::wasm;
|
||||
use crate::IValue;
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::Instruction,
|
||||
};
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
macro_rules! def_read_func {
|
||||
($func_name: ident, ($ty:ident, $elements_count:ident), $ctor:expr) => {
|
||||
pub(super) fn $func_name<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &'instance Instance,
|
||||
instruction: Instruction,
|
||||
offset: usize,
|
||||
$elements_count: usize,
|
||||
) -> Result<IValue, InstructionError>
|
||||
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>,
|
||||
{
|
||||
let value_size = std::mem::size_of::<$ty>();
|
||||
|
||||
let ctor_ = $ctor;
|
||||
|
||||
let ivalues = ivalues_from_mem(
|
||||
instance,
|
||||
instruction,
|
||||
offset,
|
||||
value_size * $elements_count,
|
||||
ctor_,
|
||||
)?;
|
||||
|
||||
let ivalue = IValue::Array(ivalues);
|
||||
Ok(ivalue)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn ivalues_from_mem<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &'instance Instance,
|
||||
instruction: Instruction,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
ivalue_ctor: impl FnOnce(&[Cell<u8>]) -> Vec<IValue>,
|
||||
) -> Result<Vec<IValue>, InstructionError>
|
||||
where
|
||||
Export: wasm::structures::Export + 'instance,
|
||||
LocalImport: wasm::structures::LocalImport + 'instance,
|
||||
Memory: wasm::structures::Memory<MemoryView> + 'instance,
|
||||
MemoryView: wasm::structures::MemoryView + 'instance,
|
||||
Instance: wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
|
||||
{
|
||||
let memory_index: u32 = 0;
|
||||
let memory_view = instance
|
||||
.memory(memory_index as usize)
|
||||
.ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::MemoryIsMissing { memory_index },
|
||||
)
|
||||
})?
|
||||
.view();
|
||||
|
||||
log::trace!("reading {} bytes from offset {}", size, offset);
|
||||
|
||||
let right = offset + size;
|
||||
if right < offset || right >= memory_view.len() {
|
||||
return instr_error!(
|
||||
instruction,
|
||||
InstructionErrorKind::MemoryOutOfBoundsAccess {
|
||||
index: right,
|
||||
length: memory_view.len(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let view = &memory_view[offset..offset + size];
|
||||
let ivalues = ivalue_ctor(view);
|
||||
Ok(ivalues)
|
||||
}
|
||||
|
||||
def_read_func!(read_bool_array, (bool, elements_count), {
|
||||
|memory_view: &[Cell<u8>]| {
|
||||
let mut result = Vec::with_capacity(elements_count);
|
||||
for element_id in 0..elements_count {
|
||||
let value = Cell::get(&memory_view[element_id]);
|
||||
result.push(IValue::Boolean(value == 1));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
def_read_func!(read_u8_array, (u8, elements_count), {
|
||||
|memory_view: &[Cell<u8>]| {
|
||||
let mut result = Vec::with_capacity(elements_count);
|
||||
for element_id in 0..elements_count {
|
||||
let value = Cell::get(&memory_view[element_id]);
|
||||
result.push(IValue::U8(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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])]);
|
||||
result.push(IValue::S8(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[2 * element_id]),
|
||||
Cell::get(&memory_view[2 * element_id + 1]),
|
||||
]);
|
||||
result.push(IValue::U16(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[2 * element_id]),
|
||||
Cell::get(&memory_view[2 * element_id + 1]),
|
||||
]);
|
||||
result.push(IValue::S16(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[4 * element_id]),
|
||||
Cell::get(&memory_view[4 * element_id + 1]),
|
||||
Cell::get(&memory_view[4 * element_id + 2]),
|
||||
Cell::get(&memory_view[4 * element_id + 3]),
|
||||
]);
|
||||
result.push(IValue::U32(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[4 * element_id]),
|
||||
Cell::get(&memory_view[4 * element_id + 1]),
|
||||
Cell::get(&memory_view[4 * element_id + 2]),
|
||||
Cell::get(&memory_view[4 * element_id + 3]),
|
||||
]);
|
||||
result.push(IValue::F32(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[4 * element_id]),
|
||||
Cell::get(&memory_view[4 * element_id + 1]),
|
||||
Cell::get(&memory_view[4 * element_id + 2]),
|
||||
Cell::get(&memory_view[4 * element_id + 3]),
|
||||
]);
|
||||
result.push(IValue::S32(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[4 * element_id]),
|
||||
Cell::get(&memory_view[4 * element_id + 1]),
|
||||
Cell::get(&memory_view[4 * element_id + 2]),
|
||||
Cell::get(&memory_view[4 * element_id + 3]),
|
||||
]);
|
||||
result.push(IValue::I32(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[4 * element_id]),
|
||||
Cell::get(&memory_view[4 * element_id + 1]),
|
||||
Cell::get(&memory_view[4 * element_id + 2]),
|
||||
Cell::get(&memory_view[4 * element_id + 3]),
|
||||
Cell::get(&memory_view[4 * element_id + 4]),
|
||||
Cell::get(&memory_view[4 * element_id + 5]),
|
||||
Cell::get(&memory_view[4 * element_id + 6]),
|
||||
Cell::get(&memory_view[4 * element_id + 7]),
|
||||
]);
|
||||
result.push(IValue::U64(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[4 * element_id]),
|
||||
Cell::get(&memory_view[4 * element_id + 1]),
|
||||
Cell::get(&memory_view[4 * element_id + 2]),
|
||||
Cell::get(&memory_view[4 * element_id + 3]),
|
||||
Cell::get(&memory_view[4 * element_id + 4]),
|
||||
Cell::get(&memory_view[4 * element_id + 5]),
|
||||
Cell::get(&memory_view[4 * element_id + 6]),
|
||||
Cell::get(&memory_view[4 * element_id + 7]),
|
||||
]);
|
||||
result.push(IValue::F64(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[4 * element_id]),
|
||||
Cell::get(&memory_view[4 * element_id + 1]),
|
||||
Cell::get(&memory_view[4 * element_id + 2]),
|
||||
Cell::get(&memory_view[4 * element_id + 3]),
|
||||
Cell::get(&memory_view[4 * element_id + 4]),
|
||||
Cell::get(&memory_view[4 * element_id + 5]),
|
||||
Cell::get(&memory_view[4 * element_id + 6]),
|
||||
Cell::get(&memory_view[4 * element_id + 7]),
|
||||
]);
|
||||
result.push(IValue::S64(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
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([
|
||||
Cell::get(&memory_view[4 * element_id]),
|
||||
Cell::get(&memory_view[4 * element_id + 1]),
|
||||
Cell::get(&memory_view[4 * element_id + 2]),
|
||||
Cell::get(&memory_view[4 * element_id + 3]),
|
||||
Cell::get(&memory_view[4 * element_id + 4]),
|
||||
Cell::get(&memory_view[4 * element_id + 5]),
|
||||
Cell::get(&memory_view[4 * element_id + 6]),
|
||||
Cell::get(&memory_view[4 * element_id + 7]),
|
||||
]);
|
||||
result.push(IValue::I64(value));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
});
|
||||
|
||||
use super::read_from_instance_mem;
|
||||
use safe_transmute::guard::AllOrNothingGuard;
|
||||
use safe_transmute::transmute_many;
|
||||
|
||||
const WASM_POINTER_SIZE: usize = 4;
|
||||
|
||||
pub(super) fn read_string_array<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &'instance Instance,
|
||||
instruction: Instruction,
|
||||
offset: usize,
|
||||
elements_count: usize,
|
||||
) -> 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 data = read_from_instance_mem(
|
||||
instance,
|
||||
instruction.clone(),
|
||||
offset,
|
||||
WASM_POINTER_SIZE * elements_count,
|
||||
)?;
|
||||
let data = transmute_many::<u32, AllOrNothingGuard>(&data).unwrap();
|
||||
|
||||
if data.is_empty() {
|
||||
return Ok(IValue::Array(vec![]));
|
||||
}
|
||||
|
||||
let mut result = Vec::with_capacity(data.len() / 2);
|
||||
let mut data = data.iter();
|
||||
|
||||
while let Some(string_offset) = data.next() {
|
||||
let string_size = data.next().ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::CorruptedArray(String::from(
|
||||
"serialized array must contain even count of elements",
|
||||
)),
|
||||
)
|
||||
})?;
|
||||
|
||||
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();
|
||||
result.push(IValue::String(string));
|
||||
}
|
||||
|
||||
let result = IValue::Array(result);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub(super) fn read_record_array<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &'instance Instance,
|
||||
instruction: Instruction,
|
||||
record_type_id: u64,
|
||||
offset: usize,
|
||||
elements_count: usize,
|
||||
) -> 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 record_type = instance.wit_record_by_id(record_type_id).ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::RecordTypeByNameIsMissing { record_type_id },
|
||||
)
|
||||
})?;
|
||||
|
||||
let data = read_from_instance_mem(
|
||||
instance,
|
||||
instruction.clone(),
|
||||
offset,
|
||||
WASM_POINTER_SIZE * elements_count,
|
||||
)?;
|
||||
let data = transmute_many::<u32, AllOrNothingGuard>(&data).unwrap();
|
||||
|
||||
let mut result = Vec::with_capacity(data.len());
|
||||
|
||||
for record_offset in data {
|
||||
result.push(super::record_lift_memory_(
|
||||
instance,
|
||||
record_type,
|
||||
*record_offset as _,
|
||||
instruction.clone(),
|
||||
)?);
|
||||
}
|
||||
|
||||
let result = IValue::Array(result);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub(super) fn read_array_array<'instance, Instance, Export, LocalImport, Memory, MemoryView>(
|
||||
instance: &'instance Instance,
|
||||
instruction: Instruction,
|
||||
ty: &crate::IType,
|
||||
offset: usize,
|
||||
elements_count: usize,
|
||||
) -> 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 data = read_from_instance_mem(
|
||||
instance,
|
||||
instruction.clone(),
|
||||
offset,
|
||||
WASM_POINTER_SIZE * elements_count,
|
||||
)?;
|
||||
let data = transmute_many::<u32, AllOrNothingGuard>(&data).unwrap();
|
||||
|
||||
if data.is_empty() {
|
||||
return Ok(IValue::Array(vec![]));
|
||||
}
|
||||
|
||||
let mut result = Vec::with_capacity(data.len() / 2);
|
||||
let mut data = data.iter();
|
||||
|
||||
while let Some(array_offset) = data.next() {
|
||||
let array_size = data.next().ok_or_else(|| {
|
||||
InstructionError::new(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::CorruptedArray(String::from(
|
||||
"serialized array must contain even count of elements",
|
||||
)),
|
||||
)
|
||||
})?;
|
||||
|
||||
let value = match ty {
|
||||
crate::IType::ByteArray => {
|
||||
let value = read_from_instance_mem(
|
||||
instance,
|
||||
instruction.clone(),
|
||||
*array_offset as _,
|
||||
*array_size as _,
|
||||
)?;
|
||||
IValue::ByteArray(value)
|
||||
}
|
||||
_ => super::array_lift_memory_(
|
||||
instance,
|
||||
&*ty,
|
||||
*array_offset as _,
|
||||
*array_size as _,
|
||||
instruction.clone(),
|
||||
)?,
|
||||
};
|
||||
|
||||
result.push(value);
|
||||
}
|
||||
|
||||
let result = IValue::Array(result);
|
||||
Ok(result)
|
||||
}
|
@ -11,10 +11,12 @@ mod utils;
|
||||
use crate::errors::{
|
||||
InstructionError, InstructionErrorKind, InstructionResult, WasmValueNativeCastError,
|
||||
};
|
||||
use crate::instr_error;
|
||||
use crate::interpreter::wasm;
|
||||
use crate::IType;
|
||||
use crate::IValue;
|
||||
use crate::NEVec;
|
||||
|
||||
pub(crate) use argument_get::argument_get;
|
||||
pub(crate) use arrays::*;
|
||||
pub(crate) use call_core::call_core;
|
||||
@ -292,13 +294,13 @@ where
|
||||
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(InstructionError::new(
|
||||
_ => instr_error!(
|
||||
instruction,
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: interface_type.clone(),
|
||||
received_value: interface_value.clone(),
|
||||
},
|
||||
)),
|
||||
}
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,14 +332,14 @@ where
|
||||
})?;
|
||||
|
||||
if record_fields.len() != record_type.fields.len() {
|
||||
return Err(InstructionError::new(
|
||||
return instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: IType::Record(record_type_id),
|
||||
// unwrap is safe here - len's been already checked
|
||||
received_value: IValue::Record(NEVec::new(record_fields.to_vec()).unwrap()),
|
||||
},
|
||||
));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
for (record_type_field, record_value_field) in
|
||||
|
@ -1,9 +1,11 @@
|
||||
use crate::instr_error;
|
||||
use crate::IType;
|
||||
use crate::IValue;
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::Instruction,
|
||||
};
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
macro_rules! lowering_lifting {
|
||||
@ -34,20 +36,20 @@ macro_rules! lowering_lifting {
|
||||
})
|
||||
}
|
||||
Some(wrong_value) => {
|
||||
return Err(InstructionError::new(
|
||||
return instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: IType::$from_variant,
|
||||
received_value: wrong_value,
|
||||
}
|
||||
))
|
||||
)
|
||||
},
|
||||
|
||||
None => {
|
||||
return Err(InstructionError::new(
|
||||
return instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 },
|
||||
))
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
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;
|
||||
@ -175,7 +176,6 @@ where
|
||||
values.push(IValue::F32(value as _));
|
||||
}
|
||||
IType::F64 => values.push(IValue::F64(f64::from_bits(value))),
|
||||
IType::Anyref => {}
|
||||
IType::String => {
|
||||
let string_offset = value;
|
||||
field_id += 1;
|
||||
@ -209,7 +209,7 @@ where
|
||||
array_size as _,
|
||||
instruction.clone(),
|
||||
)?;
|
||||
values.push(IValue::Array(array));
|
||||
values.push(array);
|
||||
} else {
|
||||
values.push(IValue::Array(vec![]));
|
||||
}
|
||||
@ -399,17 +399,17 @@ where
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Some(value) => Err(InstructionError::new(
|
||||
Some(value) => instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: IType::Record(record_type_id),
|
||||
received_value: value,
|
||||
},
|
||||
)),
|
||||
None => Err(InstructionError::new(
|
||||
}
|
||||
),
|
||||
None => instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 },
|
||||
)),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 }
|
||||
),
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1,10 +1,12 @@
|
||||
use super::to_native;
|
||||
use crate::instr_error;
|
||||
use crate::IType;
|
||||
use crate::IValue;
|
||||
use crate::{
|
||||
errors::{InstructionError, InstructionErrorKind},
|
||||
interpreter::Instruction,
|
||||
};
|
||||
|
||||
use std::{cell::Cell, convert::TryInto};
|
||||
|
||||
executable_instruction!(
|
||||
@ -45,13 +47,13 @@ executable_instruction!(
|
||||
}
|
||||
|
||||
if memory_view.len() < pointer + length {
|
||||
return Err(InstructionError::new(
|
||||
return instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::MemoryOutOfBoundsAccess {
|
||||
index: pointer + length,
|
||||
length: memory_view.len(),
|
||||
},
|
||||
));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let data: Vec<u8> = (&memory_view[pointer..pointer + length])
|
||||
@ -131,18 +133,18 @@ executable_instruction!(
|
||||
Ok(())
|
||||
},
|
||||
|
||||
Some(value) => Err(InstructionError::new(
|
||||
Some(value) => instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: IType::String,
|
||||
received_value: (&value).clone(),
|
||||
},
|
||||
)),
|
||||
}
|
||||
),
|
||||
|
||||
None => Err(InstructionError::new(
|
||||
None => instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 },
|
||||
)),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 }
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use crate::interpreter::instructions::ALLOCATE_FUNC_INDEX;
|
||||
use crate::interpreter::wasm;
|
||||
use crate::interpreter::wasm::structures::{FunctionIndex, TypedIndex};
|
||||
|
||||
use crate::instr_error;
|
||||
use crate::interpreter::instructions::to_native;
|
||||
use crate::IType;
|
||||
use crate::IValue;
|
||||
@ -38,13 +39,13 @@ where
|
||||
|
||||
let right = offset + size;
|
||||
if right < offset || right >= memory_view.len() {
|
||||
return Err(InstructionError::new(
|
||||
return instr_error!(
|
||||
instruction,
|
||||
InstructionErrorKind::MemoryOutOfBoundsAccess {
|
||||
index: right,
|
||||
length: memory_view.len(),
|
||||
},
|
||||
));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Ok((&memory_view[offset..offset + size])
|
||||
@ -82,13 +83,13 @@ where
|
||||
|
||||
let right = offset + bytes.len();
|
||||
if right < offset || right >= memory_view.len() {
|
||||
return Err(InstructionError::new(
|
||||
return instr_error!(
|
||||
instruction,
|
||||
InstructionErrorKind::MemoryOutOfBoundsAccess {
|
||||
index: right,
|
||||
length: memory_view.len(),
|
||||
},
|
||||
));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
for (byte_id, byte) in bytes.iter().enumerate() {
|
||||
@ -117,14 +118,14 @@ where
|
||||
vec![IValue::I32(size as _)],
|
||||
)?;
|
||||
if values.len() != 1 {
|
||||
return Err(InstructionError::new(
|
||||
return instr_error!(
|
||||
instruction,
|
||||
InstructionErrorKind::LocalOrImportSignatureMismatch {
|
||||
function_index: ALLOCATE_FUNC_INDEX,
|
||||
expected: (vec![IType::I32], vec![]),
|
||||
received: (vec![], vec![]),
|
||||
},
|
||||
));
|
||||
}
|
||||
);
|
||||
}
|
||||
to_native::<i32>(&values[0], instruction).map(|v| v as usize)
|
||||
}
|
||||
|
@ -242,15 +242,6 @@ where
|
||||
let value_type = value_type.clone();
|
||||
instructions::array_lower_memory(instruction, value_type)
|
||||
}
|
||||
|
||||
/*
|
||||
Instruction::RecordLift { type_index } => {
|
||||
instructions::record_lift(*type_index, instruction)
|
||||
}
|
||||
Instruction::RecordLower { type_index } => {
|
||||
instructions::record_lower(*type_index, instruction)
|
||||
}
|
||||
*/
|
||||
Instruction::RecordLiftMemory { record_type_id } => {
|
||||
instructions::record_lift_memory(record_type_id as _, instruction)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user