mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
Fix gen_wasm Let statement for heap-allocating expressions
When we allocate on the heap we'll need to force LocalId storage. In that case we don't want CodeBuilder to track the Symbol, even though it has WasmLayout::Primitive. So basically it was always the wrong condition to check, but we got away with it when we had no heap allocations.
This commit is contained in:
parent
0220f7d921
commit
73c9c7089a
1 changed files with 8 additions and 14 deletions
|
@ -296,18 +296,12 @@ impl<'a> WasmBackend<'a> {
|
||||||
|
|
||||||
self.build_expr(sym, expr, layout, &sym_storage)?;
|
self.build_expr(sym, expr, layout, &sym_storage)?;
|
||||||
|
|
||||||
// For primitives, we record that this symbol is at the top of the VM stack
|
// If this value is stored in the VM stack, we need code_builder to track it
|
||||||
// (For other values, we wrote to memory and there's nothing on the VM stack)
|
// (since every instruction can change the VM stack)
|
||||||
if let WasmLayout::Primitive(value_type, size) = wasm_layout {
|
if let Some(StoredValue::VirtualMachineStack { vm_state, .. }) =
|
||||||
let vm_state = self.code_builder.set_top_symbol(*sym);
|
self.storage.symbol_storage_map.get_mut(sym)
|
||||||
self.storage.symbol_storage_map.insert(
|
{
|
||||||
*sym,
|
*vm_state = self.code_builder.set_top_symbol(*sym);
|
||||||
StoredValue::VirtualMachineStack {
|
|
||||||
vm_state,
|
|
||||||
value_type,
|
|
||||||
size,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.symbol_layouts.insert(*sym, *layout);
|
self.symbol_layouts.insert(*sym, *layout);
|
||||||
|
@ -854,14 +848,14 @@ impl<'a> WasmBackend<'a> {
|
||||||
// Not passing it as an argument because I'm trying to match Backend method signatures
|
// Not passing it as an argument because I'm trying to match Backend method signatures
|
||||||
let storage = self.storage.get(sym).to_owned();
|
let storage = self.storage.get(sym).to_owned();
|
||||||
|
|
||||||
if let Layout::Struct(field_layouts) = layout {
|
if matches!(layout, Layout::Struct(_)) {
|
||||||
match storage {
|
match storage {
|
||||||
StoredValue::StackMemory { location, size, .. } => {
|
StoredValue::StackMemory { location, size, .. } => {
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
let (local_id, struct_offset) =
|
let (local_id, struct_offset) =
|
||||||
location.local_and_offset(self.storage.stack_frame_pointer);
|
location.local_and_offset(self.storage.stack_frame_pointer);
|
||||||
let mut field_offset = struct_offset;
|
let mut field_offset = struct_offset;
|
||||||
for (field, _) in fields.iter().zip(field_layouts.iter()) {
|
for field in fields.iter() {
|
||||||
field_offset += self.storage.copy_value_to_memory(
|
field_offset += self.storage.copy_value_to_memory(
|
||||||
&mut self.code_builder,
|
&mut self.code_builder,
|
||||||
local_id,
|
local_id,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue