mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Improve stack allocation code
This commit is contained in:
parent
f1b14c14e3
commit
79ac2f04b8
1 changed files with 20 additions and 26 deletions
|
@ -160,8 +160,7 @@ impl<'a> WasmBackend<'a> {
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
kind: LocalKind,
|
kind: LocalKind,
|
||||||
) -> SymbolStorage {
|
) -> SymbolStorage {
|
||||||
let local_index = (self.arg_types.len() + self.locals.len()) as u32;
|
let local_id = LocalId((self.arg_types.len() + self.locals.len()) as u32);
|
||||||
let local_id = LocalId(local_index);
|
|
||||||
|
|
||||||
let storage = match kind {
|
let storage = match kind {
|
||||||
LocalKind::Parameter => {
|
LocalKind::Parameter => {
|
||||||
|
@ -208,20 +207,28 @@ impl<'a> WasmBackend<'a> {
|
||||||
} => {
|
} => {
|
||||||
let offset =
|
let offset =
|
||||||
round_up_to_alignment(self.stack_memory, alignment_bytes as i32);
|
round_up_to_alignment(self.stack_memory, alignment_bytes as i32);
|
||||||
|
|
||||||
self.stack_memory = offset + size as i32;
|
self.stack_memory = offset + size as i32;
|
||||||
|
|
||||||
// TODO: if we're creating the frame pointer just reuse the same local_id!
|
match self.stack_frame_pointer {
|
||||||
let frame_pointer = self.get_or_create_frame_pointer();
|
None => {
|
||||||
|
// This is the first stack-memory variable in the function
|
||||||
|
// That means we can reuse it as the stack frame pointer,
|
||||||
|
// and it will get initialised at the start of the function
|
||||||
|
self.stack_frame_pointer = Some(local_id);
|
||||||
|
}
|
||||||
|
|
||||||
// initialise the local with the appropriate address
|
Some(frame_ptr_id) => {
|
||||||
// TODO: skip this the first time, no point generating code to add zero offset!
|
// This local points to the base of a struct, at an offset from the stack frame pointer
|
||||||
self.instructions.extend([
|
// Having one local per variable means params and locals work the same way in code gen.
|
||||||
GetLocal(frame_pointer.0),
|
// (alternatively we could use one frame pointer + offset for all struct variables)
|
||||||
I32Const(offset),
|
self.instructions.extend([
|
||||||
I32Add,
|
GetLocal(frame_ptr_id.0),
|
||||||
SetLocal(local_index),
|
I32Const(offset),
|
||||||
]);
|
I32Add,
|
||||||
|
SetLocal(local_id.0),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
SymbolStorage::VarStackMemory {
|
SymbolStorage::VarStackMemory {
|
||||||
local_id,
|
local_id,
|
||||||
|
@ -239,19 +246,6 @@ impl<'a> WasmBackend<'a> {
|
||||||
storage
|
storage
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_create_frame_pointer(&mut self) -> LocalId {
|
|
||||||
match self.stack_frame_pointer {
|
|
||||||
Some(local_id) => local_id,
|
|
||||||
None => {
|
|
||||||
let local_index = (self.arg_types.len() + self.locals.len()) as u32;
|
|
||||||
let local_id = LocalId(local_index);
|
|
||||||
self.stack_frame_pointer = Some(local_id);
|
|
||||||
self.locals.push(Local::new(1, ValueType::I32));
|
|
||||||
local_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_symbol_storage(&self, sym: &Symbol) -> Result<&SymbolStorage, String> {
|
fn get_symbol_storage(&self, sym: &Symbol) -> Result<&SymbolStorage, String> {
|
||||||
self.symbol_storage_map.get(sym).ok_or_else(|| {
|
self.symbol_storage_map.get(sym).ok_or_else(|| {
|
||||||
format!(
|
format!(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue