Skip to content

Commit

Permalink
Convert exit to syscall instead of VM instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
maximecb committed Sep 5, 2024
1 parent 22422fb commit 9165d3f
Show file tree
Hide file tree
Showing 17 changed files with 91 additions and 72 deletions.
16 changes: 16 additions & 0 deletions api/syscalls.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,22 @@
"const_idx": 17,
"description": "Grow the heap to a new size given in bytes. This is similar to the `brk()` system call on POSIX systems. Note that the heap may be resized to a size larger than requested. The heap size is guaranteed to be a multiple of 8 bytes. If the requested size is smaller than the current heap size, this is a no-op. Returns the new heap size in bytes."
},
{
"name": "exit",
"args": [
[
"i8",
"status"
]
],
"returns": [
"void",
""
],
"permission": "default_allowed",
"const_idx": 11,
"description": "End program execution with the specified exit status."
},
{
"name": "thread_spawn",
"args": [
Expand Down
8 changes: 8 additions & 0 deletions doc/syscalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ u64 vm_grow_heap(u64 num_bytes)

Grow the heap to a new size given in bytes. This is similar to the `brk()` system call on POSIX systems. Note that the heap may be resized to a size larger than requested. The heap size is guaranteed to be a multiple of 8 bytes. If the requested size is smaller than the current heap size, this is a no-op. Returns the new heap size in bytes.

## exit

```
void exit(i8 status)
```

End program execution with the specified exit status.

## thread_spawn

```
Expand Down
2 changes: 1 addition & 1 deletion ncc/include/assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
asm () -> void { syscall print_endl; };\
asm ("assert(" #test_expr ")") -> void { syscall print_str; };\
asm () -> void { syscall print_endl; };\
asm () -> void { push -1; exit; };\
asm () -> void { push -1; syscall exit; };\
}
#else
#define assert(test_val) {}
Expand Down
3 changes: 2 additions & 1 deletion ncc/include/stdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ int abs(int n)
return n;
}

#undef exit
void exit(int status)
{
asm (status) -> void { exit; };
asm (status) -> void { syscall exit; };
}

// Convert long int to string
Expand Down
4 changes: 4 additions & 0 deletions ncc/include/uvm/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
// Grow the heap to a new size given in bytes. This is similar to the `brk()` system call on POSIX systems. Note that the heap may be resized to a size larger than requested. The heap size is guaranteed to be a multiple of 8 bytes. If the requested size is smaller than the current heap size, this is a no-op. Returns the new heap size in bytes.
#define vm_grow_heap(__num_bytes) asm (__num_bytes) -> u64 { syscall vm_grow_heap; }

// void exit(i8 status)
// End program execution with the specified exit status.
#define exit(__status) asm (__status) -> void { syscall exit; }

// u64 thread_spawn(void* fptr, void* arg)
// Spawn a new thread running the given function with the argument value `arg`.
#define thread_spawn(__fptr, __arg) asm (__fptr, __arg) -> u64 { syscall thread_spawn; }
Expand Down
4 changes: 2 additions & 2 deletions ncc/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,14 @@ impl Unit

out.push_str("# call the main function and then exit\n");
out.push_str("call main, 0;\n");
out.push_str("exit;\n");
out.push_str("ret;\n");
out.push_str("\n");
}
else
{
// If there is no main function, the unit should just exit (do nothing)
out.push_str("push 0;\n");
out.push_str("exit;\n");
out.push_str("ret;\n");
out.push_str("\n");
}

Expand Down
2 changes: 1 addition & 1 deletion vm/examples/empty.asm
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
push 0;
exit;
ret;
2 changes: 1 addition & 1 deletion vm/examples/factorial.asm
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ syscall print_i64;
syscall print_endl;

push 0;
exit;
ret;

#### fact(n) ####
FACT:
Expand Down
2 changes: 1 addition & 1 deletion vm/examples/fib.asm
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ syscall print_i64;
syscall print_endl;

push 0;
exit;
ret;

#
# u64 fib(u64 n)
Expand Down
2 changes: 1 addition & 1 deletion vm/examples/fizzbuzz.asm
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ push 101;
lt_i64; # l0 < COUNT
jnz LOOP;

exit;
ret;
2 changes: 1 addition & 1 deletion vm/examples/guess.asm
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ syscall print_i64;
syscall print_endl;

push 0;
exit;
ret;

#
# Read a positive integer from stdlin
Expand Down
2 changes: 1 addition & 1 deletion vm/examples/loop.asm
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ push MIPS_STR;
syscall print_str;
syscall print_endl;

exit;
ret;
2 changes: 1 addition & 1 deletion vm/examples/memcpy.asm
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ push FPS_STR;
syscall print_str;
syscall print_endl;

exit;
ret;
3 changes: 1 addition & 2 deletions vm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,6 @@ impl Assembler
}

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

_ => {
return input.parse_error(&format!("unknown instruction opcode \"{}\"", op_name))
Expand Down Expand Up @@ -1323,7 +1322,7 @@ mod tests
parse_ok(" FOO_BAR: jmp FOO_BAR; ");

// Callback label
parse_ok("CB: ret; push_p32 CB; exit;");
parse_ok("CB: ret; push_p32 CB; ret;");
}

#[test]
Expand Down
3 changes: 2 additions & 1 deletion vm/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub const PRINT_ENDL: u16 = 7;
pub const GETCHAR: u16 = 8;
pub const WINDOW_POLL_EVENT: u16 = 9;
pub const WINDOW_DRAW_FRAME: u16 = 10;
pub const EXIT: u16 = 11;
pub const VM_HEAP_SIZE: u16 = 14;
pub const MEMSET32: u16 = 16;
pub const VM_GROW_HEAP: u16 = 17;
Expand Down Expand Up @@ -54,7 +55,7 @@ pub const SYSCALL_DESCS: [Option<SysCallDesc>; SYSCALL_TBL_LEN] = [
Some(SysCallDesc { name: "getchar", const_idx: 8, argc: 0, has_ret: true }),
Some(SysCallDesc { name: "window_poll_event", const_idx: 9, argc: 1, has_ret: true }),
Some(SysCallDesc { name: "window_draw_frame", const_idx: 10, argc: 2, has_ret: false }),
None,
Some(SysCallDesc { name: "exit", const_idx: 11, argc: 1, has_ret: false }),
None,
None,
Some(SysCallDesc { name: "vm_heap_size", const_idx: 14, argc: 0, has_ret: true }),
Expand Down
7 changes: 7 additions & 0 deletions vm/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ pub fn get_syscall(const_idx: u16) -> HostFn
MEMSET32 => HostFn::Fn3_0(memset32),
MEMCPY => HostFn::Fn3_0(memcpy),
MEMCMP => HostFn::Fn3_1(memcmp),
EXIT => HostFn::Fn1_0(exit),

THREAD_SPAWN => HostFn::Fn2_1(thread_spawn),
THREAD_JOIN => HostFn::Fn1_1(thread_join),
Expand Down Expand Up @@ -224,6 +225,12 @@ fn memcmp(thread: &mut Thread, ptr_a: Value, ptr_b: Value, num_bytes: Value) ->
}
}

// End program execution
fn exit(thread: &mut Thread, val: Value)
{
unsafe { libc::exit(val.as_i32() & 0xFF) };
}

fn print_i64(thread: &mut Thread, v: Value)
{
let v = v.as_i64();
Expand Down
Loading

0 comments on commit 9165d3f

Please sign in to comment.