mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
add alloca as an expression
This commit is contained in:
parent
750234f2de
commit
cdd2aab217
15 changed files with 171 additions and 14 deletions
|
@ -1144,6 +1144,11 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||
|
||||
Expr::ResetRef { symbol: arg, .. } => self.expr_resetref(*arg, sym, storage),
|
||||
|
||||
Expr::Alloca {
|
||||
initializer,
|
||||
element_layout,
|
||||
} => self.expr_alloca(*initializer, *element_layout, sym, storage),
|
||||
|
||||
Expr::RuntimeErrorFunction(_) => {
|
||||
todo!("Expression `{}`", expr.to_pretty(100, false))
|
||||
}
|
||||
|
@ -2140,6 +2145,48 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||
);
|
||||
}
|
||||
|
||||
fn expr_alloca(
|
||||
&mut self,
|
||||
initializer: Option<Symbol>,
|
||||
element_layout: InLayout<'a>,
|
||||
ret_symbol: Symbol,
|
||||
ret_storage: &StoredValue,
|
||||
) {
|
||||
// Alloca : a -> Ptr a
|
||||
let (size, alignment_bytes) = self
|
||||
.layout_interner
|
||||
.stack_size_and_alignment(element_layout);
|
||||
|
||||
let (frame_ptr, offset) = self
|
||||
.storage
|
||||
.allocate_anonymous_stack_memory(size, alignment_bytes);
|
||||
|
||||
// write the default value into the stack memory
|
||||
if let Some(initializer) = initializer {
|
||||
self.storage.copy_value_to_memory(
|
||||
&mut self.code_builder,
|
||||
frame_ptr,
|
||||
offset,
|
||||
initializer,
|
||||
);
|
||||
}
|
||||
|
||||
// create a local variable for the pointer
|
||||
let ptr_local_id = match self.storage.ensure_value_has_local(
|
||||
&mut self.code_builder,
|
||||
ret_symbol,
|
||||
ret_storage.clone(),
|
||||
) {
|
||||
StoredValue::Local { local_id, .. } => local_id,
|
||||
_ => internal_error!("A pointer will always be an i32"),
|
||||
};
|
||||
|
||||
self.code_builder.get_local(frame_ptr);
|
||||
self.code_builder.i32_const(offset as i32);
|
||||
self.code_builder.i32_add();
|
||||
self.code_builder.set_local(ptr_local_id);
|
||||
}
|
||||
|
||||
/// Generate a refcount helper procedure and return a pointer (table index) to it
|
||||
/// This allows it to be indirectly called from Zig code
|
||||
pub fn get_refcount_fn_index(&mut self, layout: InLayout<'a>, op: HelperOp) -> u32 {
|
||||
|
|
|
@ -2048,6 +2048,10 @@ impl<'a> LowLevelCall<'a> {
|
|||
StoredValue::StackMemory { .. } => { /* do nothing */ }
|
||||
},
|
||||
DictPseudoSeed => self.load_args_and_call_zig(backend, bitcode::UTILS_DICT_PSEUDO_SEED),
|
||||
|
||||
SetJmp | LongJmp | SetLongJmpBuffer => {
|
||||
unreachable!("only inserted in dev backend codegen")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue