mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-25 02:12:13 +00:00
Merge #1327
1327: fix(interface-types) Stack pops items in the same order than Wasm invocation rule r=Hywan a=Hywan This PR fixes the items order when popped from the stack. It matches [the Wasm invocation rule](https://webassembly.github.io/spec/core/exec/instructions.html#invocation-of-function-address). Not that it is more performant in our case, since we use the `drain` API rather than `drain` + `rev`. Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
This commit is contained in:
commit
56aec04d1d
@ -70,8 +70,8 @@ mod tests {
|
||||
test_executable_instruction!(
|
||||
test_call_core =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::CallCore { function_index: 42 },
|
||||
],
|
||||
invocation_inputs: [
|
||||
@ -113,8 +113,8 @@ mod tests {
|
||||
test_executable_instruction!(
|
||||
test_call_core__invalid_types_in_the_stack =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::CallCore { function_index: 42 },
|
||||
],
|
||||
invocation_inputs: [
|
||||
@ -129,8 +129,8 @@ mod tests {
|
||||
test_executable_instruction!(
|
||||
test_call_core__failure_when_calling =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::CallCore { function_index: 42 },
|
||||
],
|
||||
invocation_inputs: [
|
||||
@ -160,8 +160,8 @@ mod tests {
|
||||
test_executable_instruction!(
|
||||
test_call_core__void =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::CallCore { function_index: 42 },
|
||||
],
|
||||
invocation_inputs: [
|
||||
|
@ -27,8 +27,8 @@ executable_instruction!(
|
||||
)
|
||||
})?;
|
||||
|
||||
let length = to_native::<i32>(&inputs[0], instruction)? as usize;
|
||||
let pointer = to_native::<i32>(&inputs[1], instruction)? as usize;
|
||||
let pointer = to_native::<i32>(&inputs[0], instruction)? as usize;
|
||||
let length = to_native::<i32>(&inputs[1], instruction)? as usize;
|
||||
let memory_view = memory.view();
|
||||
|
||||
if length == 0 {
|
||||
@ -67,15 +67,15 @@ mod tests {
|
||||
test_executable_instruction!(
|
||||
test_memory_to_string =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::MemoryToString,
|
||||
],
|
||||
invocation_inputs: [
|
||||
InterfaceValue::I32(13),
|
||||
// ^^^^^^^ length
|
||||
InterfaceValue::I32(0),
|
||||
// ^^^^^^ pointer
|
||||
InterfaceValue::I32(13),
|
||||
// ^^^^^^^ length
|
||||
],
|
||||
instance: Instance {
|
||||
memory: Memory::new("Hello, World!".as_bytes().iter().map(|u| Cell::new(*u)).collect()),
|
||||
@ -87,8 +87,8 @@ mod tests {
|
||||
test_executable_instruction!(
|
||||
test_memory_to_string__empty_string =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::MemoryToString,
|
||||
],
|
||||
invocation_inputs: [
|
||||
@ -105,15 +105,15 @@ mod tests {
|
||||
test_executable_instruction!(
|
||||
test_memory_to_string__read_out_of_memory =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::MemoryToString,
|
||||
],
|
||||
invocation_inputs: [
|
||||
InterfaceValue::I32(13),
|
||||
// ^^^^^^^ length is too long
|
||||
InterfaceValue::I32(0),
|
||||
// ^^^^^^ pointer
|
||||
InterfaceValue::I32(13),
|
||||
// ^^^^^^^ length is too long
|
||||
],
|
||||
instance: Instance {
|
||||
memory: Memory::new("Hello!".as_bytes().iter().map(|u| Cell::new(*u)).collect()),
|
||||
@ -125,15 +125,15 @@ mod tests {
|
||||
test_executable_instruction!(
|
||||
test_memory_to_string__invalid_encoding =
|
||||
instructions: [
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::ArgumentGet { index: 0 },
|
||||
Instruction::ArgumentGet { index: 1 },
|
||||
Instruction::MemoryToString,
|
||||
],
|
||||
invocation_inputs: [
|
||||
InterfaceValue::I32(4),
|
||||
// ^^^^^^ length is too long
|
||||
InterfaceValue::I32(0),
|
||||
// ^^^^^^ pointer
|
||||
InterfaceValue::I32(4),
|
||||
// ^^^^^^ length is too long
|
||||
],
|
||||
instance: Instance {
|
||||
memory: Memory::new(vec![0, 159, 146, 150].iter().map(|b| Cell::new(*b)).collect::<Vec<Cell<u8>>>()),
|
||||
@ -150,8 +150,8 @@ mod tests {
|
||||
// ^^^^^^^^^^^^^^ `memory-to-string` expects 2 values on the stack, only one is present.
|
||||
],
|
||||
invocation_inputs: [
|
||||
InterfaceValue::I32(13),
|
||||
InterfaceValue::I32(0),
|
||||
InterfaceValue::I32(13),
|
||||
],
|
||||
instance: Instance::new(),
|
||||
error: r#"`memory-to-string` needed to read `2` value(s) from the stack, but it doesn't contain enough data"#,
|
||||
|
@ -22,8 +22,8 @@ pub trait Stackable {
|
||||
|
||||
/// Removes `n` elements from the end of the stack, `None` if the
|
||||
/// stack doesn't contain enough elements.
|
||||
/// Returned items are ordered by FIFO: the last element comes
|
||||
/// first in the list.
|
||||
/// Returned items are in reverse order: the last element comes
|
||||
/// last in the list.
|
||||
fn pop(&mut self, n: usize) -> Option<Vec<Self::Item>>;
|
||||
}
|
||||
|
||||
@ -78,7 +78,6 @@ where
|
||||
let items = self
|
||||
.inner
|
||||
.drain(self.inner.len() - n..)
|
||||
.rev()
|
||||
.collect::<Vec<Self::Item>>();
|
||||
|
||||
assert!(items.len() == n);
|
||||
@ -121,9 +120,9 @@ mod tests {
|
||||
stack.push(6);
|
||||
|
||||
assert_eq!(stack.pop(1), Some(vec![6]));
|
||||
assert_eq!(stack.pop(2), Some(vec![5, 4]));
|
||||
assert_eq!(stack.pop(2), Some(vec![4, 5]));
|
||||
assert_eq!(stack.pop(4), None); // not enough items
|
||||
assert_eq!(stack.pop(3), Some(vec![3, 2, 1]));
|
||||
assert_eq!(stack.pop(3), Some(vec![1, 2, 3]));
|
||||
assert_eq!(stack.pop1(), None);
|
||||
assert_eq!(stack.is_empty(), true);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user