diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-07 23:07:57 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-08 02:07:18 -0500 |
| commit | e5f2fac8c5ae5a1b74335816836872c2e24904e6 (patch) | |
| tree | ed131049d39320967d8d18f65749c08ebb2f79a0 /compiler/builtins.cup | |
| parent | Mark bootstrap files as binary in `.gitattributes` (diff) | |
| download | cup-master.tar.xz cup-master.zip | |
Diffstat (limited to 'compiler/builtins.cup')
| -rw-r--r-- | compiler/builtins.cup | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/compiler/builtins.cup b/compiler/builtins.cup index 8aae3d9..bee24e0 100644 --- a/compiler/builtins.cup +++ b/compiler/builtins.cup @@ -18,7 +18,16 @@ fn builtin_create_syscall(name: char*, num_args: int) { // Defined in `parser.cup` fn constant_push(name: char*, val: int); +const MACOS_SYSCALL_OFFSET = 33554432; // 0x2000000; fn builtins_push_posix_constants() { + + // TODO: make this permanent? + if (OS_IS_MACOS) { + constant_push("SYS_execve", 59 + MACOS_SYSCALL_OFFSET); + } else { + constant_push("SYS_execve", 59); + } + constant_push("SYS_read", SYS_read); constant_push("SYS_write", SYS_write); constant_push("SYS_exit", SYS_exit); @@ -72,6 +81,14 @@ fn initialize_builtins() { vector_push(node.d.func.args, variable_new("val", type_new(TYPE_ANY), 0)); vector_push(all_builtins, node); + // The return value of fork() is weird on macOS, parent/child is returned in rdx + // and the child pid is returned in rax, so we'll make our own wrapper. + node = node_new(AST_BUILTIN); + node.etyp = type_new(TYPE_INT); + node.d.func.name = "fork"; + node.d.func.args = vector_new_sized(0); + vector_push(all_builtins, node); + builtin_create_syscall("syscall0", 0); builtin_create_syscall("syscall1", 1); builtin_create_syscall("syscall2", 2); @@ -155,4 +172,17 @@ fn generate_builtins() { emit_asm(" syscall\n"); emit_asm(" ret\n"); } + + emit_asm("func_fork:\n"); + emit_asm(" mov rdi, [rsp+8]\n"); + emit_asm(" mov rax, "); emit_num(SYS_fork); emit_asm("\n"); + emit_asm(" syscall\n"); + if (OS_IS_MACOS) { + // If rdx is 0, we are in the child, so set rax to 0 to match Linux + emit_asm(" cmp rdx, 0\n"); + emit_asm(" je .L1\n"); + emit_asm(" mov rax, 0\n"); + emit_asm(".L1:\n"); + } + emit_asm(" ret\n"); }
\ No newline at end of file |