mirror of
https://github.com/roc-lang/roc.git
synced 2024-10-04 14:17:28 +03:00
generate elem refcount function and pass it into decref lowlevel
This commit is contained in:
parent
516afaff41
commit
ba9b15f7d6
@ -2102,6 +2102,17 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||||||
self.register_helper_proc(spec_sym, spec_layout, ProcSource::Helper);
|
self.register_helper_proc(spec_sym, spec_layout, ProcSource::Helper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.get_existing_refcount_fn_index(proc_symbol, layout, op)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return a pointer (table index) to a refcount helper procedure.
|
||||||
|
/// This allows it to be indirectly called from Zig code
|
||||||
|
pub fn get_existing_refcount_fn_index(
|
||||||
|
&mut self,
|
||||||
|
proc_symbol: Symbol,
|
||||||
|
layout: InLayout<'a>,
|
||||||
|
op: HelperOp,
|
||||||
|
) -> u32 {
|
||||||
let layout_repr = if op.is_indirect() {
|
let layout_repr = if op.is_indirect() {
|
||||||
LayoutRepr::Ptr(layout)
|
LayoutRepr::Ptr(layout)
|
||||||
} else {
|
} else {
|
||||||
|
@ -341,6 +341,8 @@ impl<'a> LowLevelCall<'a> {
|
|||||||
|
|
||||||
ListDecref => {
|
ListDecref => {
|
||||||
let input_list: Symbol = self.arguments[0];
|
let input_list: Symbol = self.arguments[0];
|
||||||
|
let dec_fn_sym = self.arguments[1];
|
||||||
|
|
||||||
let list_layout = backend
|
let list_layout = backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.get_repr(backend.storage.symbol_layouts[&input_list]);
|
.get_repr(backend.storage.symbol_layouts[&input_list]);
|
||||||
@ -350,8 +352,12 @@ impl<'a> LowLevelCall<'a> {
|
|||||||
elem_layout.stack_size_and_alignment(backend.layout_interner);
|
elem_layout.stack_size_and_alignment(backend.layout_interner);
|
||||||
|
|
||||||
let elem_refcounted = backend.layout_interner.contains_refcounted(elem_in_layout);
|
let elem_refcounted = backend.layout_interner.contains_refcounted(elem_in_layout);
|
||||||
let dec_fn_ptr =
|
let dec_fn = backend.get_existing_refcount_fn_index(
|
||||||
build_refcount_element_fn(backend, elem_in_layout, HelperOp::IndirectDec);
|
dec_fn_sym,
|
||||||
|
elem_in_layout,
|
||||||
|
HelperOp::IndirectDec,
|
||||||
|
);
|
||||||
|
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
||||||
|
|
||||||
// Zig arguments Wasm types
|
// Zig arguments Wasm types
|
||||||
// input_list: &RocList i32
|
// input_list: &RocList i32
|
||||||
@ -2998,11 +3004,6 @@ fn build_refcount_element_fn<'a>(
|
|||||||
elem_layout: InLayout<'a>,
|
elem_layout: InLayout<'a>,
|
||||||
rc_op: HelperOp,
|
rc_op: HelperOp,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
// The refcount function receives a pointer to an element in the list
|
let rc_fn = backend.get_refcount_fn_index(elem_layout, rc_op);
|
||||||
// This is the same as a Struct containing the element
|
|
||||||
let in_memory_layout = backend
|
|
||||||
.layout_interner
|
|
||||||
.insert_direct_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([elem_layout])));
|
|
||||||
let rc_fn = backend.get_refcount_fn_index(in_memory_layout, rc_op);
|
|
||||||
backend.get_fn_ptr(rc_fn)
|
backend.get_fn_ptr(rc_fn)
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,14 @@ pub fn refcount_generic<'a>(
|
|||||||
rc_return_stmt(root, ident_ids, ctx)
|
rc_return_stmt(root, ident_ids, ctx)
|
||||||
}
|
}
|
||||||
LayoutRepr::Builtin(Builtin::Str) => refcount_str(root, ident_ids, ctx),
|
LayoutRepr::Builtin(Builtin::Str) => refcount_str(root, ident_ids, ctx),
|
||||||
LayoutRepr::Builtin(Builtin::List(_)) => refcount_list(root, ident_ids, ctx, structure),
|
LayoutRepr::Builtin(Builtin::List(element_layout)) => refcount_list(
|
||||||
|
root,
|
||||||
|
ident_ids,
|
||||||
|
ctx,
|
||||||
|
layout_interner,
|
||||||
|
element_layout,
|
||||||
|
structure,
|
||||||
|
),
|
||||||
LayoutRepr::Struct(field_layouts) => refcount_struct(
|
LayoutRepr::Struct(field_layouts) => refcount_struct(
|
||||||
root,
|
root,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
@ -945,6 +952,8 @@ fn refcount_list<'a>(
|
|||||||
root: &mut CodeGenHelp<'a>,
|
root: &mut CodeGenHelp<'a>,
|
||||||
ident_ids: &mut IdentIds,
|
ident_ids: &mut IdentIds,
|
||||||
ctx: &mut Context<'a>,
|
ctx: &mut Context<'a>,
|
||||||
|
layout_interner: &mut STLayoutInterner<'a>,
|
||||||
|
element_layout: InLayout<'a>,
|
||||||
_structure: Symbol,
|
_structure: Symbol,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
let arena = root.arena;
|
let arena = root.arena;
|
||||||
@ -964,13 +973,19 @@ fn refcount_list<'a>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
HelperOp::DecRef(_) | HelperOp::Dec => {
|
HelperOp::DecRef(_) | HelperOp::Dec => {
|
||||||
let rc_list_args = refcount_args(root, ctx, list);
|
let (rc_sym, linker_data) = root.gen_refcount_proc(
|
||||||
|
ident_ids,
|
||||||
|
layout_interner,
|
||||||
|
element_layout,
|
||||||
|
HelperOp::IndirectDec,
|
||||||
|
);
|
||||||
|
ctx.new_linker_data.extend_from_slice(&linker_data);
|
||||||
Expr::Call(Call {
|
Expr::Call(Call {
|
||||||
call_type: CallType::LowLevel {
|
call_type: CallType::LowLevel {
|
||||||
op: LowLevel::ListDecref,
|
op: LowLevel::ListDecref,
|
||||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||||
},
|
},
|
||||||
arguments: rc_list_args,
|
arguments: root.arena.alloc([list, rc_sym]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
Loading…
Reference in New Issue
Block a user