mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 06:55:15 +00:00
Merge branch 'expect-dbg-atomics' into expect-print-values
This commit is contained in:
commit
4b9e64fd7d
27 changed files with 169 additions and 169 deletions
|
@ -1,8 +1,7 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const SIGUSR1: c_int = if (builtin.os.tag.isDarwin()) 30 else 10;
|
||||
const SIGUSR2: c_int = if (builtin.os.tag.isDarwin()) 31 else 12;
|
||||
const Atomic = std.atomic.Atomic;
|
||||
|
||||
const O_RDWR: c_int = 2;
|
||||
const O_CREAT: c_int = 64;
|
||||
|
@ -51,7 +50,6 @@ pub fn expectFailedStartSharedFile() callconv(.C) [*]u8 {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -81,18 +79,24 @@ pub fn readSharedBufferEnv() callconv(.C) void {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expectFailedFinalize() callconv(.C) void {
|
||||
pub fn notifyParent(shared_buffer: [*]u8, tag: u32) callconv(.C) void {
|
||||
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
||||
const parent_pid = roc_getppid();
|
||||
const usize_ptr = @ptrCast([*]u32, @alignCast(@alignOf(usize), shared_buffer));
|
||||
const atomic_ptr = @ptrCast(*Atomic(u32), &usize_ptr[5]);
|
||||
atomic_ptr.storeUnchecked(tag);
|
||||
|
||||
_ = roc_send_signal(parent_pid, SIGUSR1);
|
||||
// wait till the parent is done before proceeding
|
||||
const Ordering = std.atomic.Ordering;
|
||||
while (atomic_ptr.load(Ordering.Acquire) != 0) {
|
||||
std.atomic.spinLoopHint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sendDbg() callconv(.C) void {
|
||||
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
||||
const parent_pid = roc_getppid();
|
||||
|
||||
_ = roc_send_signal(parent_pid, SIGUSR2);
|
||||
}
|
||||
pub fn notifyParentExpect(shared_buffer: [*]u8) callconv(.C) void {
|
||||
notifyParent(shared_buffer, 1);
|
||||
}
|
||||
|
||||
pub fn notifyParentDbg(shared_buffer: [*]u8) callconv(.C) void {
|
||||
notifyParent(shared_buffer, 2);
|
||||
}
|
||||
|
|
|
@ -172,8 +172,8 @@ comptime {
|
|||
if (builtin.target.cpu.arch != .wasm32) {
|
||||
exportUtilsFn(expect.expectFailedStartSharedBuffer, "expect_failed_start_shared_buffer");
|
||||
exportUtilsFn(expect.expectFailedStartSharedFile, "expect_failed_start_shared_file");
|
||||
exportUtilsFn(expect.expectFailedFinalize, "expect_failed_finalize");
|
||||
exportUtilsFn(expect.sendDbg, "send_dbg");
|
||||
exportUtilsFn(expect.notifyParentExpect, "notify_parent_expect");
|
||||
exportUtilsFn(expect.notifyParentDbg, "notify_parent_dbg");
|
||||
|
||||
// sets the buffer used for expect failures
|
||||
@export(expect.setSharedBuffer, .{ .name = "set_shared_buffer", .linkage = .Weak });
|
||||
|
|
|
@ -32,9 +32,6 @@ fn roc_getppid_windows_stub() callconv(.C) c_int {
|
|||
return 0;
|
||||
}
|
||||
|
||||
fn testing_roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
|
||||
return kill(pid, sig);
|
||||
}
|
||||
fn testing_roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
|
||||
return shm_open(name, oflag, mode);
|
||||
}
|
||||
|
@ -55,7 +52,6 @@ comptime {
|
|||
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
||||
@export(testing_roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
|
||||
@export(testing_roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
|
||||
@export(testing_roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
|
||||
@export(testing_roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -424,9 +424,9 @@ pub const UTILS_EXPECT_FAILED_START_SHARED_BUFFER: &str =
|
|||
"roc_builtins.utils.expect_failed_start_shared_buffer";
|
||||
pub const UTILS_EXPECT_FAILED_START_SHARED_FILE: &str =
|
||||
"roc_builtins.utils.expect_failed_start_shared_file";
|
||||
pub const UTILS_EXPECT_FAILED_FINALIZE: &str = "roc_builtins.utils.expect_failed_finalize";
|
||||
pub const UTILS_EXPECT_READ_ENV_SHARED_BUFFER: &str = "roc_builtins.utils.read_env_shared_buffer";
|
||||
pub const UTILS_SEND_DBG: &str = "roc_builtins.utils.send_dbg";
|
||||
pub const NOTIFY_PARENT_EXPECT: &str = "roc_builtins.utils.notify_parent_expect";
|
||||
pub const NOTIFY_PARENT_DBG: &str = "roc_builtins.utils.notify_parent_dbg";
|
||||
|
||||
pub const UTILS_LONGJMP: &str = "longjmp";
|
||||
pub const UTILS_SETJMP: &str = "setjmp";
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::llvm::build_list::{self, allocate_list, empty_polymorphic_list};
|
|||
use crate::llvm::convert::{
|
||||
argument_type_from_layout, basic_type_from_builtin, basic_type_from_layout, zig_str_type,
|
||||
};
|
||||
use crate::llvm::expect::clone_to_shared_memory;
|
||||
use crate::llvm::expect::{clone_to_shared_memory, SharedMemoryPointer};
|
||||
use crate::llvm::refcounting::{
|
||||
build_reset, decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
|
||||
};
|
||||
|
@ -2611,17 +2611,20 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
|||
|
||||
match env.target_info.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes8 => {
|
||||
let shared_memory = SharedMemoryPointer::get(env);
|
||||
|
||||
clone_to_shared_memory(
|
||||
env,
|
||||
scope,
|
||||
layout_ids,
|
||||
&shared_memory,
|
||||
*cond_symbol,
|
||||
*region,
|
||||
lookups,
|
||||
);
|
||||
|
||||
if let LlvmBackendMode::BinaryDev = env.mode {
|
||||
crate::llvm::expect::finalize(env);
|
||||
crate::llvm::expect::notify_parent_expect(env, &shared_memory);
|
||||
}
|
||||
|
||||
bd.build_unconditional_branch(then_block);
|
||||
|
@ -2677,10 +2680,13 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
|||
|
||||
match env.target_info.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes8 => {
|
||||
let shared_memory = SharedMemoryPointer::get(env);
|
||||
|
||||
clone_to_shared_memory(
|
||||
env,
|
||||
scope,
|
||||
layout_ids,
|
||||
&shared_memory,
|
||||
*cond_symbol,
|
||||
*region,
|
||||
lookups,
|
||||
|
|
|
@ -18,6 +18,32 @@ use super::build::{
|
|||
Scope,
|
||||
};
|
||||
|
||||
pub(crate) struct SharedMemoryPointer<'ctx>(PointerValue<'ctx>);
|
||||
|
||||
impl<'ctx> SharedMemoryPointer<'ctx> {
|
||||
pub(crate) fn get<'a, 'env>(env: &Env<'a, 'ctx, 'env>) -> Self {
|
||||
let start_function = if let LlvmBackendMode::BinaryDev = env.mode {
|
||||
bitcode::UTILS_EXPECT_FAILED_START_SHARED_FILE
|
||||
} else {
|
||||
bitcode::UTILS_EXPECT_FAILED_START_SHARED_BUFFER
|
||||
};
|
||||
|
||||
let func = env.module.get_function(start_function).unwrap();
|
||||
|
||||
let call_result = env
|
||||
.builder
|
||||
.build_call(func, &[], "call_expect_start_failed");
|
||||
|
||||
let ptr = call_result
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap()
|
||||
.into_pointer_value();
|
||||
|
||||
Self(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Cursors<'ctx> {
|
||||
offset: IntValue<'ctx>,
|
||||
|
@ -94,48 +120,39 @@ fn write_state<'a, 'ctx, 'env>(
|
|||
env.builder.build_store(offset_ptr, offset);
|
||||
}
|
||||
|
||||
pub(crate) fn finalize(env: &Env) {
|
||||
pub(crate) fn notify_parent_expect(env: &Env, shared_memory: &SharedMemoryPointer) {
|
||||
let func = env
|
||||
.module
|
||||
.get_function(bitcode::UTILS_EXPECT_FAILED_FINALIZE)
|
||||
.get_function(bitcode::NOTIFY_PARENT_EXPECT)
|
||||
.unwrap();
|
||||
|
||||
env.builder
|
||||
.build_call(func, &[], "call_expect_failed_finalize");
|
||||
env.builder.build_call(
|
||||
func,
|
||||
&[shared_memory.0.into()],
|
||||
"call_expect_failed_finalize",
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn send_dbg(env: &Env) {
|
||||
let func = env.module.get_function(bitcode::UTILS_SEND_DBG).unwrap();
|
||||
pub(crate) fn notify_parent_dbg(env: &Env, shared_memory: &SharedMemoryPointer) {
|
||||
let func = env.module.get_function(bitcode::NOTIFY_PARENT_DBG).unwrap();
|
||||
|
||||
env.builder
|
||||
.build_call(func, &[], "call_expect_failed_finalize");
|
||||
env.builder.build_call(
|
||||
func,
|
||||
&[shared_memory.0.into()],
|
||||
"call_expect_failed_finalize",
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn clone_to_shared_memory<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
scope: &Scope<'a, 'ctx>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
shared_memory: &SharedMemoryPointer<'ctx>,
|
||||
condition: Symbol,
|
||||
region: Region,
|
||||
lookups: &[Symbol],
|
||||
) {
|
||||
let start_function = if let LlvmBackendMode::BinaryDev = env.mode {
|
||||
bitcode::UTILS_EXPECT_FAILED_START_SHARED_FILE
|
||||
} else {
|
||||
bitcode::UTILS_EXPECT_FAILED_START_SHARED_BUFFER
|
||||
};
|
||||
|
||||
let func = env.module.get_function(start_function).unwrap();
|
||||
|
||||
let call_result = env
|
||||
.builder
|
||||
.build_call(func, &[], "call_expect_start_failed");
|
||||
|
||||
let original_ptr = call_result
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap()
|
||||
.into_pointer_value();
|
||||
let original_ptr = shared_memory.0;
|
||||
|
||||
let (count, mut offset) = read_state(env, original_ptr);
|
||||
|
||||
|
|
|
@ -158,7 +158,6 @@ pub fn add_default_roc_externs(env: &Env<'_, '_, '_>) {
|
|||
|
||||
unreachable_function(env, "roc_getppid");
|
||||
unreachable_function(env, "roc_mmap");
|
||||
unreachable_function(env, "roc_send_signal");
|
||||
unreachable_function(env, "roc_shm_open");
|
||||
|
||||
add_sjlj_roc_panic(env)
|
||||
|
@ -168,7 +167,10 @@ pub fn add_default_roc_externs(env: &Env<'_, '_, '_>) {
|
|||
fn unreachable_function(env: &Env, name: &str) {
|
||||
// The type of this function (but not the implementation) should have
|
||||
// already been defined by the builtins, which rely on it.
|
||||
let fn_val = env.module.get_function(name).unwrap();
|
||||
let fn_val = match env.module.get_function(name) {
|
||||
Some(f) => f,
|
||||
None => panic!("extern function {name} is not defined by the builtins"),
|
||||
};
|
||||
|
||||
// Add a basic block for the entry point
|
||||
let entry = env.context.append_basic_block(fn_val, "entry");
|
||||
|
|
|
@ -1126,16 +1126,19 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
|||
if env.mode.runs_expects() {
|
||||
let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(args[0]) };
|
||||
|
||||
let shared_memory = crate::llvm::expect::SharedMemoryPointer::get(env);
|
||||
|
||||
crate::llvm::expect::clone_to_shared_memory(
|
||||
env,
|
||||
scope,
|
||||
layout_ids,
|
||||
&shared_memory,
|
||||
args[0],
|
||||
region,
|
||||
&[args[0]],
|
||||
);
|
||||
|
||||
crate::llvm::expect::send_dbg(env);
|
||||
crate::llvm::expect::notify_parent_dbg(env, &shared_memory);
|
||||
}
|
||||
|
||||
condition
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue