mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
codegen getters
This commit is contained in:
parent
5ae4ccad5e
commit
19a8b95c42
2 changed files with 70 additions and 13 deletions
|
@ -4371,17 +4371,62 @@ pub fn build_procedures<'a, 'ctx, 'env>(
|
|||
env: &Env<'a, 'ctx, 'env>,
|
||||
opt_level: OptLevel,
|
||||
procedures: MutMap<(Symbol, ProcLayout<'a>), roc_mono::ir::Proc<'a>>,
|
||||
_glue_layouts: &GlueLayouts<'a>,
|
||||
glue_layouts: &GlueLayouts<'a>,
|
||||
opt_entry_point: Option<EntryPoint<'a>>,
|
||||
debug_output_file: Option<&Path>,
|
||||
) {
|
||||
build_procedures_help(
|
||||
let mod_solutions = build_procedures_help(
|
||||
env,
|
||||
opt_level,
|
||||
procedures,
|
||||
opt_entry_point,
|
||||
debug_output_file,
|
||||
);
|
||||
|
||||
let captures_niche = CapturesNiche::no_niche();
|
||||
|
||||
let mut getter_names = Vec::with_capacity_in(glue_layouts.getters.len(), env.arena);
|
||||
|
||||
for (symbol, top_level) in glue_layouts.getters.iter().copied() {
|
||||
let it = top_level.arguments.iter().copied();
|
||||
let bytes =
|
||||
roc_alias_analysis::func_name_bytes_help(symbol, it, captures_niche, &top_level.result);
|
||||
let func_name = FuncName(&bytes);
|
||||
let func_solutions = mod_solutions.func_solutions(func_name).unwrap();
|
||||
|
||||
let mut it = func_solutions.specs();
|
||||
let func_spec = it.next().unwrap();
|
||||
debug_assert!(
|
||||
it.next().is_none(),
|
||||
"we expect only one specialization of this symbol"
|
||||
);
|
||||
|
||||
// NOTE fake layout; it is only used for debug prints
|
||||
let roc_main_fn = function_value_by_func_spec(
|
||||
env,
|
||||
*func_spec,
|
||||
symbol,
|
||||
&[],
|
||||
captures_niche,
|
||||
&Layout::UNIT,
|
||||
);
|
||||
|
||||
let name = roc_main_fn.get_name().to_str().unwrap();
|
||||
|
||||
let getter_name = &format!("Getter{}", name);
|
||||
let getter_name = env.arena.alloc_str(getter_name);
|
||||
getter_names.push(&*getter_name);
|
||||
|
||||
// Add main to the module.
|
||||
let _ = expose_function_to_host_help_c_abi(
|
||||
env,
|
||||
name,
|
||||
roc_main_fn,
|
||||
top_level.arguments,
|
||||
top_level.result,
|
||||
getter_name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_wasm_test_wrapper<'a, 'ctx, 'env>(
|
||||
|
|
|
@ -10891,37 +10891,49 @@ fn generate_glue_procs_for_fields<'a>(
|
|||
home: ModuleId,
|
||||
ident_ids: &mut IdentIds,
|
||||
arena: &'a Bump,
|
||||
struct_layout: Layout<'a>,
|
||||
unboxed_struct_layout: Layout<'a>,
|
||||
field_layouts: &'a [Layout<'a>],
|
||||
output: &mut Vec<'a, ((Symbol, ProcLayout<'a>), Proc<'a>)>,
|
||||
) {
|
||||
output.reserve(field_layouts.len());
|
||||
|
||||
let boxed_struct_layout = Layout::Boxed(arena.alloc(unboxed_struct_layout));
|
||||
|
||||
for (index, field) in field_layouts.iter().enumerate() {
|
||||
let symbol = Symbol::new(home, ident_ids.gen_unique());
|
||||
let argument = Symbol::new(home, ident_ids.gen_unique());
|
||||
let unboxed = Symbol::new(home, ident_ids.gen_unique());
|
||||
let result = Symbol::new(home, ident_ids.gen_unique());
|
||||
|
||||
let proc_layout = ProcLayout {
|
||||
arguments: arena.alloc([struct_layout]),
|
||||
arguments: arena.alloc([boxed_struct_layout]),
|
||||
result: *field,
|
||||
captures_niche: CapturesNiche::no_niche(),
|
||||
};
|
||||
|
||||
let expr = Expr::StructAtIndex {
|
||||
index: index as u64,
|
||||
field_layouts,
|
||||
structure: argument,
|
||||
};
|
||||
|
||||
let ret_stmt = arena.alloc(Stmt::Ret(result));
|
||||
|
||||
let body = Stmt::Let(result, expr, *field, ret_stmt);
|
||||
let field_get_expr = Expr::StructAtIndex {
|
||||
index: index as u64,
|
||||
field_layouts,
|
||||
structure: unboxed,
|
||||
};
|
||||
|
||||
let field_get_stmt = Stmt::Let(result, field_get_expr, *field, ret_stmt);
|
||||
|
||||
let unbox_expr = Expr::ExprUnbox { symbol: argument };
|
||||
|
||||
let unbox_stmt = Stmt::Let(
|
||||
unboxed,
|
||||
unbox_expr,
|
||||
unboxed_struct_layout,
|
||||
arena.alloc(field_get_stmt),
|
||||
);
|
||||
|
||||
let proc = Proc {
|
||||
name: LambdaName::no_niche(symbol),
|
||||
args: arena.alloc([(struct_layout, argument)]),
|
||||
body,
|
||||
args: arena.alloc([(boxed_struct_layout, argument)]),
|
||||
body: unbox_stmt,
|
||||
closure_data_layout: None,
|
||||
ret_layout: *field,
|
||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue