mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Returning records on the stack from Wasm dev backend!
This commit is contained in:
parent
39fda3e675
commit
02bb9028ef
5 changed files with 504 additions and 410 deletions
|
@ -1,10 +1,10 @@
|
|||
use parity_wasm::elements::{Instruction, Instruction::*, ValueType};
|
||||
use parity_wasm::elements::ValueType;
|
||||
use roc_mono::layout::{Layout, UnionLayout};
|
||||
|
||||
use crate::{copy_memory, LocalId, ALIGN_1, ALIGN_2, ALIGN_4, ALIGN_8, PTR_SIZE, PTR_TYPE};
|
||||
use crate::{PTR_SIZE, PTR_TYPE};
|
||||
|
||||
// See README for background information on Wasm locals, memory and function calls
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum WasmLayout {
|
||||
// Primitive number value. Just a Wasm local, without any stack memory.
|
||||
// For example, Roc i8 is represented as Wasm i32. Store the type and the original size.
|
||||
|
@ -79,81 +79,4 @@ impl WasmLayout {
|
|||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn load(&self, offset: u32) -> Result<Instruction, String> {
|
||||
use crate::layout::WasmLayout::*;
|
||||
use ValueType::*;
|
||||
|
||||
match self {
|
||||
LocalOnly(I32, 4) => Ok(I32Load(ALIGN_4, offset)),
|
||||
LocalOnly(I32, 2) => Ok(I32Load16S(ALIGN_2, offset)),
|
||||
LocalOnly(I32, 1) => Ok(I32Load8S(ALIGN_1, offset)),
|
||||
LocalOnly(I64, 8) => Ok(I64Load(ALIGN_8, offset)),
|
||||
LocalOnly(F64, 8) => Ok(F64Load(ALIGN_8, offset)),
|
||||
LocalOnly(F32, 4) => Ok(F32Load(ALIGN_4, offset)),
|
||||
|
||||
// TODO: Come back to this when we need to access fields of structs
|
||||
// LocalOnly(F32, 2) => Ok(), // convert F16 to F32 (lowlevel function? Wasm-only?)
|
||||
// StackMemory(size) => Ok(), // would this be some kind of memcpy in the IR?
|
||||
|
||||
HeapMemory => {
|
||||
if PTR_TYPE == I64 {
|
||||
Ok(I64Load(ALIGN_8, offset))
|
||||
} else {
|
||||
Ok(I32Load(ALIGN_4, offset))
|
||||
}
|
||||
}
|
||||
|
||||
_ => Err(format!(
|
||||
"Failed to generate load instruction for WasmLayout {:?}",
|
||||
self
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn store(&self, offset: u32, instructions: &mut Vec<Instruction>) -> Result<(), String> {
|
||||
use crate::layout::WasmLayout::*;
|
||||
use ValueType::*;
|
||||
|
||||
let mut result = Ok(());
|
||||
match self {
|
||||
LocalOnly(I32, 4) => instructions.push(I32Store(ALIGN_4, offset)),
|
||||
LocalOnly(I32, 2) => instructions.push(I32Store16(ALIGN_2, offset)),
|
||||
LocalOnly(I32, 1) => instructions.push(I32Store8(ALIGN_1, offset)),
|
||||
LocalOnly(I64, 8) => instructions.push(I64Store(ALIGN_8, offset)),
|
||||
LocalOnly(F64, 8) => instructions.push(F64Store(ALIGN_8, offset)),
|
||||
LocalOnly(F32, 4) => instructions.push(F32Store(ALIGN_4, offset)),
|
||||
|
||||
StackMemory {
|
||||
size,
|
||||
alignment_bytes,
|
||||
} => {
|
||||
// TODO
|
||||
// Need extra arguments for this case that we don't need for primitives.
|
||||
// Maybe it should be somewhere we have more relevant context?
|
||||
// Come back to it when we need to insert things into structs.
|
||||
let from_ptr = LocalId(0); // TODO
|
||||
let to_ptr = LocalId(0); // TODO
|
||||
copy_memory(instructions, from_ptr, to_ptr, *size, *alignment_bytes)?;
|
||||
}
|
||||
|
||||
HeapMemory => {
|
||||
if PTR_TYPE == I64 {
|
||||
instructions.push(I64Store(ALIGN_8, offset));
|
||||
} else {
|
||||
instructions.push(I32Store(ALIGN_4, offset));
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
result = Err(format!(
|
||||
"Failed to generate store instruction for WasmLayout {:?}",
|
||||
self
|
||||
));
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue