mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-28 16:11:32 +00:00
fix(interface-types) Remove allocator index from string.lower_memory
.
This commit is contained in:
@ -232,16 +232,7 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
|
|||||||
0x21 => (input, Instruction::I64FromU64),
|
0x21 => (input, Instruction::I64FromU64),
|
||||||
|
|
||||||
0x22 => (input, Instruction::StringLiftMemory),
|
0x22 => (input, Instruction::StringLiftMemory),
|
||||||
0x23 => {
|
0x23 => (input, Instruction::StringLowerMemory),
|
||||||
consume!((input, argument_0) = uleb(input)?);
|
|
||||||
|
|
||||||
(
|
|
||||||
input,
|
|
||||||
Instruction::StringLowerMemory {
|
|
||||||
allocator_index: argument_0 as u32,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
0x24 => (input, Instruction::StringSize),
|
0x24 => (input, Instruction::StringSize),
|
||||||
|
|
||||||
0x25 => {
|
0x25 => {
|
||||||
@ -764,7 +755,7 @@ mod tests {
|
|||||||
0x20, // I64FromU32
|
0x20, // I64FromU32
|
||||||
0x21, // I64FromU64
|
0x21, // I64FromU64
|
||||||
0x22, // StringLiftMemory
|
0x22, // StringLiftMemory
|
||||||
0x23, 0x01, // StringLowerMemory { allocator_index: 1 }
|
0x23, // StringLowerMemory
|
||||||
0x24, // StringSize
|
0x24, // StringSize
|
||||||
0x25, 0x01, // RecordLift { type_index: 1 },
|
0x25, 0x01, // RecordLift { type_index: 1 },
|
||||||
0x26, 0x01, // RecordLower { type_index: 1 },
|
0x26, 0x01, // RecordLower { type_index: 1 },
|
||||||
@ -808,7 +799,7 @@ mod tests {
|
|||||||
Instruction::I64FromU32,
|
Instruction::I64FromU32,
|
||||||
Instruction::I64FromU64,
|
Instruction::I64FromU64,
|
||||||
Instruction::StringLiftMemory,
|
Instruction::StringLiftMemory,
|
||||||
Instruction::StringLowerMemory { allocator_index: 1 },
|
Instruction::StringLowerMemory,
|
||||||
Instruction::StringSize,
|
Instruction::StringSize,
|
||||||
Instruction::RecordLift { type_index: 1 },
|
Instruction::RecordLift { type_index: 1 },
|
||||||
Instruction::RecordLower { type_index: 1 },
|
Instruction::RecordLower { type_index: 1 },
|
||||||
|
@ -309,9 +309,7 @@ impl<'a> Parse<'a> for Instruction {
|
|||||||
} else if lookahead.peek::<keyword::string_lower_memory>() {
|
} else if lookahead.peek::<keyword::string_lower_memory>() {
|
||||||
parser.parse::<keyword::string_lower_memory>()?;
|
parser.parse::<keyword::string_lower_memory>()?;
|
||||||
|
|
||||||
Ok(Instruction::StringLowerMemory {
|
Ok(Instruction::StringLowerMemory)
|
||||||
allocator_index: parser.parse()?,
|
|
||||||
})
|
|
||||||
} else if lookahead.peek::<keyword::string_size>() {
|
} else if lookahead.peek::<keyword::string_size>() {
|
||||||
parser.parse::<keyword::string_size>()?;
|
parser.parse::<keyword::string_size>()?;
|
||||||
|
|
||||||
@ -770,7 +768,7 @@ mod tests {
|
|||||||
"i64.from_u32",
|
"i64.from_u32",
|
||||||
"i64.from_u64",
|
"i64.from_u64",
|
||||||
"string.lift_memory",
|
"string.lift_memory",
|
||||||
"string.lower_memory 42",
|
"string.lower_memory",
|
||||||
"string.size",
|
"string.size",
|
||||||
"record.lift 42",
|
"record.lift 42",
|
||||||
"record.lower 42",
|
"record.lower 42",
|
||||||
@ -811,9 +809,7 @@ mod tests {
|
|||||||
Instruction::I64FromU32,
|
Instruction::I64FromU32,
|
||||||
Instruction::I64FromU64,
|
Instruction::I64FromU64,
|
||||||
Instruction::StringLiftMemory,
|
Instruction::StringLiftMemory,
|
||||||
Instruction::StringLowerMemory {
|
Instruction::StringLowerMemory,
|
||||||
allocator_index: 42,
|
|
||||||
},
|
|
||||||
Instruction::StringSize,
|
Instruction::StringSize,
|
||||||
Instruction::RecordLift { type_index: 42 },
|
Instruction::RecordLift { type_index: 42 },
|
||||||
Instruction::RecordLower { type_index: 42 },
|
Instruction::RecordLower { type_index: 42 },
|
||||||
|
@ -331,10 +331,7 @@ where
|
|||||||
Instruction::I64FromU64 => 0x21_u8.to_bytes(writer)?,
|
Instruction::I64FromU64 => 0x21_u8.to_bytes(writer)?,
|
||||||
|
|
||||||
Instruction::StringLiftMemory => 0x22_u8.to_bytes(writer)?,
|
Instruction::StringLiftMemory => 0x22_u8.to_bytes(writer)?,
|
||||||
Instruction::StringLowerMemory { allocator_index } => {
|
Instruction::StringLowerMemory => 0x23_u8.to_bytes(writer)?,
|
||||||
0x23_u8.to_bytes(writer)?;
|
|
||||||
(*allocator_index as u64).to_bytes(writer)?;
|
|
||||||
}
|
|
||||||
Instruction::StringSize => 0x24_u8.to_bytes(writer)?,
|
Instruction::StringSize => 0x24_u8.to_bytes(writer)?,
|
||||||
|
|
||||||
Instruction::RecordLift { type_index } => {
|
Instruction::RecordLift { type_index } => {
|
||||||
@ -688,7 +685,7 @@ mod tests {
|
|||||||
Instruction::I64FromU32,
|
Instruction::I64FromU32,
|
||||||
Instruction::I64FromU64,
|
Instruction::I64FromU64,
|
||||||
Instruction::StringLiftMemory,
|
Instruction::StringLiftMemory,
|
||||||
Instruction::StringLowerMemory { allocator_index: 1 },
|
Instruction::StringLowerMemory,
|
||||||
Instruction::StringSize,
|
Instruction::StringSize,
|
||||||
Instruction::RecordLift { type_index: 1 },
|
Instruction::RecordLift { type_index: 1 },
|
||||||
Instruction::RecordLower { type_index: 1 },
|
Instruction::RecordLower { type_index: 1 },
|
||||||
@ -730,7 +727,7 @@ mod tests {
|
|||||||
0x20, // I64FromU32
|
0x20, // I64FromU32
|
||||||
0x21, // I64FromU64
|
0x21, // I64FromU64
|
||||||
0x22, // StringLiftMemory
|
0x22, // StringLiftMemory
|
||||||
0x23, 0x01, // StringLowerMemory { allocator_index: 1 }
|
0x23, // StringLowerMemory
|
||||||
0x24, // StringSize
|
0x24, // StringSize
|
||||||
0x025, 0x01, // RecordLift { type_index: 1 }
|
0x025, 0x01, // RecordLift { type_index: 1 }
|
||||||
0x026, 0x01, // RecordLower { type_index: 1 }
|
0x026, 0x01, // RecordLower { type_index: 1 }
|
||||||
|
@ -135,9 +135,7 @@ impl ToString for &Instruction {
|
|||||||
Instruction::I64FromU32 => "i64.from_u32".into(),
|
Instruction::I64FromU32 => "i64.from_u32".into(),
|
||||||
Instruction::I64FromU64 => "i64.from_u64".into(),
|
Instruction::I64FromU64 => "i64.from_u64".into(),
|
||||||
Instruction::StringLiftMemory => "string.lift_memory".into(),
|
Instruction::StringLiftMemory => "string.lift_memory".into(),
|
||||||
Instruction::StringLowerMemory { allocator_index } => {
|
Instruction::StringLowerMemory => "string.lower_memory".into(),
|
||||||
format!("string.lower_memory {}", allocator_index)
|
|
||||||
}
|
|
||||||
Instruction::StringSize => "string.size".into(),
|
Instruction::StringSize => "string.size".into(),
|
||||||
Instruction::RecordLift { type_index } => format!("record.lift {}", type_index),
|
Instruction::RecordLift { type_index } => format!("record.lift {}", type_index),
|
||||||
Instruction::RecordLower { type_index } => format!("record.lower {}", type_index),
|
Instruction::RecordLower { type_index } => format!("record.lower {}", type_index),
|
||||||
@ -462,10 +460,7 @@ mod tests {
|
|||||||
(&Instruction::I64FromU32).to_string(),
|
(&Instruction::I64FromU32).to_string(),
|
||||||
(&Instruction::I64FromU64).to_string(),
|
(&Instruction::I64FromU64).to_string(),
|
||||||
(&Instruction::StringLiftMemory).to_string(),
|
(&Instruction::StringLiftMemory).to_string(),
|
||||||
(&Instruction::StringLowerMemory {
|
(&Instruction::StringLowerMemory).to_string(),
|
||||||
allocator_index: 42,
|
|
||||||
})
|
|
||||||
.to_string(),
|
|
||||||
(&Instruction::StringSize).to_string(),
|
(&Instruction::StringSize).to_string(),
|
||||||
(&Instruction::RecordLift { type_index: 42 }).to_string(),
|
(&Instruction::RecordLift { type_index: 42 }).to_string(),
|
||||||
(&Instruction::RecordLower { type_index: 42 }).to_string(),
|
(&Instruction::RecordLower { type_index: 42 }).to_string(),
|
||||||
@ -506,7 +501,7 @@ mod tests {
|
|||||||
"i64.from_u32",
|
"i64.from_u32",
|
||||||
"i64.from_u64",
|
"i64.from_u64",
|
||||||
"string.lift_memory",
|
"string.lift_memory",
|
||||||
"string.lower_memory 42",
|
"string.lower_memory",
|
||||||
"string.size",
|
"string.size",
|
||||||
"record.lift 42",
|
"record.lift 42",
|
||||||
"record.lower 42",
|
"record.lower 42",
|
||||||
|
@ -130,10 +130,7 @@ pub enum Instruction {
|
|||||||
StringLiftMemory,
|
StringLiftMemory,
|
||||||
|
|
||||||
/// The `string.lower_memory` instruction.
|
/// The `string.lower_memory` instruction.
|
||||||
StringLowerMemory {
|
StringLowerMemory,
|
||||||
/// The allocator function index.
|
|
||||||
allocator_index: u32,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// The `string.size` instruction.
|
/// The `string.size` instruction.
|
||||||
StringSize,
|
StringSize,
|
||||||
|
@ -2,13 +2,7 @@ use super::to_native;
|
|||||||
use crate::{
|
use crate::{
|
||||||
ast::InterfaceType,
|
ast::InterfaceType,
|
||||||
errors::{InstructionError, InstructionErrorKind},
|
errors::{InstructionError, InstructionErrorKind},
|
||||||
interpreter::{
|
interpreter::{wasm::values::InterfaceValue, Instruction},
|
||||||
wasm::{
|
|
||||||
structures::{FunctionIndex, TypedIndex},
|
|
||||||
values::InterfaceValue,
|
|
||||||
},
|
|
||||||
Instruction,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use std::{cell::Cell, convert::TryInto};
|
use std::{cell::Cell, convert::TryInto};
|
||||||
|
|
||||||
@ -75,37 +69,16 @@ executable_instruction!(
|
|||||||
);
|
);
|
||||||
|
|
||||||
executable_instruction!(
|
executable_instruction!(
|
||||||
string_lower_memory(allocator_index: u32, instruction: Instruction) -> _ {
|
string_lower_memory(instruction: Instruction) -> _ {
|
||||||
move |runtime| -> _ {
|
move |runtime| -> _ {
|
||||||
let instance = &mut runtime.wasm_instance;
|
let inputs = runtime.stack.pop(2).ok_or_else(|| {
|
||||||
let index = FunctionIndex::new(allocator_index as usize);
|
|
||||||
|
|
||||||
let allocator = instance.local_or_import(index).ok_or_else(|| {
|
|
||||||
InstructionError::new(
|
InstructionError::new(
|
||||||
instruction,
|
instruction,
|
||||||
InstructionErrorKind::LocalOrImportIsMissing { function_index: allocator_index },
|
InstructionErrorKind::StackIsTooSmall { needed: 2 },
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if allocator.inputs() != [InterfaceType::I32] || allocator.outputs() != [InterfaceType::I32] {
|
let string: String = to_native(&inputs[0], instruction)?;
|
||||||
return Err(InstructionError::new(
|
|
||||||
instruction,
|
|
||||||
InstructionErrorKind::LocalOrImportSignatureMismatch {
|
|
||||||
function_index: allocator_index,
|
|
||||||
expected: (vec![InterfaceType::I32], vec![InterfaceType::I32]),
|
|
||||||
received: (allocator.inputs().to_vec(), allocator.outputs().to_vec()),
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
let string = runtime.stack.pop1().ok_or_else(|| {
|
|
||||||
InstructionError::new(
|
|
||||||
instruction,
|
|
||||||
InstructionErrorKind::StackIsTooSmall { needed: 1 },
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let string: String = to_native(&string, instruction)?;
|
|
||||||
let string_bytes = string.as_bytes();
|
let string_bytes = string.as_bytes();
|
||||||
let string_length: i32 = string_bytes.len().try_into().map_err(|_| {
|
let string_length: i32 = string_bytes.len().try_into().map_err(|_| {
|
||||||
InstructionError::new(
|
InstructionError::new(
|
||||||
@ -113,20 +86,12 @@ executable_instruction!(
|
|||||||
InstructionErrorKind::NegativeValue { subject: "string_length" },
|
InstructionErrorKind::NegativeValue { subject: "string_length" },
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
let string_pointer: usize = to_native::<i32>(&inputs[1], instruction)?
|
||||||
|
.try_into()
|
||||||
|
.map_err(|e| (e, "pointer").into())
|
||||||
|
.map_err(|k| InstructionError::new(instruction, k))?;
|
||||||
|
|
||||||
let outputs = allocator.call(&[InterfaceValue::I32(string_length)]).map_err(|_| {
|
let instance = &mut runtime.wasm_instance;
|
||||||
InstructionError::new(
|
|
||||||
instruction,
|
|
||||||
InstructionErrorKind::LocalOrImportCall { function_index: allocator_index },
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
let string_pointer: u32 = to_native::<i32>(&outputs[0], instruction)?.try_into().map_err(|_| {
|
|
||||||
InstructionError::new(
|
|
||||||
instruction,
|
|
||||||
InstructionErrorKind::NegativeValue { subject: "string_pointer" },
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let memory_index: u32 = 0;
|
let memory_index: u32 = 0;
|
||||||
let memory_view = instance
|
let memory_view = instance
|
||||||
.memory(memory_index as usize)
|
.memory(memory_index as usize)
|
||||||
@ -313,7 +278,10 @@ mod tests {
|
|||||||
test_string_lower_memory =
|
test_string_lower_memory =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::StringLowerMemory { allocator_index: 43 },
|
Instruction::StringSize,
|
||||||
|
Instruction::CallCore { function_index: 43 },
|
||||||
|
Instruction::StringLowerMemory,
|
||||||
|
|
||||||
],
|
],
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||||
instance: Instance::new(),
|
instance: Instance::new(),
|
||||||
@ -329,7 +297,9 @@ mod tests {
|
|||||||
test_string__roundtrip =
|
test_string__roundtrip =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::ArgumentGet { index: 0 },
|
Instruction::ArgumentGet { index: 0 },
|
||||||
Instruction::StringLowerMemory { allocator_index: 43 },
|
Instruction::StringSize,
|
||||||
|
Instruction::CallCore { function_index: 43 },
|
||||||
|
Instruction::StringLowerMemory,
|
||||||
Instruction::StringLiftMemory,
|
Instruction::StringLiftMemory,
|
||||||
],
|
],
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
||||||
@ -337,70 +307,14 @@ mod tests {
|
|||||||
stack: [InterfaceValue::String("Hello, World!".into())],
|
stack: [InterfaceValue::String("Hello, World!".into())],
|
||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_string_lower_memory__allocator_does_not_exist =
|
|
||||||
instructions: [Instruction::StringLowerMemory { allocator_index: 43 }],
|
|
||||||
invocation_inputs: [],
|
|
||||||
instance: Instance { ..Default::default() },
|
|
||||||
error: r#"`string.lower_memory 43` the local or import function `43` doesn't exist"#,
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
test_string_lower_memory__stack_is_too_small =
|
test_string_lower_memory__stack_is_too_small =
|
||||||
instructions: [
|
instructions: [
|
||||||
Instruction::StringLowerMemory { allocator_index: 43 }
|
Instruction::StringLowerMemory,
|
||||||
// ^^ `43` expects 1 value on the stack, none is present
|
|
||||||
],
|
],
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
invocation_inputs: [],
|
||||||
instance: Instance::new(),
|
instance: Instance::new(),
|
||||||
error: r#"`string.lower_memory 43` needed to read `1` value(s) from the stack, but it doesn't contain enough data"#,
|
error: r#"`string.lower_memory` needed to read `2` value(s) from the stack, but it doesn't contain enough data"#,
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_string_lower_memory__failure_when_calling_the_allocator =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::StringLowerMemory { allocator_index: 153 }
|
|
||||||
],
|
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
|
||||||
instance: {
|
|
||||||
let mut instance = Instance::new();
|
|
||||||
instance.locals_or_imports.insert(
|
|
||||||
153,
|
|
||||||
LocalImport {
|
|
||||||
inputs: vec![InterfaceType::I32],
|
|
||||||
outputs: vec![InterfaceType::I32],
|
|
||||||
function: |_| Err(()),
|
|
||||||
// ^^^^^^^ function fails
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
instance
|
|
||||||
},
|
|
||||||
error: r#"`string.lower_memory 153` failed while calling the local or import function `153`"#,
|
|
||||||
);
|
|
||||||
|
|
||||||
test_executable_instruction!(
|
|
||||||
test_string_lower_memory__invalid_allocator_signature =
|
|
||||||
instructions: [
|
|
||||||
Instruction::ArgumentGet { index: 0 },
|
|
||||||
Instruction::StringLowerMemory { allocator_index: 153 }
|
|
||||||
],
|
|
||||||
invocation_inputs: [InterfaceValue::String("Hello, World!".into())],
|
|
||||||
instance: {
|
|
||||||
let mut instance = Instance::new();
|
|
||||||
instance.locals_or_imports.insert(
|
|
||||||
153,
|
|
||||||
LocalImport {
|
|
||||||
inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
|
||||||
outputs: vec![],
|
|
||||||
function: |_| Err(()),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
instance
|
|
||||||
},
|
|
||||||
error: r#"`string.lower_memory 153` the local or import function `153` has the signature `[I32] -> [I32]` but it received values of kind `[I32, I32] -> []`"#,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
test_executable_instruction!(
|
test_executable_instruction!(
|
||||||
|
@ -230,9 +230,7 @@ where
|
|||||||
Instruction::I64FromU64 => instructions::i64_from_u64(*instruction),
|
Instruction::I64FromU64 => instructions::i64_from_u64(*instruction),
|
||||||
|
|
||||||
Instruction::StringLiftMemory => instructions::string_lift_memory(*instruction),
|
Instruction::StringLiftMemory => instructions::string_lift_memory(*instruction),
|
||||||
Instruction::StringLowerMemory { allocator_index } => {
|
Instruction::StringLowerMemory => instructions::string_lower_memory(*instruction),
|
||||||
instructions::string_lower_memory(*allocator_index, *instruction)
|
|
||||||
}
|
|
||||||
Instruction::StringSize => instructions::string_size(*instruction),
|
Instruction::StringSize => instructions::string_size(*instruction),
|
||||||
|
|
||||||
Instruction::RecordLift { type_index } => {
|
Instruction::RecordLift { type_index } => {
|
||||||
|
Reference in New Issue
Block a user