copy returned structs to caller stack

This commit is contained in:
Brian Carroll 2021-09-17 19:42:29 +01:00
parent 3d18d34135
commit 036503c750
3 changed files with 114 additions and 35 deletions

View file

@ -1,7 +1,7 @@
use parity_wasm::elements::{Instruction, Instruction::*, ValueType};
use parity_wasm::elements::ValueType;
use roc_mono::layout::{Layout, UnionLayout};
use crate::{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)]
@ -11,7 +11,7 @@ pub enum WasmLayout {
LocalOnly(ValueType, u32),
// A `local` pointing to stack memory
StackMemory(u32),
StackMemory { size: u32, alignment_bytes: u32 },
// A `local` pointing to heap memory
HeapMemory,
@ -24,6 +24,7 @@ impl WasmLayout {
use ValueType::*;
let size = layout.stack_size(PTR_SIZE);
let alignment_bytes = layout.alignment_bytes(PTR_SIZE);
match layout {
Layout::Builtin(Int32 | Int16 | Int8 | Int1 | Usize) => Self::LocalOnly(I32, size),
@ -49,7 +50,10 @@ impl WasmLayout {
)
| Layout::Struct(_)
| Layout::LambdaSet(_)
| Layout::Union(NonRecursive(_)) => Self::StackMemory(size),
| Layout::Union(NonRecursive(_)) => Self::StackMemory {
size,
alignment_bytes,
},
Layout::Union(
Recursive(_)
@ -70,11 +74,12 @@ impl WasmLayout {
pub fn stack_memory(&self) -> u32 {
match self {
Self::StackMemory(size) => *size,
Self::StackMemory { size, .. } => *size,
_ => 0,
}
}
/*
#[allow(dead_code)]
fn load(&self, offset: u32) -> Result<Instruction, String> {
use crate::layout::WasmLayout::*;
@ -104,34 +109,50 @@ impl WasmLayout {
)),
}
}
*/
/*
TODO: this is probably in the wrong place, need specific locals for the StackMemory case.
Come back to it later.
#[allow(dead_code)]
fn store(&self, offset: u32) -> Result<Instruction, String> {
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) => Ok(I32Store(ALIGN_4, offset)),
LocalOnly(I32, 2) => Ok(I32Store16(ALIGN_2, offset)),
LocalOnly(I32, 1) => Ok(I32Store8(ALIGN_1, offset)),
LocalOnly(I64, 8) => Ok(I64Store(ALIGN_8, offset)),
LocalOnly(F64, 8) => Ok(F64Store(ALIGN_8, offset)),
LocalOnly(F32, 4) => Ok(F32Store(ALIGN_4, offset)),
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,
} => {
let from_ptr = LocalId(0);
let to_ptr = LocalId(0);
copy_memory(instructions, from_ptr, to_ptr: size, alignment_bytes)
}
// LocalOnly(F32, 2) => Ok(), // convert F32 to F16 (lowlevel function? Wasm-only?)
// StackMemory(size) => Ok(), // would this be some kind of memcpy in the IR?
HeapMemory => {
if PTR_TYPE == I64 {
Ok(I64Store(ALIGN_8, offset))
instructions.push(I64Store(ALIGN_8, offset));
} else {
Ok(I32Store(ALIGN_4, offset))
instructions.push(I32Store(ALIGN_4, offset));
}
}
_ => Err(format!(
"Failed to generate store instruction for WasmLayout {:?}",
self
)),
_ => {
result = Err(format!(
"Failed to generate store instruction for WasmLayout {:?}",
self
));
}
}
result
}
*/
}