From 693b210638278daa4bfafb226fce35465e44d089 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 23 Mar 2020 14:32:26 +0100 Subject: [PATCH 1/2] fix(interface-types) Stack pops items in the same order than Wasm invocation rule. --- lib/interface-types/src/interpreter/stack.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/interface-types/src/interpreter/stack.rs b/lib/interface-types/src/interpreter/stack.rs index 7877da573..7d39b9f91 100644 --- a/lib/interface-types/src/interpreter/stack.rs +++ b/lib/interface-types/src/interpreter/stack.rs @@ -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>; } @@ -78,7 +78,6 @@ where let items = self .inner .drain(self.inner.len() - n..) - .rev() .collect::>(); 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); } From a1f0a556e58a5d77c798262d00825fb7f202f41b Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 23 Mar 2020 14:34:57 +0100 Subject: [PATCH 2/2] fix(interface-types) Use same stack order than Wasm invocation rule. --- .../src/interpreter/instructions/call_core.rs | 8 +++--- .../instructions/memory_to_string.rs | 26 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/interface-types/src/interpreter/instructions/call_core.rs b/lib/interface-types/src/interpreter/instructions/call_core.rs index 77486498f..5a3da2124 100644 --- a/lib/interface-types/src/interpreter/instructions/call_core.rs +++ b/lib/interface-types/src/interpreter/instructions/call_core.rs @@ -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: [ diff --git a/lib/interface-types/src/interpreter/instructions/memory_to_string.rs b/lib/interface-types/src/interpreter/instructions/memory_to_string.rs index e30b70ce0..8e9902ca1 100644 --- a/lib/interface-types/src/interpreter/instructions/memory_to_string.rs +++ b/lib/interface-types/src/interpreter/instructions/memory_to_string.rs @@ -27,8 +27,8 @@ executable_instruction!( ) })?; - let length = to_native::(&inputs[0], instruction)? as usize; - let pointer = to_native::(&inputs[1], instruction)? as usize; + let pointer = to_native::(&inputs[0], instruction)? as usize; + let length = to_native::(&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::>>()), @@ -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"#,