mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
WIP
This commit is contained in:
parent
10aa4f58c9
commit
e7f9ff8b51
1 changed files with 140 additions and 32 deletions
|
@ -1,13 +1,14 @@
|
||||||
use bumpalo::collections::vec::Vec;
|
use bumpalo::collections::vec::Vec;
|
||||||
use bumpalo::collections::CollectIn;
|
use bumpalo::collections::CollectIn;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
use roc_can::abilities::SpecializationId;
|
||||||
use roc_module::low_level::LowLevel;
|
use roc_module::low_level::LowLevel;
|
||||||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||||
use roc_target::TargetInfo;
|
use roc_target::TargetInfo;
|
||||||
|
|
||||||
use crate::ir::{
|
use crate::ir::{
|
||||||
Call, CallSpecId, CallType, Expr, HostExposedLayouts, JoinPointId, Literal, ModifyRc,
|
BranchInfo, Call, CallSpecId, CallType, Expr, HostExposedLayouts, JoinPointId, Literal,
|
||||||
PassedFunction, Proc, ProcLayout, SelfRecursive, Stmt, UpdateModeId,
|
ModifyRc, PassedFunction, Proc, ProcLayout, SelfRecursive, Stmt, UpdateModeId,
|
||||||
};
|
};
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
Builtin, InLayout, LambdaName, Layout, LayoutInterner, LayoutRepr, LayoutWrapper, Niche,
|
Builtin, InLayout, LambdaName, Layout, LayoutInterner, LayoutRepr, LayoutWrapper, Niche,
|
||||||
|
@ -850,27 +851,45 @@ fn layout_needs_helper_proc<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_helper<'a>(
|
fn test_helper<'a>(
|
||||||
arena: &'a Bump,
|
env: &CodeGenHelp<'a>,
|
||||||
layout_interner: &STLayoutInterner<'a>,
|
ident_ids: &mut IdentIds,
|
||||||
|
layout_interner: &mut STLayoutInterner<'a>,
|
||||||
main_proc: &Proc<'a>,
|
main_proc: &Proc<'a>,
|
||||||
) -> Proc<'a> {
|
) -> Proc<'a> {
|
||||||
|
let it = (0..main_proc.args.len()).map(|i| env.create_symbol(ident_ids, &format!("arg_{i}")));
|
||||||
|
let arguments = Vec::from_iter_in(it, env.arena).into_bump_slice();
|
||||||
|
|
||||||
|
let it = arguments
|
||||||
|
.iter()
|
||||||
|
.zip(main_proc.args.iter())
|
||||||
|
.map(|(s, (l, _))| (*l, *s));
|
||||||
|
let args = Vec::from_iter_in(it, env.arena).into_bump_slice();
|
||||||
|
|
||||||
|
let body = test_helper_body(env, ident_ids, layout_interner, main_proc, arguments);
|
||||||
|
|
||||||
|
let name = LambdaName::no_niche(env.create_symbol(ident_ids, "test_main"));
|
||||||
|
|
||||||
Proc {
|
Proc {
|
||||||
name: (),
|
name,
|
||||||
args: (),
|
args,
|
||||||
body: (),
|
body,
|
||||||
closure_data_layout: (),
|
closure_data_layout: None,
|
||||||
ret_layout: (),
|
ret_layout: main_proc.ret_layout,
|
||||||
is_self_recursive: (),
|
is_self_recursive: main_proc.is_self_recursive,
|
||||||
host_exposed_layouts: (),
|
host_exposed_layouts: HostExposedLayouts::HostExposed {
|
||||||
is_erased: (),
|
rigids: Default::default(),
|
||||||
|
aliases: Default::default(),
|
||||||
|
},
|
||||||
|
is_erased: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_helper_body<'a>(
|
fn test_helper_body<'a>(
|
||||||
env: &CodeGenHelp,
|
env: &CodeGenHelp<'a>,
|
||||||
ident_ids: &mut IdentIds,
|
ident_ids: &mut IdentIds,
|
||||||
layout_interner: &STLayoutInterner<'a>,
|
layout_interner: &mut STLayoutInterner<'a>,
|
||||||
main_proc: &Proc<'a>,
|
main_proc: &Proc<'a>,
|
||||||
|
arguments: &'a [Symbol],
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
// let buffer = SetLongJmpBuffer
|
// let buffer = SetLongJmpBuffer
|
||||||
let buffer_symbol = env.create_symbol(ident_ids, "buffer");
|
let buffer_symbol = env.create_symbol(ident_ids, "buffer");
|
||||||
|
@ -896,24 +915,26 @@ fn test_helper_body<'a>(
|
||||||
// tag: u64,
|
// tag: u64,
|
||||||
// error_msg: *mut RocStr,
|
// error_msg: *mut RocStr,
|
||||||
// value: MaybeUninit<T>,
|
// value: MaybeUninit<T>,
|
||||||
let repr =
|
let fields = [Layout::U64, Layout::U64, main_proc.ret_layout];
|
||||||
LayoutRepr::Struct(
|
let repr = LayoutRepr::Struct(env.arena.alloc(fields));
|
||||||
env.arena
|
|
||||||
.alloc([Layout::U64, Layout::U64, main_proc.ret_layout]),
|
|
||||||
);
|
|
||||||
let return_layout = layout_interner.insert_direct_no_semantic(repr);
|
let return_layout = layout_interner.insert_direct_no_semantic(repr);
|
||||||
|
|
||||||
// normal path, no panics
|
// normal path, no panics
|
||||||
let else_branch_stmt = {
|
let if_zero_stmt = {
|
||||||
let result_symbol = Expr::Call(Call {
|
let it = main_proc.args.iter().map(|(a, _)| *a);
|
||||||
|
let arg_layouts = Vec::from_iter_in(it, env.arena).into_bump_slice();
|
||||||
|
|
||||||
|
let result_symbol = env.create_symbol(ident_ids, "result");
|
||||||
|
let result_expr = Expr::Call(Call {
|
||||||
call_type: CallType::ByName {
|
call_type: CallType::ByName {
|
||||||
name: (),
|
name: main_proc.name,
|
||||||
ret_layout: (),
|
ret_layout: main_proc.ret_layout,
|
||||||
arg_layouts: (),
|
arg_layouts,
|
||||||
specialization_id: (),
|
specialization_id: CallSpecId::BACKEND_DUMMY,
|
||||||
},
|
},
|
||||||
arguments: proc_arguments,
|
arguments,
|
||||||
});
|
});
|
||||||
|
let result = |next| Stmt::Let(result_symbol, result_expr, main_proc.ret_layout, next);
|
||||||
|
|
||||||
let ok_tag_symbol = env.create_symbol(ident_ids, "ok_tag");
|
let ok_tag_symbol = env.create_symbol(ident_ids, "ok_tag");
|
||||||
let ok_tag_expr = Expr::Literal(Literal::Int((0 as i128).to_be_bytes()));
|
let ok_tag_expr = Expr::Literal(Literal::Int((0 as i128).to_be_bytes()));
|
||||||
|
@ -922,19 +943,106 @@ fn test_helper_body<'a>(
|
||||||
let msg_ptr_symbol = env.create_symbol(ident_ids, "msg_ptr");
|
let msg_ptr_symbol = env.create_symbol(ident_ids, "msg_ptr");
|
||||||
let msg_ptr_expr = Expr::Literal(Literal::Int((0 as i128).to_be_bytes()));
|
let msg_ptr_expr = Expr::Literal(Literal::Int((0 as i128).to_be_bytes()));
|
||||||
let msg_ptr = |next| Stmt::Let(msg_ptr_symbol, msg_ptr_expr, Layout::U64, next);
|
let msg_ptr = |next| Stmt::Let(msg_ptr_symbol, msg_ptr_expr, Layout::U64, next);
|
||||||
|
|
||||||
|
// construct the record
|
||||||
|
let output_symbol = env.create_symbol(ident_ids, "output");
|
||||||
|
let fields = [ok_tag_symbol, msg_ptr_symbol, result_symbol];
|
||||||
|
let output_expr = Expr::Struct(env.arena.alloc(fields));
|
||||||
|
let output = |next| Stmt::Let(output_symbol, output_expr, Layout::U64, next);
|
||||||
|
|
||||||
|
let arena = env.arena;
|
||||||
|
result(arena.alloc(
|
||||||
|
//
|
||||||
|
ok_tag(arena.alloc(
|
||||||
|
//
|
||||||
|
msg_ptr(arena.alloc(
|
||||||
|
//
|
||||||
|
output(arena.alloc(
|
||||||
|
//
|
||||||
|
Stmt::Ret(output_symbol),
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
// a longjmp/panic occured
|
// a longjmp/panic occured
|
||||||
let then_branch_stmt = {
|
let if_nonzero_stmt = {
|
||||||
//
|
let alloca_symbol = env.create_symbol(ident_ids, "alloca");
|
||||||
todo!()
|
let alloca_expr = Expr::Alloca {
|
||||||
|
element_layout: main_proc.ret_layout,
|
||||||
|
initializer: None,
|
||||||
|
};
|
||||||
|
let alloca = |next| Stmt::Let(alloca_symbol, alloca_expr, Layout::U64, next);
|
||||||
|
|
||||||
|
let load_symbol = env.create_symbol(ident_ids, "load");
|
||||||
|
let load_expr = Expr::Call(Call {
|
||||||
|
call_type: CallType::LowLevel {
|
||||||
|
op: LowLevel::PtrLoad,
|
||||||
|
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||||
|
},
|
||||||
|
arguments: &[alloca_symbol],
|
||||||
|
});
|
||||||
|
let load = |next| Stmt::Let(load_symbol, load_expr, Layout::U64, next);
|
||||||
|
|
||||||
|
// is_longjmp_symbol will the pointer to the error message
|
||||||
|
let ok_tag_symbol = env.create_symbol(ident_ids, "ok_tag");
|
||||||
|
let ok_tag_expr = Expr::Literal(Literal::Int((0 as i128).to_be_bytes()));
|
||||||
|
let ok_tag = |next| Stmt::Let(ok_tag_symbol, ok_tag_expr, Layout::U64, next);
|
||||||
|
|
||||||
|
let msg_ptr_symbol = env.create_symbol(ident_ids, "msg_ptr");
|
||||||
|
let msg_ptr_expr = Expr::Literal(Literal::Int((0 as i128).to_be_bytes()));
|
||||||
|
let msg_ptr = |next| Stmt::Let(msg_ptr_symbol, msg_ptr_expr, Layout::U64, next);
|
||||||
|
|
||||||
|
// construct the record
|
||||||
|
let output_symbol = env.create_symbol(ident_ids, "output");
|
||||||
|
let fields = [ok_tag_symbol, msg_ptr_symbol, load_symbol];
|
||||||
|
let output_expr = Expr::Struct(env.arena.alloc(fields));
|
||||||
|
let output = |next| Stmt::Let(output_symbol, output_expr, Layout::U64, next);
|
||||||
|
|
||||||
|
let arena = env.arena;
|
||||||
|
arena.alloc(alloca(arena.alloc(
|
||||||
|
//
|
||||||
|
load(arena.alloc(
|
||||||
|
//
|
||||||
|
ok_tag(arena.alloc(
|
||||||
|
//
|
||||||
|
msg_ptr(arena.alloc(
|
||||||
|
//
|
||||||
|
output(arena.alloc(
|
||||||
|
//
|
||||||
|
Stmt::Ret(output_symbol),
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
)))
|
||||||
};
|
};
|
||||||
|
|
||||||
Stmt::if_then_else(
|
switch_if_zero_else(
|
||||||
env.arena,
|
env.arena,
|
||||||
is_longjmp_symbol,
|
is_longjmp_symbol,
|
||||||
return_layout,
|
return_layout,
|
||||||
then_branch_stmt,
|
if_zero_stmt,
|
||||||
else_branch_stmt,
|
if_nonzero_stmt,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn switch_if_zero_else<'a>(
|
||||||
|
arena: &'a Bump,
|
||||||
|
condition_symbol: Symbol,
|
||||||
|
return_layout: InLayout<'a>,
|
||||||
|
then_branch_stmt: Stmt<'a>,
|
||||||
|
else_branch_stmt: &'a Stmt<'a>,
|
||||||
|
) -> Stmt<'a> {
|
||||||
|
let then_branch = (0u64, BranchInfo::None, then_branch_stmt);
|
||||||
|
let else_branch = (BranchInfo::None, else_branch_stmt);
|
||||||
|
|
||||||
|
Stmt::Switch {
|
||||||
|
cond_symbol: condition_symbol,
|
||||||
|
cond_layout: Layout::U64,
|
||||||
|
branches: &*arena.alloc([then_branch]),
|
||||||
|
default_branch: else_branch,
|
||||||
|
ret_layout: return_layout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue