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

@ -4,7 +4,7 @@ mod layout;
use bumpalo::Bump;
use parity_wasm::builder;
use parity_wasm::elements::{Instruction, Internal, ValueType};
use parity_wasm::elements::{Instruction, Instruction::*, Internal, ValueType};
use roc_collections::all::{MutMap, MutSet};
use roc_module::symbol::{Interns, Symbol};
@ -24,6 +24,9 @@ pub const ALIGN_8: u32 = 3;
pub const STACK_POINTER_GLOBAL_ID: u32 = 0;
#[derive(Clone, Copy, Debug)]
struct LocalId(u32);
pub struct Env<'a> {
pub arena: &'a Bump, // not really using this much, parity_wasm works with std::vec a lot
pub interns: Interns,
@ -105,3 +108,47 @@ pub fn build_module_help<'a>(
Ok((backend.builder, main_function_index))
}
fn encode_alignment(bytes: u32) -> Result<u32, String> {
match bytes {
1 => Ok(ALIGN_1),
2 => Ok(ALIGN_2),
4 => Ok(ALIGN_4),
8 => Ok(ALIGN_8),
_ => Err(format!("{:?}-byte alignment is not supported", bytes)),
}
}
fn copy_memory(
instructions: &mut Vec<Instruction>,
from_ptr: LocalId,
to_ptr: LocalId,
size_with_alignment: u32,
alignment_bytes: u32,
) -> Result<(), String> {
let alignment_flag = encode_alignment(alignment_bytes)?;
let size = size_with_alignment - alignment_bytes;
let mut offset = 0;
while size - offset >= 8 {
instructions.push(GetLocal(to_ptr.0));
instructions.push(GetLocal(from_ptr.0));
instructions.push(I64Load(alignment_flag, offset));
instructions.push(I64Store(alignment_flag, offset));
offset += 8;
}
if size - offset >= 4 {
instructions.push(GetLocal(to_ptr.0));
instructions.push(GetLocal(from_ptr.0));
instructions.push(I32Load(alignment_flag, offset));
instructions.push(I32Store(alignment_flag, offset));
offset += 4;
}
while size - offset > 0 {
instructions.push(GetLocal(to_ptr.0));
instructions.push(GetLocal(from_ptr.0));
instructions.push(I32Load8U(alignment_flag, offset));
instructions.push(I32Store8(alignment_flag, offset));
offset += 1;
}
Ok(())
}