Skip to content

Commit

Permalink
Add call_fp (call function pointer). Requested in #39.
Browse files Browse the repository at this point in the history
  • Loading branch information
maximecb committed Nov 27, 2023
1 parent 32be919 commit aef97d4
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
8 changes: 8 additions & 0 deletions vm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,7 @@ impl Assembler
self.code.push_u16(syscall_idx);
}

// Call label
"call" => {
let label_name = input.parse_ident()?;
input.expect_token(",")?;
Expand All @@ -1164,6 +1165,13 @@ impl Assembler
self.code.push_u8(argc);
}

// Call function pointer
"call_fp" => {
let argc: u8 = self.parse_int_arg(input)?;
self.code.push_op(Op::call_fp);
self.code.push_u8(argc);
}

"ret" => self.code.push_op(Op::ret),
"exit" => self.code.push_op(Op::exit),

Expand Down
32 changes: 29 additions & 3 deletions vm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ pub enum Op
call,

// Call a function pointer passed as argument
// call <num_args:u8> (f_ptr, arg0, arg1, ..., argN)
//call_fp,
// call <num_args:u8> (arg0, arg1, ..., argN, f_ptr)
call_fp,

// Call into a host function
// For example, to set up a device or to allocate more memory
Expand Down Expand Up @@ -1440,6 +1440,26 @@ impl VM
pc = ((pc as isize) + offset) as usize;
}

// call <num_args:u8> (arg0, arg1, ..., argN, f_ptr)
Op::call_fp => {
// Absolute address of the function to call
let fp = self.pop();

// Argument count
let num_args = self.code.read_pc::<u8>(&mut pc) as usize;
assert!(num_args <= self.stack.len() - bp);

self.frames.push(StackFrame {
prev_bp: bp,
ret_addr: pc,
argc: num_args,
});

// The base pointer will point at the first local
bp = self.stack.len();
pc = fp.as_usize();
}

Op::syscall => {
let syscall_idx = self.code.read_pc::<u16>(&mut pc);
let syscall_fn = self.sys_state.get_syscall(syscall_idx);
Expand Down Expand Up @@ -1593,7 +1613,7 @@ mod tests

// Keep track of how many short opcodes we have so far
dbg!(Op::exit as usize);
assert!(Op::exit as usize <= 112);
assert!(Op::exit as usize <= 113);
}

#[test]
Expand Down Expand Up @@ -1681,6 +1701,12 @@ mod tests
eval_i64("push 5; call foo, 0; pop; exit; foo: push 2; push 0; ret;", 5);
}

#[test]
fn test_call_fp()
{
eval_i64(" push FN; call_fp 0; exit; FN: push_i8 33; ret;", 33);
}

#[test]
fn test_syscalls()
{
Expand Down

0 comments on commit aef97d4

Please sign in to comment.