mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-02 22:01:20 +00:00
inline dbg
This commit is contained in:
parent
dcb530d3af
commit
e7f3c6f281
18 changed files with 192 additions and 21 deletions
|
|
@ -939,7 +939,11 @@ fn roc_dev_native(
|
|||
expect_metadata: ExpectMetadata,
|
||||
) -> ! {
|
||||
use roc_repl_expect::run::ExpectMemory;
|
||||
use signal_hook::{consts::signal::SIGCHLD, consts::signal::SIGUSR1, iterator::Signals};
|
||||
use signal_hook::{
|
||||
consts::signal::SIGCHLD,
|
||||
consts::signal::{SIGUSR1, SIGUSR2},
|
||||
iterator::Signals,
|
||||
};
|
||||
|
||||
let ExpectMetadata {
|
||||
mut expectations,
|
||||
|
|
@ -947,7 +951,7 @@ fn roc_dev_native(
|
|||
layout_interner,
|
||||
} = expect_metadata;
|
||||
|
||||
let mut signals = Signals::new(&[SIGCHLD, SIGUSR1]).unwrap();
|
||||
let mut signals = Signals::new(&[SIGCHLD, SIGUSR1, SIGUSR2]).unwrap();
|
||||
|
||||
// let shm_name =
|
||||
let shm_name = format!("/roc_expect_buffer_{}", std::process::id());
|
||||
|
|
@ -993,6 +997,11 @@ fn roc_dev_native(
|
|||
)
|
||||
.unwrap();
|
||||
}
|
||||
SIGUSR2 => {
|
||||
// this is the signal we use for a dbg
|
||||
|
||||
println!("I need to dbg something");
|
||||
}
|
||||
_ => println!("received signal {}", sig),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,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 O_RDWR: c_int = 2;
|
||||
const O_CREAT: c_int = 64;
|
||||
|
|
@ -87,3 +88,11 @@ pub fn expectFailedFinalize() callconv(.C) void {
|
|||
_ = roc_send_signal(parent_pid, SIGUSR1);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ comptime {
|
|||
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");
|
||||
|
||||
// sets the buffer used for expect failures
|
||||
@export(expect.setSharedBuffer, .{ .name = "set_shared_buffer", .linkage = .Weak });
|
||||
|
|
|
|||
|
|
@ -410,6 +410,7 @@ 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 UTILS_LONGJMP: &str = "longjmp";
|
||||
pub const UTILS_SETJMP: &str = "setjmp";
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ macro_rules! map_symbol_to_lowlevel_and_arity {
|
|||
LowLevel::PtrCast => unimplemented!(),
|
||||
LowLevel::RefCountInc => unimplemented!(),
|
||||
LowLevel::RefCountDec => unimplemented!(),
|
||||
LowLevel::Dbg => unimplemented!(),
|
||||
|
||||
// these are not implemented, not sure why
|
||||
LowLevel::StrFromInt => unimplemented!(),
|
||||
|
|
|
|||
|
|
@ -611,6 +611,16 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
|
|||
lookups_in_cond: lookups_in_cond.to_vec(),
|
||||
},
|
||||
|
||||
Dbg {
|
||||
loc_condition,
|
||||
loc_continuation,
|
||||
variable,
|
||||
} => Dbg {
|
||||
loc_condition: Box::new(loc_condition.map(|e| go_help!(e))),
|
||||
loc_continuation: Box::new(loc_continuation.map(|e| go_help!(e))),
|
||||
variable: sub!(*variable),
|
||||
},
|
||||
|
||||
TypedHole(v) => TypedHole(sub!(*v)),
|
||||
|
||||
RuntimeError(err) => RuntimeError(err.clone()),
|
||||
|
|
|
|||
|
|
@ -240,6 +240,12 @@ pub enum Expr {
|
|||
lookups_in_cond: Vec<ExpectLookup>,
|
||||
},
|
||||
|
||||
Dbg {
|
||||
loc_condition: Box<Loc<Expr>>,
|
||||
loc_continuation: Box<Loc<Expr>>,
|
||||
variable: Variable,
|
||||
},
|
||||
|
||||
/// Rendered as empty box in editor
|
||||
TypedHole(Variable),
|
||||
|
||||
|
|
@ -295,6 +301,8 @@ impl Expr {
|
|||
Self::Expect { .. } => Category::Expect,
|
||||
Self::ExpectFx { .. } => Category::Expect,
|
||||
|
||||
Self::Dbg { .. } => Category::Expect,
|
||||
|
||||
// these nodes place no constraints on the expression's type
|
||||
Self::TypedHole(_) | Self::RuntimeError(..) => Category::Unknown,
|
||||
}
|
||||
|
|
@ -1826,6 +1834,28 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
|||
}
|
||||
}
|
||||
|
||||
Dbg {
|
||||
loc_condition,
|
||||
loc_continuation,
|
||||
variable,
|
||||
} => {
|
||||
let loc_condition = Loc {
|
||||
region: loc_condition.region,
|
||||
value: inline_calls(var_store, loc_condition.value),
|
||||
};
|
||||
|
||||
let loc_continuation = Loc {
|
||||
region: loc_continuation.region,
|
||||
value: inline_calls(var_store, loc_continuation.value),
|
||||
};
|
||||
|
||||
Dbg {
|
||||
loc_condition: Box::new(loc_condition),
|
||||
loc_continuation: Box::new(loc_continuation),
|
||||
variable,
|
||||
}
|
||||
}
|
||||
|
||||
LetRec(defs, loc_expr, mark) => {
|
||||
let mut new_defs = Vec::with_capacity(defs.len());
|
||||
|
||||
|
|
@ -2740,6 +2770,9 @@ fn get_lookup_symbols(expr: &Expr) -> Vec<ExpectLookup> {
|
|||
}
|
||||
| Expr::ExpectFx {
|
||||
loc_continuation, ..
|
||||
}
|
||||
| Expr::Dbg {
|
||||
loc_continuation, ..
|
||||
} => {
|
||||
stack.push(&loc_continuation.value);
|
||||
|
||||
|
|
|
|||
|
|
@ -952,24 +952,17 @@ fn fix_values_captured_in_closure_expr(
|
|||
Expect {
|
||||
loc_condition,
|
||||
loc_continuation,
|
||||
lookups_in_cond: _,
|
||||
} => {
|
||||
fix_values_captured_in_closure_expr(
|
||||
&mut loc_condition.value,
|
||||
no_capture_symbols,
|
||||
closure_captures,
|
||||
);
|
||||
fix_values_captured_in_closure_expr(
|
||||
&mut loc_continuation.value,
|
||||
no_capture_symbols,
|
||||
closure_captures,
|
||||
);
|
||||
..
|
||||
}
|
||||
|
||||
ExpectFx {
|
||||
| ExpectFx {
|
||||
loc_condition,
|
||||
loc_continuation,
|
||||
lookups_in_cond: _,
|
||||
..
|
||||
}
|
||||
| Dbg {
|
||||
loc_condition,
|
||||
loc_continuation,
|
||||
..
|
||||
} => {
|
||||
fix_values_captured_in_closure_expr(
|
||||
&mut loc_condition.value,
|
||||
|
|
|
|||
|
|
@ -268,8 +268,7 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
|||
loc_continuation,
|
||||
lookups_in_cond: _,
|
||||
} => {
|
||||
// TODO: what type does an expect have? bool
|
||||
visitor.visit_expr(&loc_condition.value, loc_condition.region, Variable::NULL);
|
||||
visitor.visit_expr(&loc_condition.value, loc_condition.region, Variable::BOOL);
|
||||
visitor.visit_expr(
|
||||
&loc_continuation.value,
|
||||
loc_continuation.region,
|
||||
|
|
@ -281,8 +280,19 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
|||
loc_continuation,
|
||||
lookups_in_cond: _,
|
||||
} => {
|
||||
// TODO: what type does an expect have? bool
|
||||
visitor.visit_expr(&loc_condition.value, loc_condition.region, Variable::NULL);
|
||||
visitor.visit_expr(&loc_condition.value, loc_condition.region, Variable::BOOL);
|
||||
visitor.visit_expr(
|
||||
&loc_continuation.value,
|
||||
loc_continuation.region,
|
||||
Variable::NULL,
|
||||
);
|
||||
}
|
||||
Expr::Dbg {
|
||||
variable,
|
||||
loc_condition,
|
||||
loc_continuation,
|
||||
} => {
|
||||
visitor.visit_expr(&loc_condition.value, loc_condition.region, *variable);
|
||||
visitor.visit_expr(
|
||||
&loc_continuation.value,
|
||||
loc_continuation.region,
|
||||
|
|
|
|||
|
|
@ -656,6 +656,35 @@ pub fn constrain_expr(
|
|||
constraints.exists_many(vars, all_constraints)
|
||||
}
|
||||
|
||||
Dbg {
|
||||
loc_condition,
|
||||
loc_continuation,
|
||||
variable,
|
||||
} => {
|
||||
let dbg_type = constraints.push_variable(*variable);
|
||||
let expected_dbg = constraints.push_expected_type(Expected::NoExpectation(dbg_type));
|
||||
|
||||
let cond_con = constrain_expr(
|
||||
types,
|
||||
constraints,
|
||||
env,
|
||||
loc_condition.region,
|
||||
&loc_condition.value,
|
||||
expected_dbg,
|
||||
);
|
||||
|
||||
let continuation_con = constrain_expr(
|
||||
types,
|
||||
constraints,
|
||||
env,
|
||||
loc_continuation.region,
|
||||
&loc_continuation.value,
|
||||
expected,
|
||||
);
|
||||
|
||||
constraints.exists_many([], [cond_con, continuation_con])
|
||||
}
|
||||
|
||||
If {
|
||||
cond_var,
|
||||
branch_var,
|
||||
|
|
|
|||
|
|
@ -104,6 +104,13 @@ pub(crate) fn finalize(env: &Env) {
|
|||
.build_call(func, &[], "call_expect_failed_finalize");
|
||||
}
|
||||
|
||||
pub(crate) fn send_dbg(env: &Env) {
|
||||
let func = env.module.get_function(bitcode::UTILS_SEND_DBG).unwrap();
|
||||
|
||||
env.builder
|
||||
.build_call(func, &[], "call_expect_failed_finalize");
|
||||
}
|
||||
|
||||
pub(crate) fn clone_to_shared_memory<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
scope: &Scope<'a, 'ctx>,
|
||||
|
|
|
|||
|
|
@ -1119,6 +1119,25 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
|||
ptr.into()
|
||||
}
|
||||
},
|
||||
Dbg => {
|
||||
// now what
|
||||
arguments!(condition);
|
||||
|
||||
let region = roc_region::all::Region::zero(); // todo
|
||||
|
||||
crate::llvm::expect::clone_to_shared_memory(
|
||||
env,
|
||||
scope,
|
||||
layout_ids,
|
||||
args[0],
|
||||
region,
|
||||
&[],
|
||||
);
|
||||
|
||||
crate::llvm::expect::send_dbg(env);
|
||||
|
||||
condition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1874,6 +1874,8 @@ impl<'a> LowLevelCall<'a> {
|
|||
},
|
||||
StoredValue::StackMemory { .. } => { /* do nothing */ }
|
||||
},
|
||||
|
||||
Dbg => todo!("{:?}", self.lowlevel),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ pub enum LowLevel {
|
|||
RefCountDec,
|
||||
BoxExpr,
|
||||
UnboxExpr,
|
||||
Dbg,
|
||||
Unreachable,
|
||||
}
|
||||
|
||||
|
|
@ -208,11 +209,13 @@ macro_rules! map_symbol_to_lowlevel {
|
|||
LowLevel::NumToIntChecked => unreachable!(),
|
||||
LowLevel::NumToFloatChecked => unreachable!(),
|
||||
|
||||
|
||||
// these are used internally and not tied to a symbol
|
||||
LowLevel::Hash => unimplemented!(),
|
||||
LowLevel::PtrCast => unimplemented!(),
|
||||
LowLevel::RefCountInc => unimplemented!(),
|
||||
LowLevel::RefCountDec => unimplemented!(),
|
||||
LowLevel::Dbg => unreachable!(),
|
||||
|
||||
// these are not implemented, not sure why
|
||||
LowLevel::StrFromInt => unimplemented!(),
|
||||
|
|
|
|||
|
|
@ -937,6 +937,8 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
|||
|
||||
ListIsUnique => arena.alloc_slice_copy(&[borrowed]),
|
||||
|
||||
Dbg => arena.alloc_slice_copy(&[borrowed]),
|
||||
|
||||
BoxExpr | UnboxExpr => {
|
||||
unreachable!("These lowlevel operations are turned into mono Expr's")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4403,6 +4403,7 @@ pub fn with_hole<'a>(
|
|||
|
||||
Expect { .. } => unreachable!("I think this is unreachable"),
|
||||
ExpectFx { .. } => unreachable!("I think this is unreachable"),
|
||||
Dbg { .. } => unreachable!("I think this is unreachable"),
|
||||
|
||||
If {
|
||||
cond_var,
|
||||
|
|
@ -6546,6 +6547,42 @@ pub fn from_can<'a>(
|
|||
stmt
|
||||
}
|
||||
|
||||
Dbg {
|
||||
loc_condition,
|
||||
loc_continuation,
|
||||
variable,
|
||||
} => {
|
||||
let rest = from_can(env, variable, loc_continuation.value, procs, layout_cache);
|
||||
let dbg_symbol = env.unique_symbol();
|
||||
|
||||
let call = crate::ir::Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::Dbg,
|
||||
update_mode: env.next_update_mode_id(),
|
||||
},
|
||||
arguments: env.arena.alloc([dbg_symbol]),
|
||||
};
|
||||
|
||||
let dbg_layout = layout_cache
|
||||
.from_var(env.arena, variable, env.subs)
|
||||
.expect("invalid dbg_layout");
|
||||
|
||||
let expr = Expr::Call(call);
|
||||
let mut stmt = Stmt::Let(dbg_symbol, expr, dbg_layout, env.arena.alloc(rest));
|
||||
|
||||
stmt = with_hole(
|
||||
env,
|
||||
loc_condition.value,
|
||||
variable,
|
||||
procs,
|
||||
layout_cache,
|
||||
dbg_symbol,
|
||||
env.arena.alloc(stmt),
|
||||
);
|
||||
|
||||
stmt
|
||||
}
|
||||
|
||||
LetRec(defs, cont, _cycle_mark) => {
|
||||
// because Roc is strict, only functions can be recursive!
|
||||
for def in defs.into_iter() {
|
||||
|
|
|
|||
|
|
@ -3529,6 +3529,7 @@ pub enum Category {
|
|||
AbilityMemberSpecialization(Symbol),
|
||||
|
||||
Expect,
|
||||
Dbg,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1696,6 +1696,10 @@ fn format_category<'b>(
|
|||
alloc.concat([this_is, alloc.text(" an expectation")]),
|
||||
alloc.text(" of type:"),
|
||||
),
|
||||
Dbg => (
|
||||
alloc.concat([this_is, alloc.text(" a dbg statement")]),
|
||||
alloc.text(" of type:"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue