mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Fix a bug in our model of the Wasm VM stack
This commit is contained in:
parent
86403b4a2f
commit
7f633c107f
4 changed files with 15 additions and 9 deletions
|
@ -202,10 +202,10 @@ impl<'a> CodeBuilder<'a> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_insertion(&mut self, insert_at: usize, opcode: u8, immediate: u32) {
|
fn add_insertion(&mut self, insert_at: usize, opcode: OpCode, immediate: u32) {
|
||||||
let start = self.insert_bytes.len();
|
let start = self.insert_bytes.len();
|
||||||
|
|
||||||
self.insert_bytes.push(opcode);
|
self.insert_bytes.push(opcode as u8);
|
||||||
self.insert_bytes.encode_u32(immediate);
|
self.insert_bytes.encode_u32(immediate);
|
||||||
|
|
||||||
self.insertions.push(Insertion {
|
self.insertions.push(Insertion {
|
||||||
|
@ -213,6 +213,8 @@ impl<'a> CodeBuilder<'a> {
|
||||||
start,
|
start,
|
||||||
end: self.insert_bytes.len(),
|
end: self.insert_bytes.len(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// println!("insert {:?} {} at byte offset {} ", opcode, immediate, insert_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a Symbol that is stored in the VM stack
|
/// Load a Symbol that is stored in the VM stack
|
||||||
|
@ -244,14 +246,14 @@ impl<'a> CodeBuilder<'a> {
|
||||||
// Symbol is not on top of the stack. Find it.
|
// Symbol is not on top of the stack. Find it.
|
||||||
if let Some(found_index) = self.vm_stack.iter().rposition(|&s| s == symbol) {
|
if let Some(found_index) = self.vm_stack.iter().rposition(|&s| s == symbol) {
|
||||||
// Insert a local.set where the value was created
|
// Insert a local.set where the value was created
|
||||||
self.add_insertion(pushed_at, SETLOCAL as u8, next_local_id.0);
|
self.add_insertion(pushed_at, SETLOCAL, next_local_id.0);
|
||||||
|
|
||||||
// Take the value out of the stack where local.set was inserted
|
// Take the value out of the stack where local.set was inserted
|
||||||
self.vm_stack.remove(found_index);
|
self.vm_stack.remove(found_index);
|
||||||
|
|
||||||
// Insert a local.get at the current position
|
// Insert a local.get at the current position
|
||||||
self.get_local(next_local_id);
|
self.get_local(next_local_id);
|
||||||
self.vm_stack.push(symbol);
|
self.set_top_symbol(symbol);
|
||||||
|
|
||||||
// This Symbol is no longer stored in the VM stack, but in a local
|
// This Symbol is no longer stored in the VM stack, but in a local
|
||||||
None
|
None
|
||||||
|
@ -267,11 +269,11 @@ impl<'a> CodeBuilder<'a> {
|
||||||
Popped { pushed_at } => {
|
Popped { pushed_at } => {
|
||||||
// This Symbol is being used for a second time
|
// This Symbol is being used for a second time
|
||||||
// Insert a local.tee where it was pushed, so we don't interfere with the first usage
|
// Insert a local.tee where it was pushed, so we don't interfere with the first usage
|
||||||
self.add_insertion(pushed_at, TEELOCAL as u8, next_local_id.0);
|
self.add_insertion(pushed_at, TEELOCAL, next_local_id.0);
|
||||||
|
|
||||||
// Insert a local.get at the current position
|
// Insert a local.get at the current position
|
||||||
self.get_local(next_local_id);
|
self.get_local(next_local_id);
|
||||||
self.vm_stack.push(symbol);
|
self.set_top_symbol(symbol);
|
||||||
|
|
||||||
// This symbol has been promoted to a Local
|
// This symbol has been promoted to a Local
|
||||||
// Tell the caller it no longer has a VirtualMachineSymbolState
|
// Tell the caller it no longer has a VirtualMachineSymbolState
|
||||||
|
@ -441,6 +443,8 @@ impl<'a> CodeBuilder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.code.push(opcode as u8);
|
self.code.push(opcode as u8);
|
||||||
|
|
||||||
|
// println!("{:10}\t{:?}", format!("{:?}", opcode), &self.vm_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inst_imm8(&mut self, opcode: OpCode, pops: usize, push: bool, immediate: u8) {
|
fn inst_imm8(&mut self, opcode: OpCode, pops: usize, push: bool, immediate: u8) {
|
||||||
|
@ -529,6 +533,8 @@ impl<'a> CodeBuilder<'a> {
|
||||||
}
|
}
|
||||||
self.code.push(CALL as u8);
|
self.code.push(CALL as u8);
|
||||||
|
|
||||||
|
// println!("CALL \t{:?}", &self.vm_stack);
|
||||||
|
|
||||||
// Write the index of the function to be called.
|
// Write the index of the function to be called.
|
||||||
// Also make a RelocationEntry so the linker can see that this byte offset relates to a function by name.
|
// Also make a RelocationEntry so the linker can see that this byte offset relates to a function by name.
|
||||||
// Here we initialise the offset to an index of self.code. After completing the function, we'll add
|
// Here we initialise the offset to an index of self.code. After completing the function, we'll add
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum OpCode {
|
pub enum OpCode {
|
||||||
UNREACHABLE = 0x00,
|
UNREACHABLE = 0x00,
|
||||||
NOP = 0x01,
|
NOP = 0x01,
|
||||||
|
|
|
@ -571,7 +571,7 @@ fn abs_min_int_overflow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||||
fn gen_if_fn() {
|
fn gen_if_fn() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
|
|
@ -127,7 +127,7 @@ pub fn helper_wasm<'a, T: Wasm32TestResult>(
|
||||||
let src_hash = hash_state.finish();
|
let src_hash = hash_state.finish();
|
||||||
|
|
||||||
// Filename contains a hash of the Roc test source code. Helpful when comparing across commits.
|
// Filename contains a hash of the Roc test source code. Helpful when comparing across commits.
|
||||||
let dir = "/tmp/roc/compiler/gen_wasm/output";
|
let dir = "/tmp/roc/gen_wasm";
|
||||||
std::fs::create_dir_all(dir).unwrap();
|
std::fs::create_dir_all(dir).unwrap();
|
||||||
let path = format!("{}/test-{:016x}.wasm", dir, src_hash);
|
let path = format!("{}/test-{:016x}.wasm", dir, src_hash);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue