diff --git a/crates/cli/tests/fixtures/multi-dep-str/platform/host.zig b/crates/cli/tests/fixtures/multi-dep-str/platform/host.zig index d1e0e912fa..eaed7abb87 100644 --- a/crates/cli/tests/fixtures/multi-dep-str/platform/host.zig +++ b/crates/cli/tests/fixtures/multi-dep-str/platform/host.zig @@ -65,6 +65,34 @@ export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void { std.process.exit(0); } +extern fn kill(pid: c_int, sig: c_int) c_int; +extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; +extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; +extern fn getppid() c_int; + +fn roc_getppid() callconv(.C) c_int { + return getppid(); +} + +fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int { + return kill(pid, sig); +} +fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int { + return shm_open(name, oflag, mode); +} +fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque { + return mmap(addr, length, prot, flags, fd, offset); +} + +comptime { + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + @export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong }); + @export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong }); + @export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong }); + @export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong }); + } +} + const Unit = extern struct {}; pub export fn main() i32 { diff --git a/crates/cli/tests/fixtures/multi-dep-thunk/platform/host.zig b/crates/cli/tests/fixtures/multi-dep-thunk/platform/host.zig index 1bf51a90e9..935f24ea62 100644 --- a/crates/cli/tests/fixtures/multi-dep-thunk/platform/host.zig +++ b/crates/cli/tests/fixtures/multi-dep-thunk/platform/host.zig @@ -64,6 +64,34 @@ export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void { std.process.exit(0); } +extern fn kill(pid: c_int, sig: c_int) c_int; +extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; +extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; +extern fn getppid() c_int; + +fn roc_getppid() callconv(.C) c_int { + return getppid(); +} + +fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int { + return kill(pid, sig); +} +fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int { + return shm_open(name, oflag, mode); +} +fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque { + return mmap(addr, length, prot, flags, fd, offset); +} + +comptime { + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + @export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong }); + @export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong }); + @export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong }); + @export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong }); + } +} + const Unit = extern struct {}; pub export fn main() i32 { diff --git a/crates/cli_testing_examples/algorithms/fibonacci-platform/host.zig b/crates/cli_testing_examples/algorithms/fibonacci-platform/host.zig index 55f55e2658..004663313b 100644 --- a/crates/cli_testing_examples/algorithms/fibonacci-platform/host.zig +++ b/crates/cli_testing_examples/algorithms/fibonacci-platform/host.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const testing = std.testing; const expectEqual = testing.expectEqual; const expect = testing.expect; @@ -13,7 +14,6 @@ comptime { // -fcompiler-rt in link.rs instead of doing this. Note that this // workaround is present in many host.zig files, so make sure to undo // it everywhere! - const builtin = @import("builtin"); if (builtin.os.tag == .macos) { _ = @import("compiler_rt"); } @@ -81,6 +81,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { return memset(dst, value, size); } +extern fn kill(pid: c_int, sig: c_int) c_int; +extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; +extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; +extern fn getppid() c_int; + +fn roc_getppid() callconv(.C) c_int { + return getppid(); +} + +fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int { + return kill(pid, sig); +} +fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int { + return shm_open(name, oflag, mode); +} +fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque { + return mmap(addr, length, prot, flags, fd, offset); +} + +comptime { + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + @export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong }); + @export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong }); + @export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong }); + @export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong }); + } +} + pub export fn main() u8 { const stdout = std.io.getStdOut().writer(); const stderr = std.io.getStdErr().writer(); diff --git a/crates/cli_testing_examples/algorithms/quicksort-platform/host.zig b/crates/cli_testing_examples/algorithms/quicksort-platform/host.zig index c2e70f3d31..3047ed327e 100644 --- a/crates/cli_testing_examples/algorithms/quicksort-platform/host.zig +++ b/crates/cli_testing_examples/algorithms/quicksort-platform/host.zig @@ -80,6 +80,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { return memset(dst, value, size); } +extern fn kill(pid: c_int, sig: c_int) c_int; +extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; +extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; +extern fn getppid() c_int; + +fn roc_getppid() callconv(.C) c_int { + return getppid(); +} + +fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int { + return kill(pid, sig); +} +fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int { + return shm_open(name, oflag, mode); +} +fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque { + return mmap(addr, length, prot, flags, fd, offset); +} + +comptime { + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + @export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong }); + @export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong }); + @export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong }); + @export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong }); + } +} + // warning! the array is currently stack-allocated so don't make this too big const NUM_NUMS = 100; diff --git a/crates/cli_testing_examples/benchmarks/platform/host.zig b/crates/cli_testing_examples/benchmarks/platform/host.zig index 209ea9e06b..d8010a3de1 100644 --- a/crates/cli_testing_examples/benchmarks/platform/host.zig +++ b/crates/cli_testing_examples/benchmarks/platform/host.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const str = @import("str"); const RocStr = str.RocStr; const testing = std.testing; @@ -15,7 +16,6 @@ comptime { // -fcompiler-rt in link.rs instead of doing this. Note that this // workaround is present in many host.zig files, so make sure to undo // it everywhere! - const builtin = @import("builtin"); if (builtin.os.tag == .macos) { _ = @import("compiler_rt"); } @@ -85,6 +85,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { return memset(dst, value, size); } +extern fn kill(pid: c_int, sig: c_int) c_int; +extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; +extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; +extern fn getppid() c_int; + +fn roc_getppid() callconv(.C) c_int { + return getppid(); +} + +fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int { + return kill(pid, sig); +} +fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int { + return shm_open(name, oflag, mode); +} +fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque { + return mmap(addr, length, prot, flags, fd, offset); +} + +comptime { + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + @export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong }); + @export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong }); + @export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong }); + @export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong }); + } +} + const Unit = extern struct {}; pub fn main() !u8 { diff --git a/crates/cli_testing_examples/platform-switching/c-platform/host.c b/crates/cli_testing_examples/platform-switching/c-platform/host.c index 3f9a63c2a2..553af25c4c 100644 --- a/crates/cli_testing_examples/platform-switching/c-platform/host.c +++ b/crates/cli_testing_examples/platform-switching/c-platform/host.c @@ -27,6 +27,12 @@ void* roc_memcpy(void* dest, const void* src, size_t n) { void* roc_memset(void* str, int c, size_t n) { return memset(str, c, n); } + +int roc_send_signal(int pid, int sig) { return kill(pid, sig); } +int roc_shm_open(char* name, int oflag, int mode) { return shm_open(name, oflag, mode); } +void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) { return mmap(addr, length, prot, flags, fd, offset); } +int roc_getppid() { return getppid(); } + struct RocStr { char* bytes; size_t len; diff --git a/crates/cli_testing_examples/platform-switching/rust-platform/src/lib.rs b/crates/cli_testing_examples/platform-switching/rust-platform/src/lib.rs index 303f5fb6f1..ce2bf4fc0a 100644 --- a/crates/cli_testing_examples/platform-switching/rust-platform/src/lib.rs +++ b/crates/cli_testing_examples/platform-switching/rust-platform/src/lib.rs @@ -54,6 +54,41 @@ pub unsafe extern "C" fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut libc::memset(dst, c, n) } +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_getppid() -> libc::pid_t { + libc::getppid() +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_mmap( + addr: *mut libc::c_void, + len: libc::size_t, + prot: libc::c_int, + flags: libc::c_int, + fd: libc::c_int, + offset: libc::off_t, +) -> *mut libc::c_void { + libc::mmap(addr, len, prot, flags, fd, offset) +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_shm_open( + name: *const libc::c_char, + oflag: libc::c_int, + mode: libc::mode_t, +) -> libc::c_int { + libc::shm_open(name, oflag, mode) +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int { + libc::kill(pid, sig) +} + #[no_mangle] pub extern "C" fn rust_main() -> i32 { unsafe { diff --git a/crates/cli_testing_examples/platform-switching/zig-platform/host.zig b/crates/cli_testing_examples/platform-switching/zig-platform/host.zig index d03e803047..e9f6cc83e4 100644 --- a/crates/cli_testing_examples/platform-switching/zig-platform/host.zig +++ b/crates/cli_testing_examples/platform-switching/zig-platform/host.zig @@ -75,6 +75,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { return memset(dst, value, size); } +extern fn kill(pid: c_int, sig: c_int) c_int; +extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; +extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; +extern fn getppid() c_int; + +fn roc_getppid() callconv(.C) c_int { + return getppid(); +} + +fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int { + return kill(pid, sig); +} +fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int { + return shm_open(name, oflag, mode); +} +fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque { + return mmap(addr, length, prot, flags, fd, offset); +} + +comptime { + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + @export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong }); + @export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong }); + @export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong }); + @export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong }); + } +} + const mem = std.mem; const Allocator = mem.Allocator; @@ -103,4 +131,4 @@ pub fn main() u8 { stderr.print("runtime: {d:.3}ms\n", .{seconds * 1000}) catch unreachable; return 0; -} \ No newline at end of file +} diff --git a/crates/compiler/builtins/bitcode/src/expect.zig b/crates/compiler/builtins/bitcode/src/expect.zig index 9aab2081a2..f6a7e19c73 100644 --- a/crates/compiler/builtins/bitcode/src/expect.zig +++ b/crates/compiler/builtins/bitcode/src/expect.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const SIGUSR1: c_int = 10; @@ -22,32 +23,36 @@ pub fn expectFailedStart() callconv(.C) [*]u8 { return SHARED_BUFFER.ptr; } -extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; -extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; -extern fn kill(pid: c_int, sig: c_int) c_int; -extern fn getppid() c_int; +extern fn roc_send_signal(pid: c_int, sig: c_int) c_int; +extern fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; +extern fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; +extern fn roc_getppid() c_int; pub fn readSharedBufferEnv() callconv(.C) void { - const name = "/roc_expect_buffer"; // IMPORTANT: shared memory object names must begin with / and contain no other slashes! - const shared_fd = shm_open(@ptrCast(*const i8, name), O_RDWR | O_CREAT, 0o666); - const length = 4096; + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + const name = "/roc_expect_buffer"; // IMPORTANT: shared memory object names must begin with / and contain no other slashes! + const shared_fd = roc_shm_open(@ptrCast(*const i8, name), O_RDWR | O_CREAT, 0o666); + const length = 4096; - const shared_ptr = mmap( - null, - length, - PROT_WRITE, - MAP_SHARED, - shared_fd, - 0, - ); + const shared_ptr = roc_mmap( + null, + length, + PROT_WRITE, + MAP_SHARED, + shared_fd, + 0, + ); - const ptr = @ptrCast([*]u8, shared_ptr); + const ptr = @ptrCast([*]u8, shared_ptr); - SHARED_BUFFER = ptr[0..length]; + SHARED_BUFFER = ptr[0..length]; + } } pub fn expectFailedFinalize() callconv(.C) void { - const parent_pid = getppid(); + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + const parent_pid = roc_getppid(); - _ = kill(parent_pid, SIGUSR1); + _ = roc_send_signal(parent_pid, SIGUSR1); + } } diff --git a/crates/linker/src/elf.rs b/crates/linker/src/elf.rs index 11db80e4da..637054a173 100644 --- a/crates/linker/src/elf.rs +++ b/crates/linker/src/elf.rs @@ -77,13 +77,23 @@ fn collect_roc_definitions<'a>(object: &object::File<'a, &'a [u8]>) -> MutMap Some("memcpy"), + "roc_memset" => Some("memset"), + "roc_memmove" => Some("memmove"), + + // for expects + "roc_mmap" => Some("mmap"), + "roc_getppid" => Some("getppid"), + "roc_send_signal" => Some("kill"), + "roc_shm_open" => Some("shm_open"), + + _ => None, + }; + + if let Some(libc_symbol) = direct_mapping { + vaddresses.insert(libc_symbol.to_string(), address); } vaddresses.insert(name.to_string(), address); diff --git a/examples/cli/cli-platform/src/lib.rs b/examples/cli/cli-platform/src/lib.rs index 51abf949eb..d8b8787d2f 100644 --- a/examples/cli/cli-platform/src/lib.rs +++ b/examples/cli/cli-platform/src/lib.rs @@ -73,6 +73,41 @@ pub unsafe extern "C" fn roc_panic(c_ptr: *mut c_void, tag_id: u32) { } } +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_getppid() -> libc::pid_t { + libc::getppid() +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_mmap( + addr: *mut libc::c_void, + len: libc::size_t, + prot: libc::c_int, + flags: libc::c_int, + fd: libc::c_int, + offset: libc::off_t, +) -> *mut libc::c_void { + libc::mmap(addr, len, prot, flags, fd, offset) +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_shm_open( + name: *const libc::c_char, + oflag: libc::c_int, + mode: libc::mode_t, +) -> libc::c_int { + libc::shm_open(name, oflag, mode) +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int { + libc::kill(pid, sig) +} + fn print_backtrace() { eprintln!("Here is the call stack that led to the crash:\n"); diff --git a/examples/cli/effects-platform/host.zig b/examples/cli/effects-platform/host.zig index 8489b36425..afb4604076 100644 --- a/examples/cli/effects-platform/host.zig +++ b/examples/cli/effects-platform/host.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const str = @import("str"); const RocStr = str.RocStr; const testing = std.testing; @@ -15,7 +16,6 @@ comptime { // -fcompiler-rt in link.rs instead of doing this. Note that this // workaround is present in many host.zig files, so make sure to undo // it everywhere! - const builtin = @import("builtin"); if (builtin.os.tag == .macos) { _ = @import("compiler_rt"); } @@ -85,6 +85,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { return memset(dst, value, size); } +extern fn kill(pid: c_int, sig: c_int) c_int; +extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; +extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; +extern fn getppid() c_int; + +fn roc_getppid() callconv(.C) c_int { + return getppid(); +} + +fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int { + return kill(pid, sig); +} +fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int { + return shm_open(name, oflag, mode); +} +fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque { + return mmap(addr, length, prot, flags, fd, offset); +} + +comptime { + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + @export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong }); + @export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong }); + @export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong }); + @export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong }); + } +} + const Unit = extern struct {}; pub export fn main() u8 { diff --git a/examples/cli/false-interpreter/platform/src/lib.rs b/examples/cli/false-interpreter/platform/src/lib.rs index 64e1a92c1a..1d0dfcf63a 100644 --- a/examples/cli/false-interpreter/platform/src/lib.rs +++ b/examples/cli/false-interpreter/platform/src/lib.rs @@ -72,6 +72,41 @@ pub unsafe extern "C" fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut libc::memset(dst, c, n) } +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_getppid() -> libc::pid_t { + libc::getppid() +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_mmap( + addr: *mut libc::c_void, + len: libc::size_t, + prot: libc::c_int, + flags: libc::c_int, + fd: libc::c_int, + offset: libc::off_t, +) -> *mut libc::c_void { + libc::mmap(addr, len, prot, flags, fd, offset) +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_shm_open( + name: *const libc::c_char, + oflag: libc::c_int, + mode: libc::mode_t, +) -> libc::c_int { + libc::shm_open(name, oflag, mode) +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int { + libc::kill(pid, sig) +} + #[no_mangle] pub extern "C" fn rust_main() -> i32 { let arg = env::args() diff --git a/examples/cli/tui-platform/host.zig b/examples/cli/tui-platform/host.zig index fea7652bc7..5120c4aaf7 100644 --- a/examples/cli/tui-platform/host.zig +++ b/examples/cli/tui-platform/host.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const str = @import("str"); const RocStr = str.RocStr; const testing = std.testing; @@ -15,7 +16,6 @@ comptime { // -fcompiler-rt in link.rs instead of doing this. Note that this // workaround is present in many host.zig files, so make sure to undo // it everywhere! - const builtin = @import("builtin"); if (builtin.os.tag == .macos) { _ = @import("compiler_rt"); } @@ -134,6 +134,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { return memset(dst, value, size); } +extern fn kill(pid: c_int, sig: c_int) c_int; +extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; +extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; +extern fn getppid() c_int; + +fn roc_getppid() callconv(.C) c_int { + return getppid(); +} + +fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int { + return kill(pid, sig); +} +fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int { + return shm_open(name, oflag, mode); +} +fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque { + return mmap(addr, length, prot, flags, fd, offset); +} + +comptime { + if (builtin.os.tag == .macos or builtin.os.tag == .linux) { + @export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong }); + @export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong }); + @export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong }); + @export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong }); + } +} + const Unit = extern struct {}; pub export fn main() callconv(.C) u8 { diff --git a/examples/parser/platform/host.c b/examples/parser/platform/host.c index 56465121be..6bbd8c76c0 100644 --- a/examples/parser/platform/host.c +++ b/examples/parser/platform/host.c @@ -95,6 +95,11 @@ void *roc_memset(void *str, int c, size_t n) { return memset(str, c, n); } +int roc_send_signal(int pid, int sig) { return kill(pid, sig); } +int roc_shm_open(char* name, int oflag, int mode) { return shm_open(name, oflag, mode); } +void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) { return mmap(addr, length, prot, flags, fd, offset); } +int roc_getppid() { return getppid(); } + struct RocStr { char *bytes; size_t len; diff --git a/examples/ruby-interop/platform/host.c b/examples/ruby-interop/platform/host.c index 3f9a63c2a2..3141892345 100644 --- a/examples/ruby-interop/platform/host.c +++ b/examples/ruby-interop/platform/host.c @@ -27,6 +27,11 @@ void* roc_memcpy(void* dest, const void* src, size_t n) { void* roc_memset(void* str, int c, size_t n) { return memset(str, c, n); } +int roc_send_signal(int pid, int sig) { return kill(pid, sig); } +int roc_shm_open(char* name, int oflag, int mode) { return shm_open(name, oflag, mode); } +void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) { return mmap(addr, length, prot, flags, fd, offset); } +int roc_getppid() { return getppid(); } + struct RocStr { char* bytes; size_t len; diff --git a/examples/static-site-gen/platform/src/lib.rs b/examples/static-site-gen/platform/src/lib.rs index 40349b3a17..f3a36167c2 100644 --- a/examples/static-site-gen/platform/src/lib.rs +++ b/examples/static-site-gen/platform/src/lib.rs @@ -33,6 +33,41 @@ pub unsafe extern "C" fn roc_dealloc(c_ptr: *mut c_void, _alignment: u32) { libc::free(c_ptr) } +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_getppid() -> libc::pid_t { + libc::getppid() +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_mmap( + addr: *mut libc::c_void, + len: libc::size_t, + prot: libc::c_int, + flags: libc::c_int, + fd: libc::c_int, + offset: libc::off_t, +) -> *mut libc::c_void { + libc::mmap(addr, len, prot, flags, fd, offset) +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_shm_open( + name: *const libc::c_char, + oflag: libc::c_int, + mode: libc::mode_t, +) -> libc::c_int { + libc::shm_open(name, oflag, mode) +} + +#[cfg(unix)] +#[no_mangle] +pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int { + libc::kill(pid, sig) +} + #[no_mangle] pub extern "C" fn rust_main() -> i32 { let args: Vec = env::args().collect();