mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
add exception id to invoke/rethrow
This commit is contained in:
parent
3636e18a18
commit
64576ddab5
8 changed files with 101 additions and 92 deletions
|
@ -48,7 +48,9 @@ use roc_collections::all::{ImMap, MutSet};
|
||||||
use roc_module::ident::TagName;
|
use roc_module::ident::TagName;
|
||||||
use roc_module::low_level::LowLevel;
|
use roc_module::low_level::LowLevel;
|
||||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||||
use roc_mono::ir::{BranchInfo, CallType, JoinPointId, ModifyRc, TopLevelFunctionLayout, Wrapped};
|
use roc_mono::ir::{
|
||||||
|
BranchInfo, CallType, ExceptionId, JoinPointId, ModifyRc, TopLevelFunctionLayout, Wrapped,
|
||||||
|
};
|
||||||
use roc_mono::layout::{Builtin, InPlace, LambdaSet, Layout, LayoutIds, UnionLayout};
|
use roc_mono::layout::{Builtin, InPlace, LambdaSet, Layout, LayoutIds, UnionLayout};
|
||||||
use target_lexicon::CallingConvention;
|
use target_lexicon::CallingConvention;
|
||||||
|
|
||||||
|
@ -1821,6 +1823,7 @@ fn invoke_roc_function<'a, 'ctx, 'env>(
|
||||||
closure_argument: Option<BasicValueEnum<'ctx>>,
|
closure_argument: Option<BasicValueEnum<'ctx>>,
|
||||||
pass: &'a roc_mono::ir::Stmt<'a>,
|
pass: &'a roc_mono::ir::Stmt<'a>,
|
||||||
fail: &'a roc_mono::ir::Stmt<'a>,
|
fail: &'a roc_mono::ir::Stmt<'a>,
|
||||||
|
exception_id: ExceptionId,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let context = env.context;
|
let context = env.context;
|
||||||
|
|
||||||
|
@ -1877,14 +1880,17 @@ fn invoke_roc_function<'a, 'ctx, 'env>(
|
||||||
context.struct_type(&[exception_ptr, selector_value], false)
|
context.struct_type(&[exception_ptr, selector_value], false)
|
||||||
};
|
};
|
||||||
|
|
||||||
env.builder
|
let exception_object = env.builder.build_cleanup_landing_pad(
|
||||||
.build_catch_all_landing_pad(
|
&landing_pad_type,
|
||||||
&landing_pad_type,
|
&BasicValueEnum::IntValue(context.i8_type().const_zero()),
|
||||||
&BasicValueEnum::IntValue(context.i8_type().const_zero()),
|
context.i8_type().ptr_type(AddressSpace::Generic),
|
||||||
context.i8_type().ptr_type(AddressSpace::Generic),
|
"invoke_landing_pad",
|
||||||
"invoke_landing_pad",
|
);
|
||||||
)
|
|
||||||
.into_struct_value();
|
scope.insert(
|
||||||
|
exception_id.into_inner(),
|
||||||
|
(Layout::Struct(&[]), exception_object),
|
||||||
|
);
|
||||||
|
|
||||||
build_exp_stmt(env, layout_ids, scope, parent, fail);
|
build_exp_stmt(env, layout_ids, scope, parent, fail);
|
||||||
}
|
}
|
||||||
|
@ -1983,7 +1989,8 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
call,
|
call,
|
||||||
layout,
|
layout,
|
||||||
pass,
|
pass,
|
||||||
fail: roc_mono::ir::Stmt::Rethrow,
|
fail: roc_mono::ir::Stmt::Rethrow(_),
|
||||||
|
exception_id: _,
|
||||||
} => {
|
} => {
|
||||||
// when the fail case is just Rethrow, there is no cleanup work to do
|
// when the fail case is just Rethrow, there is no cleanup work to do
|
||||||
// so we can just treat this invoke as a normal call
|
// so we can just treat this invoke as a normal call
|
||||||
|
@ -1997,6 +2004,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
layout,
|
layout,
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
|
exception_id,
|
||||||
} => match call.call_type {
|
} => match call.call_type {
|
||||||
CallType::ByName {
|
CallType::ByName {
|
||||||
name,
|
name,
|
||||||
|
@ -2017,6 +2025,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
None,
|
None,
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
|
*exception_id,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2047,11 +2056,9 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Rethrow => {
|
Rethrow(exception_id) => {
|
||||||
cxa_rethrow_exception(env);
|
let exception_object = scope.get(&exception_id.into_inner()).unwrap().1;
|
||||||
|
env.builder.build_resume(&exception_object);
|
||||||
// used in exception handling
|
|
||||||
env.builder.build_unreachable();
|
|
||||||
|
|
||||||
env.context.i64_type().const_zero().into()
|
env.context.i64_type().const_zero().into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,7 @@ where
|
||||||
call,
|
call,
|
||||||
pass,
|
pass,
|
||||||
fail: _,
|
fail: _,
|
||||||
|
exception_id: _,
|
||||||
} => {
|
} => {
|
||||||
// for now, treat invoke as a normal call
|
// for now, treat invoke as a normal call
|
||||||
self.build_expr(symbol, &Expr::Call(call.clone()), layout)?;
|
self.build_expr(symbol, &Expr::Call(call.clone()), layout)?;
|
||||||
|
@ -486,6 +487,7 @@ where
|
||||||
call,
|
call,
|
||||||
pass,
|
pass,
|
||||||
fail: _,
|
fail: _,
|
||||||
|
exception_id: _,
|
||||||
} => {
|
} => {
|
||||||
// for now, treat invoke as a normal call
|
// for now, treat invoke as a normal call
|
||||||
self.set_last_seen(*symbol, stmt);
|
self.set_last_seen(*symbol, stmt);
|
||||||
|
@ -508,7 +510,7 @@ where
|
||||||
Stmt::Ret(sym) => {
|
Stmt::Ret(sym) => {
|
||||||
self.set_last_seen(*sym, stmt);
|
self.set_last_seen(*sym, stmt);
|
||||||
}
|
}
|
||||||
Stmt::Rethrow => {}
|
Stmt::Rethrow(_exception_id) => {}
|
||||||
Stmt::Refcounting(modify, following) => {
|
Stmt::Refcounting(modify, following) => {
|
||||||
let sym = modify.get_symbol();
|
let sym = modify.get_symbol();
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ fn stmt_spec(
|
||||||
layout: call_layout,
|
layout: call_layout,
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
|
exception_id: _,
|
||||||
} => {
|
} => {
|
||||||
// a call that might throw an exception
|
// a call that might throw an exception
|
||||||
|
|
||||||
|
@ -208,7 +209,7 @@ fn stmt_spec(
|
||||||
let jpid = env.join_points[id];
|
let jpid = env.join_points[id];
|
||||||
builder.add_jump(block, jpid, argument, ret_type_id)
|
builder.add_jump(block, jpid, argument, ret_type_id)
|
||||||
}
|
}
|
||||||
Rethrow | RuntimeError(_) => {
|
Rethrow(_) | RuntimeError(_) => {
|
||||||
let type_id = layout_spec(builder, layout)?;
|
let type_id = layout_spec(builder, layout)?;
|
||||||
|
|
||||||
builder.add_terminate(block, type_id)
|
builder.add_terminate(block, type_id)
|
||||||
|
|
|
@ -220,7 +220,7 @@ impl<'a> ParamMap<'a> {
|
||||||
}
|
}
|
||||||
Refcounting(_, _) => unreachable!("these have not been introduced yet"),
|
Refcounting(_, _) => unreachable!("these have not been introduced yet"),
|
||||||
|
|
||||||
Ret(_) | Rethrow | Jump(_, _) | RuntimeError(_) => {
|
Ret(_) | Rethrow(_) | Jump(_, _) | RuntimeError(_) => {
|
||||||
// these are terminal, do nothing
|
// these are terminal, do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -641,6 +641,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
layout: _,
|
layout: _,
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
|
exception_id: _,
|
||||||
} => {
|
} => {
|
||||||
self.collect_stmt(pass);
|
self.collect_stmt(pass);
|
||||||
self.collect_stmt(fail);
|
self.collect_stmt(fail);
|
||||||
|
@ -672,7 +673,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
}
|
}
|
||||||
Refcounting(_, _) => unreachable!("these have not been introduced yet"),
|
Refcounting(_, _) => unreachable!("these have not been introduced yet"),
|
||||||
|
|
||||||
Ret(_) | RuntimeError(_) | Rethrow => {
|
Ret(_) | RuntimeError(_) | Rethrow(_) => {
|
||||||
// these are terminal, do nothing
|
// these are terminal, do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -602,6 +602,7 @@ fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a Stmt<
|
||||||
layout,
|
layout,
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
|
exception_id,
|
||||||
} => {
|
} => {
|
||||||
let pass = expand_and_cancel(env, pass);
|
let pass = expand_and_cancel(env, pass);
|
||||||
let fail = expand_and_cancel(env, fail);
|
let fail = expand_and_cancel(env, fail);
|
||||||
|
@ -612,6 +613,7 @@ fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a Stmt<
|
||||||
layout: *layout,
|
layout: *layout,
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
|
exception_id: *exception_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
env.arena.alloc(stmt)
|
env.arena.alloc(stmt)
|
||||||
|
@ -636,7 +638,7 @@ fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a Stmt<
|
||||||
env.arena.alloc(stmt)
|
env.arena.alloc(stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
Rethrow | Ret(_) | Jump(_, _) | RuntimeError(_) => stmt,
|
Rethrow(_) | Ret(_) | Jump(_, _) | RuntimeError(_) => stmt,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub fn occuring_variables(stmt: &Stmt<'_>) -> (MutSet<Symbol>, MutSet<Symbol>) {
|
||||||
result.insert(*symbol);
|
result.insert(*symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rethrow => {}
|
Rethrow(_) => {}
|
||||||
|
|
||||||
Refcounting(modify, cont) => {
|
Refcounting(modify, cont) => {
|
||||||
let symbol = modify.get_symbol();
|
let symbol = modify.get_symbol();
|
||||||
|
@ -892,6 +892,7 @@ impl<'a> Context<'a> {
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
layout,
|
layout,
|
||||||
|
exception_id,
|
||||||
} => {
|
} => {
|
||||||
// live vars of the whole expression
|
// live vars of the whole expression
|
||||||
let invoke_live_vars = collect_stmt(stmt, &self.jp_live_vars, MutSet::default());
|
let invoke_live_vars = collect_stmt(stmt, &self.jp_live_vars, MutSet::default());
|
||||||
|
@ -926,6 +927,7 @@ impl<'a> Context<'a> {
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
layout: *layout,
|
layout: *layout,
|
||||||
|
exception_id: *exception_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
let cont = self.arena.alloc(invoke);
|
let cont = self.arena.alloc(invoke);
|
||||||
|
@ -1009,7 +1011,7 @@ impl<'a> Context<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rethrow => (stmt, MutSet::default()),
|
Rethrow(_) => (stmt, MutSet::default()),
|
||||||
|
|
||||||
Jump(j, xs) => {
|
Jump(j, xs) => {
|
||||||
let empty = MutSet::default();
|
let empty = MutSet::default();
|
||||||
|
@ -1175,7 +1177,7 @@ pub fn collect_stmt(
|
||||||
vars
|
vars
|
||||||
}
|
}
|
||||||
|
|
||||||
Rethrow => vars,
|
Rethrow(_) => vars,
|
||||||
|
|
||||||
RuntimeError(_) => vars,
|
RuntimeError(_) => vars,
|
||||||
}
|
}
|
||||||
|
|
|
@ -855,6 +855,7 @@ pub enum Stmt<'a> {
|
||||||
layout: Layout<'a>,
|
layout: Layout<'a>,
|
||||||
pass: &'a Stmt<'a>,
|
pass: &'a Stmt<'a>,
|
||||||
fail: &'a Stmt<'a>,
|
fail: &'a Stmt<'a>,
|
||||||
|
exception_id: ExceptionId,
|
||||||
},
|
},
|
||||||
Switch {
|
Switch {
|
||||||
/// This *must* stand for an integer, because Switch potentially compiles to a jump table.
|
/// This *must* stand for an integer, because Switch potentially compiles to a jump table.
|
||||||
|
@ -869,7 +870,7 @@ pub enum Stmt<'a> {
|
||||||
ret_layout: Layout<'a>,
|
ret_layout: Layout<'a>,
|
||||||
},
|
},
|
||||||
Ret(Symbol),
|
Ret(Symbol),
|
||||||
Rethrow,
|
Rethrow(ExceptionId),
|
||||||
Refcounting(ModifyRc, &'a Stmt<'a>),
|
Refcounting(ModifyRc, &'a Stmt<'a>),
|
||||||
/// a join point `join f <params> = <continuation> in remainder`
|
/// a join point `join f <params> = <continuation> in remainder`
|
||||||
Join {
|
Join {
|
||||||
|
@ -1361,7 +1362,7 @@ impl<'a> Stmt<'a> {
|
||||||
symbol,
|
symbol,
|
||||||
call,
|
call,
|
||||||
pass,
|
pass,
|
||||||
fail: Stmt::Rethrow,
|
fail: Stmt::Rethrow(_),
|
||||||
..
|
..
|
||||||
} => alloc
|
} => alloc
|
||||||
.text("let ")
|
.text("let ")
|
||||||
|
@ -1394,7 +1395,7 @@ impl<'a> Stmt<'a> {
|
||||||
.append(symbol_to_doc(alloc, *symbol))
|
.append(symbol_to_doc(alloc, *symbol))
|
||||||
.append(";"),
|
.append(";"),
|
||||||
|
|
||||||
Rethrow => alloc.text("unreachable;"),
|
Rethrow(_) => alloc.text("unreachable;"),
|
||||||
|
|
||||||
Switch {
|
Switch {
|
||||||
cond_symbol,
|
cond_symbol,
|
||||||
|
@ -4684,12 +4685,14 @@ pub fn from_can<'a>(
|
||||||
arguments,
|
arguments,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let exception_id = ExceptionId(env.unique_symbol());
|
||||||
let rest = Stmt::Invoke {
|
let rest = Stmt::Invoke {
|
||||||
symbol: env.unique_symbol(),
|
symbol: env.unique_symbol(),
|
||||||
call,
|
call,
|
||||||
layout: bool_layout,
|
layout: bool_layout,
|
||||||
pass: env.arena.alloc(rest),
|
pass: env.arena.alloc(rest),
|
||||||
fail: env.arena.alloc(Stmt::Rethrow),
|
fail: env.arena.alloc(Stmt::Rethrow(exception_id)),
|
||||||
|
exception_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
with_hole(
|
with_hole(
|
||||||
|
@ -5271,6 +5274,7 @@ fn substitute_in_stmt_help<'a>(
|
||||||
layout,
|
layout,
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
|
exception_id,
|
||||||
} => {
|
} => {
|
||||||
let opt_call = substitute_in_call(arena, call, subs);
|
let opt_call = substitute_in_call(arena, call, subs);
|
||||||
let opt_pass = substitute_in_stmt_help(arena, pass, subs);
|
let opt_pass = substitute_in_stmt_help(arena, pass, subs);
|
||||||
|
@ -5287,6 +5291,7 @@ fn substitute_in_stmt_help<'a>(
|
||||||
layout: *layout,
|
layout: *layout,
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
|
exception_id: *exception_id,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -5406,7 +5411,7 @@ fn substitute_in_stmt_help<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rethrow => None,
|
Rethrow(_) => None,
|
||||||
|
|
||||||
RuntimeError(_) => None,
|
RuntimeError(_) => None,
|
||||||
}
|
}
|
||||||
|
@ -5909,7 +5914,7 @@ fn force_thunk<'a>(
|
||||||
arguments: &[],
|
arguments: &[],
|
||||||
};
|
};
|
||||||
|
|
||||||
Stmt::Let(assigned, Expr::Call(call), layout, env.arena.alloc(hole))
|
build_call(env, call, assigned, layout, env.arena.alloc(hole))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn let_empty_struct<'a>(assigned: Symbol, hole: &'a Stmt<'a>) -> Stmt<'a> {
|
fn let_empty_struct<'a>(assigned: Symbol, hole: &'a Stmt<'a>) -> Stmt<'a> {
|
||||||
|
@ -6160,6 +6165,18 @@ fn can_throw_exception(call: &Call) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Symbol that links an Invoke with a Rethrow
|
||||||
|
/// we'll assign the exception object to this symbol
|
||||||
|
/// so we can later rethrow the exception
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
pub struct ExceptionId(Symbol);
|
||||||
|
|
||||||
|
impl ExceptionId {
|
||||||
|
pub fn into_inner(self) -> Symbol {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn build_call<'a>(
|
fn build_call<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
call: Call<'a>,
|
call: Call<'a>,
|
||||||
|
@ -6168,13 +6185,15 @@ fn build_call<'a>(
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
if can_throw_exception(&call) {
|
if can_throw_exception(&call) {
|
||||||
let fail = env.arena.alloc(Stmt::Rethrow);
|
let id = ExceptionId(env.unique_symbol());
|
||||||
|
let fail = env.arena.alloc(Stmt::Rethrow(id));
|
||||||
Stmt::Invoke {
|
Stmt::Invoke {
|
||||||
symbol: assigned,
|
symbol: assigned,
|
||||||
call,
|
call,
|
||||||
layout,
|
layout,
|
||||||
fail,
|
fail,
|
||||||
pass: hole,
|
pass: hole,
|
||||||
|
exception_id: id,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Stmt::Let(assigned, Expr::Call(call), layout, hole)
|
Stmt::Let(assigned, Expr::Call(call), layout, hole)
|
||||||
|
@ -7693,17 +7712,9 @@ where
|
||||||
Layout::Struct(_) => {
|
Layout::Struct(_) => {
|
||||||
let function_symbol = lambda_set.set[0].0;
|
let function_symbol = lambda_set.set[0].0;
|
||||||
|
|
||||||
// build the call
|
let call = to_lowlevel_call(function_symbol, closure_data_symbol, function_layout);
|
||||||
Stmt::Let(
|
|
||||||
assigned,
|
build_call(env, call, assigned, return_layout, env.arena.alloc(hole))
|
||||||
Expr::Call(to_lowlevel_call(
|
|
||||||
function_symbol,
|
|
||||||
closure_data_symbol,
|
|
||||||
function_layout,
|
|
||||||
)),
|
|
||||||
return_layout,
|
|
||||||
env.arena.alloc(hole),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Layout::Builtin(Builtin::Int1) => {
|
Layout::Builtin(Builtin::Int1) => {
|
||||||
let closure_tag_id_symbol = closure_data_symbol;
|
let closure_tag_id_symbol = closure_data_symbol;
|
||||||
|
@ -7768,17 +7779,8 @@ where
|
||||||
|
|
||||||
let hole = Stmt::Jump(join_point_id, env.arena.alloc([assigned]));
|
let hole = Stmt::Jump(join_point_id, env.arena.alloc([assigned]));
|
||||||
|
|
||||||
// build the call
|
let call = to_lowlevel_call(*function_symbol, closure_data_symbol, function_layout);
|
||||||
let stmt = Stmt::Let(
|
let stmt = build_call(env, call, assigned, return_layout, env.arena.alloc(hole));
|
||||||
assigned,
|
|
||||||
Expr::Call(to_lowlevel_call(
|
|
||||||
*function_symbol,
|
|
||||||
closure_data_symbol,
|
|
||||||
function_layout,
|
|
||||||
)),
|
|
||||||
return_layout,
|
|
||||||
env.arena.alloc(hole),
|
|
||||||
);
|
|
||||||
|
|
||||||
branches.push((i as u64, BranchInfo::None, stmt));
|
branches.push((i as u64, BranchInfo::None, stmt));
|
||||||
}
|
}
|
||||||
|
@ -8036,21 +8038,18 @@ fn union_lambda_set_branch_help<'a>(
|
||||||
let full_layout = Layout::FunctionPointer(argument_layouts, env.arena.alloc(return_layout));
|
let full_layout = Layout::FunctionPointer(argument_layouts, env.arena.alloc(return_layout));
|
||||||
|
|
||||||
// build the call
|
// build the call
|
||||||
Stmt::Let(
|
let call = self::Call {
|
||||||
assigned,
|
call_type: CallType::ByName {
|
||||||
Expr::Call(self::Call {
|
name: function_symbol,
|
||||||
call_type: CallType::ByName {
|
full_layout,
|
||||||
name: function_symbol,
|
ret_layout: return_layout,
|
||||||
full_layout,
|
arg_layouts: argument_layouts,
|
||||||
ret_layout: return_layout,
|
specialization_id: env.next_call_specialization_id(),
|
||||||
arg_layouts: argument_layouts,
|
},
|
||||||
specialization_id: env.next_call_specialization_id(),
|
arguments: argument_symbols,
|
||||||
},
|
};
|
||||||
arguments: argument_symbols,
|
|
||||||
}),
|
build_call(env, call, assigned, return_layout, hole)
|
||||||
return_layout,
|
|
||||||
hole,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
@ -8159,22 +8158,17 @@ fn enum_lambda_set_branch<'a>(
|
||||||
|
|
||||||
let full_layout = Layout::FunctionPointer(argument_layouts, env.arena.alloc(return_layout));
|
let full_layout = Layout::FunctionPointer(argument_layouts, env.arena.alloc(return_layout));
|
||||||
|
|
||||||
// build the call
|
let call = self::Call {
|
||||||
Stmt::Let(
|
call_type: CallType::ByName {
|
||||||
assigned,
|
name: function_symbol,
|
||||||
Expr::Call(self::Call {
|
full_layout,
|
||||||
call_type: CallType::ByName {
|
ret_layout: return_layout,
|
||||||
name: function_symbol,
|
arg_layouts: argument_layouts,
|
||||||
full_layout,
|
specialization_id: env.next_call_specialization_id(),
|
||||||
ret_layout: return_layout,
|
},
|
||||||
arg_layouts: argument_layouts,
|
arguments: argument_symbols,
|
||||||
specialization_id: env.next_call_specialization_id(),
|
};
|
||||||
},
|
build_call(env, call, assigned, return_layout, env.arena.alloc(hole))
|
||||||
arguments: argument_symbols,
|
|
||||||
}),
|
|
||||||
return_layout,
|
|
||||||
env.arena.alloc(hole),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
@ -8204,14 +8198,11 @@ where
|
||||||
|
|
||||||
let hole = Stmt::Jump(join_point_id, env.arena.alloc([result_symbol]));
|
let hole = Stmt::Jump(join_point_id, env.arena.alloc([result_symbol]));
|
||||||
|
|
||||||
// build the call
|
let call = to_lowlevel_call(*function_symbol, closure_data_symbol, function_layout);
|
||||||
let stmt = Stmt::Let(
|
let stmt = build_call(
|
||||||
|
env,
|
||||||
|
call,
|
||||||
result_symbol,
|
result_symbol,
|
||||||
Expr::Call(to_lowlevel_call(
|
|
||||||
*function_symbol,
|
|
||||||
closure_data_symbol,
|
|
||||||
function_layout,
|
|
||||||
)),
|
|
||||||
return_layout,
|
return_layout,
|
||||||
env.arena.alloc(hole),
|
env.arena.alloc(hole),
|
||||||
);
|
);
|
||||||
|
|
|
@ -102,9 +102,10 @@ fn insert_jumps<'a>(
|
||||||
},
|
},
|
||||||
fail,
|
fail,
|
||||||
pass: Stmt::Ret(rsym),
|
pass: Stmt::Ret(rsym),
|
||||||
|
exception_id,
|
||||||
..
|
..
|
||||||
} if needle == *fsym && symbol == rsym => {
|
} if needle == *fsym && symbol == rsym => {
|
||||||
debug_assert_eq!(fail, &&Stmt::Rethrow);
|
debug_assert_eq!(fail, &&Stmt::Rethrow(*exception_id));
|
||||||
|
|
||||||
// replace the call and return with a jump
|
// replace the call and return with a jump
|
||||||
|
|
||||||
|
@ -131,6 +132,7 @@ fn insert_jumps<'a>(
|
||||||
fail,
|
fail,
|
||||||
pass,
|
pass,
|
||||||
layout,
|
layout,
|
||||||
|
exception_id,
|
||||||
} => {
|
} => {
|
||||||
let opt_pass = insert_jumps(arena, pass, goal_id, needle);
|
let opt_pass = insert_jumps(arena, pass, goal_id, needle);
|
||||||
let opt_fail = insert_jumps(arena, fail, goal_id, needle);
|
let opt_fail = insert_jumps(arena, fail, goal_id, needle);
|
||||||
|
@ -145,6 +147,7 @@ fn insert_jumps<'a>(
|
||||||
layout: *layout,
|
layout: *layout,
|
||||||
pass,
|
pass,
|
||||||
fail,
|
fail,
|
||||||
|
exception_id: *exception_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(arena.alloc(stmt))
|
Some(arena.alloc(stmt))
|
||||||
|
@ -238,7 +241,7 @@ fn insert_jumps<'a>(
|
||||||
None => None,
|
None => None,
|
||||||
},
|
},
|
||||||
|
|
||||||
Rethrow => None,
|
Rethrow(_) => None,
|
||||||
Ret(_) => None,
|
Ret(_) => None,
|
||||||
Jump(_, _) => None,
|
Jump(_, _) => None,
|
||||||
RuntimeError(_) => None,
|
RuntimeError(_) => None,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue