mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 07:10:21 +00:00
support u128
This commit is contained in:
parent
9095389a5a
commit
34bf8a196a
@ -37,6 +37,7 @@ pub fn ser_type_size(ty: &IType) -> usize {
|
||||
// Vec-like types are passed by pointer and size
|
||||
IType::String | IType::ByteArray | IType::Array(_) => 2 * WASM_POINTER_SIZE,
|
||||
IType::S64 | IType::U64 | IType::I64 | IType::F64 => 8,
|
||||
IType::U128 => 16,
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +48,7 @@ pub fn ser_value_size(value: &IValue) -> usize {
|
||||
IValue::S16(_) | IValue::U16(_) => 2,
|
||||
IValue::S32(_) | IValue::U32(_) | IValue::F32(_) | IValue::I32(_) => 4,
|
||||
IValue::S64(_) | IValue::U64(_) | IValue::F64(_) | IValue::I64(_) => 8,
|
||||
IValue::U128(_) => 16,
|
||||
IValue::String(_) | IValue::ByteArray(_) | IValue::Array(_) => 2 * 4,
|
||||
IValue::Record(_) => 4,
|
||||
}
|
||||
@ -70,12 +72,13 @@ pub fn type_tag_form_itype(itype: &IType) -> u32 {
|
||||
IType::U16 => 2, // u16
|
||||
IType::U32 => 3, // u32
|
||||
IType::U64 => 4, // u64
|
||||
IType::S8 => 5, // i8
|
||||
IType::S16 => 6, // i16
|
||||
IType::S32 | IType::I32 => 7, // i32
|
||||
IType::S64 | IType::I64 => 8, // i64
|
||||
IType::F32 => 9, // f32
|
||||
IType::F64 => 10, // f64
|
||||
IType::U128 => 5, // u128
|
||||
IType::S8 => 6, // i8
|
||||
IType::S16 => 7, // i16
|
||||
IType::S32 | IType::I32 => 8, // i32
|
||||
IType::S64 | IType::I64 => 9, // i64
|
||||
IType::F32 => 10, // f32
|
||||
IType::F64 => 11, // f64
|
||||
IType::ByteArray | IType::Array(_) | IType::Record(_) | IType::String => POINTER_CODE,
|
||||
}
|
||||
}
|
||||
@ -89,12 +92,13 @@ pub fn type_tag_form_ivalue(itype: &IValue) -> u32 {
|
||||
IValue::U16(_) => 2, // u16
|
||||
IValue::U32(_) => 3, // u32
|
||||
IValue::U64(_) => 4, // u64
|
||||
IValue::S8(_) => 5, // i8
|
||||
IValue::S16(_) => 6, // i16
|
||||
IValue::S32(_) | IValue::I32(_) => 7, // i32
|
||||
IValue::S64(_) | IValue::I64(_) => 8, // i64
|
||||
IValue::F32(_) => 9, // f32
|
||||
IValue::F64(_) => 10, // f64
|
||||
IValue::U128(_) => 5, // u128
|
||||
IValue::S8(_) => 6, // i8
|
||||
IValue::S16(_) => 7, // i16
|
||||
IValue::S32(_) | IValue::I32(_) => 8, // i32
|
||||
IValue::S64(_) | IValue::I64(_) => 9, // i64
|
||||
IValue::F32(_) => 10, // f32
|
||||
IValue::F64(_) => 11, // f64
|
||||
IValue::ByteArray(_) | IValue::Array(_) | IValue::Record(_) | IValue::String(_) => {
|
||||
POINTER_CODE
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ macro_rules! value_der {
|
||||
($self:expr, $offset:expr, 8) => {
|
||||
crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7 @seq_end);
|
||||
};
|
||||
|
||||
($self:expr, $offset:expr, 16) => {
|
||||
crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 @seq_end);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
@ -78,6 +82,16 @@ macro_rules! read_ty {
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
($func_name:ident, $ty:ty, 16) => {
|
||||
pub fn $func_name(&self) -> $ty {
|
||||
let offset = self.offset.get();
|
||||
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 16));
|
||||
|
||||
self.offset.set(offset + 16);
|
||||
result
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
@ -103,6 +103,7 @@ impl<'m> MemoryReader<'m> {
|
||||
read_array_ty!(read_s64_array, i64, S64);
|
||||
read_array_ty!(read_i64_array, i64, I64);
|
||||
read_array_ty!(read_f64_array, f64, F64);
|
||||
read_array_ty!(read_u128_array, u128, U128);
|
||||
}
|
||||
|
||||
impl<'r, 'm> SequentialReader<'r, 'm> {
|
||||
@ -129,4 +130,5 @@ impl<'r, 'm> SequentialReader<'r, 'm> {
|
||||
read_ty!(read_u64, u64, 8);
|
||||
read_ty!(read_i64, i64, 8);
|
||||
read_ty!(read_f64, f64, 8);
|
||||
read_ty!(read_u128, u128, 16);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ where
|
||||
IType::U64 => 0x07_u8.to_bytes(writer),
|
||||
IType::F32 => 0x08_u8.to_bytes(writer),
|
||||
IType::F64 => 0x09_u8.to_bytes(writer),
|
||||
IType::U128 => 0x46_u8.to_bytes(writer),
|
||||
IType::String => 0x0a_u8.to_bytes(writer),
|
||||
IType::ByteArray => 0x3C_u8.to_bytes(writer),
|
||||
IType::Array(ty) => {
|
||||
@ -87,6 +88,7 @@ mod keyword {
|
||||
custom_keyword!(u16);
|
||||
custom_keyword!(u32);
|
||||
custom_keyword!(u64);
|
||||
custom_keyword!(u128);
|
||||
custom_keyword!(string);
|
||||
custom_keyword!(array);
|
||||
}
|
||||
@ -138,6 +140,10 @@ impl Parse<'_> for IType {
|
||||
parser.parse::<keyword::f64>()?;
|
||||
|
||||
Ok(IType::F64)
|
||||
} else if lookahead.peek::<keyword::u128>() {
|
||||
parser.parse::<keyword::u128>()?;
|
||||
|
||||
Ok(IType::U128)
|
||||
} else if lookahead.peek::<keyword::string>() {
|
||||
parser.parse::<keyword::string>()?;
|
||||
|
||||
|
@ -22,14 +22,14 @@ macro_rules! native {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&IValue> for $native_type {
|
||||
impl TryFrom<IValue> for $native_type {
|
||||
type Error = WasmValueNativeCastError;
|
||||
|
||||
fn try_from(w: &IValue) -> Result<Self, Self::Error> {
|
||||
fn try_from(w: IValue) -> Result<Self, Self::Error> {
|
||||
match w {
|
||||
IValue::$variant(n) => Ok(n.clone()),
|
||||
IValue::$variant(n) => Ok(n),
|
||||
_ => Err(WasmValueNativeCastError {
|
||||
from: w.clone(),
|
||||
from: w,
|
||||
to: <$native_type>::INTERFACE_TYPE,
|
||||
}),
|
||||
}
|
||||
@ -48,4 +48,6 @@ native!(u32, U32);
|
||||
native!(u64, U64);
|
||||
native!(f32, F32);
|
||||
native!(f64, F64);
|
||||
native!(u128, U128);
|
||||
native!(String, String);
|
||||
native!(Vec<u8>, ByteArray);
|
||||
|
@ -41,6 +41,9 @@ pub enum IType {
|
||||
/// A 64-bits float.
|
||||
F64,
|
||||
|
||||
/// A 128-bit unsigned integer.
|
||||
U128,
|
||||
|
||||
/// A string.
|
||||
String,
|
||||
|
||||
@ -112,6 +115,7 @@ impl ToString for &IType {
|
||||
IType::U64 => "u64".to_string(),
|
||||
IType::F32 => "f32".to_string(),
|
||||
IType::F64 => "f64".to_string(),
|
||||
IType::U128 => "u128".to_string(),
|
||||
IType::String => "string".to_string(),
|
||||
IType::ByteArray => "array (u8)".to_string(),
|
||||
IType::Array(ty) => format!("array ({})", ty.as_ref().to_string()),
|
||||
|
@ -38,6 +38,9 @@ pub enum IValue {
|
||||
/// A 64-bits float.
|
||||
F64(f64),
|
||||
|
||||
/// A 128-bits integer.
|
||||
U128(u128),
|
||||
|
||||
/// A string.
|
||||
String(String),
|
||||
|
||||
|
@ -298,6 +298,10 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
|
||||
0x23 => (input, Instruction::StringLowerMemory),
|
||||
0x24 => (input, Instruction::StringSize),
|
||||
|
||||
0x43 => (input, Instruction::ByteArrayLiftMemory),
|
||||
0x44 => (input, Instruction::ByteArrayLowerMemory),
|
||||
0x45 => (input, Instruction::ByteArraySize),
|
||||
|
||||
0x37 => {
|
||||
consume!((input, value_type) = ty(input)?);
|
||||
|
||||
|
@ -80,6 +80,9 @@ mod keyword {
|
||||
custom_keyword!(string_lift_memory = "string.lift_memory");
|
||||
custom_keyword!(string_lower_memory = "string.lower_memory");
|
||||
custom_keyword!(string_size = "string.size");
|
||||
custom_keyword!(byte_array_lift_memory = "byte_array.lift_memory");
|
||||
custom_keyword!(byte_array_lower_memory = "byte_array.lower_memory");
|
||||
custom_keyword!(byte_array_size = "byte_array.size");
|
||||
custom_keyword!(array_lift_memory = "array.lift_memory");
|
||||
custom_keyword!(array_lower_memory = "array.lower_memory");
|
||||
custom_keyword!(array_size = "array.size");
|
||||
@ -260,6 +263,18 @@ impl<'a> Parse<'a> for Instruction {
|
||||
} else if lookahead.peek::<keyword::string_size>() {
|
||||
parser.parse::<keyword::string_size>()?;
|
||||
|
||||
Ok(Instruction::StringSize)
|
||||
} else if lookahead.peek::<keyword::byte_array_lift_memory>() {
|
||||
parser.parse::<keyword::byte_array_lift_memory>()?;
|
||||
|
||||
Ok(Instruction::StringLiftMemory)
|
||||
} else if lookahead.peek::<keyword::byte_array_lower_memory>() {
|
||||
parser.parse::<keyword::byte_array_lower_memory>()?;
|
||||
|
||||
Ok(Instruction::StringLowerMemory)
|
||||
} else if lookahead.peek::<keyword::byte_array_size>() {
|
||||
parser.parse::<keyword::byte_array_size>()?;
|
||||
|
||||
Ok(Instruction::StringSize)
|
||||
} else if lookahead.peek::<keyword::array_lift_memory>() {
|
||||
parser.parse::<keyword::array_lift_memory>()?;
|
||||
|
@ -235,6 +235,10 @@ where
|
||||
Instruction::StringLowerMemory => 0x23_u8.to_bytes(writer)?,
|
||||
Instruction::StringSize => 0x24_u8.to_bytes(writer)?,
|
||||
|
||||
Instruction::ByteArrayLiftMemory => 0x43_u8.to_bytes(writer)?,
|
||||
Instruction::ByteArrayLowerMemory => 0x44_u8.to_bytes(writer)?,
|
||||
Instruction::ByteArraySize => 0x45_u8.to_bytes(writer)?,
|
||||
|
||||
Instruction::ArrayLiftMemory { value_type } => {
|
||||
0x37_u8.to_bytes(writer)?;
|
||||
value_type.to_bytes(writer)?
|
||||
|
@ -102,6 +102,11 @@ impl ToString for &Instruction {
|
||||
Instruction::StringLiftMemory => "string.lift_memory".into(),
|
||||
Instruction::StringLowerMemory => "string.lower_memory".into(),
|
||||
Instruction::StringSize => "string.size".into(),
|
||||
|
||||
Instruction::ByteArrayLiftMemory => "byte_array.lift_memory".into(),
|
||||
Instruction::ByteArrayLowerMemory => "byte_array.lower_memory".into(),
|
||||
Instruction::ByteArraySize => "byte_array.size".into(),
|
||||
|
||||
Instruction::ArrayLiftMemory { value_type } => {
|
||||
format!("array.lift_memory {}", value_type.to_string())
|
||||
}
|
||||
|
@ -33,19 +33,19 @@ where
|
||||
use crate::interpreter::stack::Stackable;
|
||||
Box::new({
|
||||
move |runtime| -> _ {
|
||||
let inputs = runtime.stack.pop(2).ok_or_else(|| {
|
||||
let mut inputs = runtime.stack.pop(2).ok_or_else(|| {
|
||||
InstructionError::from_error_kind(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 },
|
||||
)
|
||||
})?;
|
||||
|
||||
let offset: usize = to_native::<i32>(&inputs[0], instruction.clone())?
|
||||
let offset: usize = to_native::<i32>(inputs.remove(0), instruction.clone())?
|
||||
.try_into()
|
||||
.map_err(|e| (e, "offset").into())
|
||||
.map_err(|k| InstructionError::from_error_kind(instruction.clone(), k))?;
|
||||
|
||||
let size: usize = to_native::<i32>(&inputs[1], instruction.clone())?
|
||||
let size: usize = to_native::<i32>(inputs.remove(0), instruction.clone())?
|
||||
.try_into()
|
||||
.map_err(|e| (e, "size").into())
|
||||
.map_err(|k| InstructionError::from_error_kind(instruction.clone(), k))?;
|
||||
|
@ -30,6 +30,7 @@ pub(crate) fn array_lift_memory_impl(
|
||||
IType::U16 => reader.read_u16_array(offset, elements_count)?,
|
||||
IType::U32 => reader.read_u32_array(offset, elements_count)?,
|
||||
IType::U64 => reader.read_u64_array(offset, elements_count)?,
|
||||
IType::U128 => reader.read_u128_array(offset, elements_count)?,
|
||||
IType::F32 => reader.read_f32_array(offset, elements_count)?,
|
||||
IType::F64 => reader.read_f64_array(offset, elements_count)?,
|
||||
IType::String => read_string_array(li_helper, offset, elements_count)?,
|
||||
|
@ -40,6 +40,7 @@ pub(crate) fn array_lower_memory_impl(
|
||||
IValue::U16(value) => seq_writer.write_array(value.to_le_bytes()),
|
||||
IValue::U32(value) => seq_writer.write_array(value.to_le_bytes()),
|
||||
IValue::U64(value) => seq_writer.write_array(value.to_le_bytes()),
|
||||
IValue::U128(value) => seq_writer.write_array(value.to_le_bytes()),
|
||||
IValue::I32(value) => seq_writer.write_array(value.to_le_bytes()),
|
||||
IValue::I64(value) => seq_writer.write_array(value.to_le_bytes()),
|
||||
IValue::F32(value) => seq_writer.write_array(value.to_le_bytes()),
|
||||
|
147
wasmer-it/src/interpreter/instructions/byte_arrays.rs
Normal file
147
wasmer-it/src/interpreter/instructions/byte_arrays.rs
Normal file
@ -0,0 +1,147 @@
|
||||
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!(
|
||||
byte_array_lift_memory(instruction: Instruction) -> _ {
|
||||
move |runtime| -> _ {
|
||||
let mut inputs = runtime.stack.pop(2).ok_or_else(|| {
|
||||
InstructionError::from_error_kind(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 2 },
|
||||
)
|
||||
})?;
|
||||
|
||||
let memory_index = 0;
|
||||
let memory = runtime
|
||||
.wasm_instance
|
||||
.memory(memory_index)
|
||||
.ok_or_else(|| {
|
||||
InstructionError::from_error_kind(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::MemoryIsMissing { memory_index },
|
||||
)
|
||||
})?;
|
||||
|
||||
let pointer: usize = to_native::<i32>(inputs.remove(0), instruction.clone())?
|
||||
.try_into()
|
||||
.map_err(|e| (e, "pointer").into())
|
||||
.map_err(|k| InstructionError::from_error_kind(instruction.clone(), k))?;
|
||||
let length: usize = to_native::<i32>(inputs.remove(0), instruction.clone())?
|
||||
.try_into()
|
||||
.map_err(|e| (e, "length").into())
|
||||
.map_err(|k| InstructionError::from_error_kind(instruction.clone(), k))?;
|
||||
let memory_view = memory.view();
|
||||
|
||||
if length == 0 {
|
||||
runtime.stack.push(IValue::String("".into()));
|
||||
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
if memory_view.len() < pointer + length {
|
||||
return instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::MemoryOutOfBoundsAccess {
|
||||
index: pointer + length,
|
||||
length: memory_view.len(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let data: Vec<u8> = (&memory_view[pointer..pointer + length])
|
||||
.iter()
|
||||
.map(Cell::get)
|
||||
.collect();
|
||||
|
||||
log::debug!("byte_array.lift_memory: pushing {:?} on the stack", data);
|
||||
runtime.stack.push(IValue::ByteArray(data));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
executable_instruction!(
|
||||
byte_array_lower_memory(instruction: Instruction) -> _ {
|
||||
move |runtime| -> _ {
|
||||
let mut inputs = runtime.stack.pop(2).ok_or_else(|| {
|
||||
InstructionError::from_error_kind(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 2 },
|
||||
)
|
||||
})?;
|
||||
|
||||
let array_pointer: usize = to_native::<i32>(inputs.remove(0), instruction.clone())?
|
||||
.try_into()
|
||||
.map_err(|e| (e, "pointer").into())
|
||||
.map_err(|k| InstructionError::from_error_kind(instruction.clone(), k))?;
|
||||
let array: Vec<u8> = to_native(inputs.remove(0), instruction.clone())?;
|
||||
let length: i32 = array.len().try_into().map_err(|_| {
|
||||
InstructionError::from_error_kind(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::NegativeValue { subject: "array_length" },
|
||||
)
|
||||
})?;
|
||||
|
||||
let instance = &mut runtime.wasm_instance;
|
||||
let memory_index = 0;
|
||||
let memory_view = instance
|
||||
.memory(memory_index)
|
||||
.ok_or_else(|| {
|
||||
InstructionError::from_error_kind(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::MemoryIsMissing { memory_index },
|
||||
)
|
||||
})?
|
||||
.view();
|
||||
|
||||
for (nth, byte) in array.iter().enumerate() {
|
||||
memory_view[array_pointer as usize + nth].set(*byte);
|
||||
}
|
||||
|
||||
log::debug!("string.lower_memory: pushing {}, {} on the stack", array_pointer, length);
|
||||
runtime.stack.push(IValue::I32(array_pointer as i32));
|
||||
runtime.stack.push(IValue::I32(length));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
executable_instruction!(
|
||||
byte_array_size(instruction: Instruction) -> _ {
|
||||
move |runtime| -> _ {
|
||||
match runtime.stack.pop1() {
|
||||
Some(IValue::ByteArray(array)) => {
|
||||
let length = array.len() as i32;
|
||||
|
||||
log::debug!("byte_array.size: pushing {} on the stack", length);
|
||||
runtime.stack.push(IValue::I32(length));
|
||||
|
||||
Ok(())
|
||||
},
|
||||
|
||||
Some(value) => instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::InvalidValueOnTheStack {
|
||||
expected_type: IType::String,
|
||||
received_value: (&value).clone(),
|
||||
}
|
||||
),
|
||||
|
||||
None => instr_error!(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 }
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
@ -1,5 +1,6 @@
|
||||
mod argument_get;
|
||||
mod arrays;
|
||||
mod byte_arrays;
|
||||
mod call_core;
|
||||
mod dup;
|
||||
pub(self) mod lilo;
|
||||
@ -19,6 +20,7 @@ use crate::NEVec;
|
||||
|
||||
pub(crate) use argument_get::argument_get;
|
||||
pub(crate) use arrays::*;
|
||||
pub(crate) use byte_arrays::*;
|
||||
pub(crate) use call_core::call_core;
|
||||
pub(crate) use dup::dup;
|
||||
pub(crate) use numbers::*;
|
||||
@ -158,6 +160,15 @@ pub enum Instruction {
|
||||
/// The `string.lower_memory` instruction.
|
||||
StringLowerMemory,
|
||||
|
||||
/// The `byte_array.size` instruction.
|
||||
ByteArraySize,
|
||||
|
||||
/// The `byte_array.lift_memory` instruction.
|
||||
ByteArrayLiftMemory,
|
||||
|
||||
/// The `byte_array.lower_memory` instruction.
|
||||
ByteArrayLowerMemory,
|
||||
|
||||
/// The `string.size` instruction.
|
||||
StringSize,
|
||||
|
||||
@ -206,12 +217,9 @@ pub enum Instruction {
|
||||
|
||||
/// Just a short helper to map the error of a cast from an
|
||||
/// `IValue` to a native value.
|
||||
pub(crate) fn to_native<'a, T>(
|
||||
wit_value: &'a IValue,
|
||||
instruction: Instruction,
|
||||
) -> InstructionResult<T>
|
||||
pub(crate) fn to_native<'a, T>(wit_value: IValue, instruction: Instruction) -> InstructionResult<T>
|
||||
where
|
||||
T: NativeType + TryFrom<&'a IValue, Error = WasmValueNativeCastError>,
|
||||
T: NativeType + TryFrom<IValue, Error = WasmValueNativeCastError>,
|
||||
{
|
||||
T::try_from(wit_value).map_err(|error| {
|
||||
InstructionError::from_error_kind(instruction, InstructionErrorKind::ToNative(error))
|
||||
|
@ -32,14 +32,14 @@ where
|
||||
use crate::interpreter::stack::Stackable;
|
||||
Box::new({
|
||||
move |runtime| -> _ {
|
||||
let inputs = runtime.stack.pop(1).ok_or_else(|| {
|
||||
let mut inputs = runtime.stack.pop(1).ok_or_else(|| {
|
||||
InstructionError::from_error_kind(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 1 },
|
||||
)
|
||||
})?;
|
||||
|
||||
let offset: usize = to_native::<i32>(&inputs[0], instruction.clone())?
|
||||
let offset: usize = to_native::<i32>(inputs.remove(0), instruction.clone())?
|
||||
.try_into()
|
||||
.map_err(|e| (e, "offset").into())
|
||||
.map_err(|k| InstructionError::from_error_kind(instruction.clone(), k))?;
|
||||
|
@ -33,6 +33,7 @@ pub(crate) fn record_lift_memory_impl(
|
||||
IType::U16 => values.push(IValue::U16(seq_reader.read_u16())),
|
||||
IType::U32 => values.push(IValue::U32(seq_reader.read_u32())),
|
||||
IType::U64 => values.push(IValue::U64(seq_reader.read_u64())),
|
||||
IType::U128 => values.push(IValue::U128(seq_reader.read_u128())),
|
||||
IType::F32 => values.push(IValue::F32(seq_reader.read_f32())),
|
||||
IType::F64 => values.push(IValue::F64(seq_reader.read_f64())),
|
||||
IType::String => values.push(IValue::String(read_string(reader, &seq_reader)?)),
|
||||
|
@ -21,6 +21,7 @@ pub(crate) fn record_lower_memory_impl(
|
||||
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::U128(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()),
|
||||
|
@ -12,7 +12,7 @@ use std::{cell::Cell, convert::TryInto};
|
||||
executable_instruction!(
|
||||
string_lift_memory(instruction: Instruction) -> _ {
|
||||
move |runtime| -> _ {
|
||||
let inputs = runtime.stack.pop(2).ok_or_else(|| {
|
||||
let mut inputs = runtime.stack.pop(2).ok_or_else(|| {
|
||||
InstructionError::from_error_kind(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 2 },
|
||||
@ -30,11 +30,11 @@ executable_instruction!(
|
||||
)
|
||||
})?;
|
||||
|
||||
let pointer: usize = to_native::<i32>(&inputs[0], instruction.clone())?
|
||||
let pointer: usize = to_native::<i32>(inputs.remove(0), instruction.clone())?
|
||||
.try_into()
|
||||
.map_err(|e| (e, "pointer").into())
|
||||
.map_err(|k| InstructionError::from_error_kind(instruction.clone(), k))?;
|
||||
let length: usize = to_native::<i32>(&inputs[1], instruction.clone())?
|
||||
let length: usize = to_native::<i32>(inputs.remove(0), instruction.clone())?
|
||||
.try_into()
|
||||
.map_err(|e| (e, "length").into())
|
||||
.map_err(|k| InstructionError::from_error_kind(instruction.clone(), k))?;
|
||||
@ -75,18 +75,18 @@ executable_instruction!(
|
||||
executable_instruction!(
|
||||
string_lower_memory(instruction: Instruction) -> _ {
|
||||
move |runtime| -> _ {
|
||||
let inputs = runtime.stack.pop(2).ok_or_else(|| {
|
||||
let mut inputs = runtime.stack.pop(2).ok_or_else(|| {
|
||||
InstructionError::from_error_kind(
|
||||
instruction.clone(),
|
||||
InstructionErrorKind::StackIsTooSmall { needed: 2 },
|
||||
)
|
||||
})?;
|
||||
|
||||
let string_pointer: usize = to_native::<i32>(&inputs[0], instruction.clone())?
|
||||
let string_pointer: usize = to_native::<i32>(inputs.remove(0), instruction.clone())?
|
||||
.try_into()
|
||||
.map_err(|e| (e, "pointer").into())
|
||||
.map_err(|k| InstructionError::from_error_kind(instruction.clone(), k))?;
|
||||
let string: String = to_native(&inputs[1], instruction.clone())?;
|
||||
let string: String = to_native(inputs.remove(0), instruction.clone())?;
|
||||
let string_bytes = string.as_bytes();
|
||||
let string_length: i32 = string_bytes.len().try_into().map_err(|_| {
|
||||
InstructionError::from_error_kind(
|
||||
|
@ -239,6 +239,15 @@ where
|
||||
Instruction::StringLiftMemory => instructions::string_lift_memory(instruction),
|
||||
Instruction::StringLowerMemory => instructions::string_lower_memory(instruction),
|
||||
Instruction::StringSize => instructions::string_size(instruction),
|
||||
|
||||
Instruction::ByteArrayLiftMemory => {
|
||||
instructions::byte_array_lift_memory(instruction)
|
||||
}
|
||||
Instruction::ByteArrayLowerMemory => {
|
||||
instructions::byte_array_lower_memory(instruction)
|
||||
}
|
||||
Instruction::ByteArraySize => instructions::byte_array_size(instruction),
|
||||
|
||||
Instruction::ArrayLiftMemory { ref value_type } => {
|
||||
let value_type = value_type.clone();
|
||||
instructions::array_lift_memory(instruction, value_type)
|
||||
|
@ -215,6 +215,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||
Some(IValue::U16(_)) => self.deserialize_u16(visitor),
|
||||
Some(IValue::U32(_)) => self.deserialize_u32(visitor),
|
||||
Some(IValue::U64(_)) => self.deserialize_u64(visitor),
|
||||
Some(IValue::U128(_)) => self.deserialize_u64(visitor),
|
||||
Some(IValue::F32(_)) => self.deserialize_f32(visitor),
|
||||
Some(IValue::F64(_)) => self.deserialize_f64(visitor),
|
||||
Some(IValue::String(_)) => self.deserialize_string(visitor),
|
||||
|
Loading…
Reference in New Issue
Block a user