Handle zero-size structs

This commit is contained in:
Brian Carroll 2021-11-28 09:27:34 +00:00
parent 8eb74da0f3
commit 27af5897d1
2 changed files with 20 additions and 6 deletions

View file

@ -178,15 +178,18 @@ impl<'a> WasmBackend<'a> {
fn start_proc(&mut self, proc: &Proc<'a>) { fn start_proc(&mut self, proc: &Proc<'a>) {
let ret_layout = WasmLayout::new(&proc.ret_layout); let ret_layout = WasmLayout::new(&proc.ret_layout);
let ret_type = if ret_layout.is_stack_memory() { let ret_type = if ret_layout.is_stack_memory() {
self.storage.arg_types.push(PTR_TYPE); if ret_layout.size() != 0 {
self.start_block(BlockType::NoResult); // block to ensure all paths pop stack memory (if any) self.storage.arg_types.push(PTR_TYPE);
}
None None
} else { } else {
let ty = ret_layout.value_type(); Some(ret_layout.value_type())
self.start_block(BlockType::Value(ty)); // block to ensure all paths pop stack memory (if any)
Some(ty)
}; };
// Create a block so we can exit the function without skipping stack frame "pop" code.
// We never use the `return` instruction. Instead, we break from this block.
self.start_block(BlockType::from(ret_type));
for (layout, symbol) in proc.args { for (layout, symbol) in proc.args {
let arg_layout = WasmLayout::new(layout); let arg_layout = WasmLayout::new(layout);
self.storage self.storage
@ -767,7 +770,9 @@ impl<'a> WasmBackend<'a> {
); );
} }
} else { } else {
return Err(format!("Not supported yet: zero-size struct at {:?}", sym)); // Zero-size struct. No code to emit.
// These values are purely conceptual, they only exist internally in the compiler
return Ok(());
} }
} }
_ => { _ => {

View file

@ -50,6 +50,15 @@ impl BlockType {
} }
} }
impl From<Option<ValueType>> for BlockType {
fn from(opt: Option<ValueType>) -> Self {
match opt {
Some(ty) => BlockType::Value(ty),
None => BlockType::NoResult,
}
}
}
/// A control block in our model of the VM /// A control block in our model of the VM
/// Child blocks cannot "see" values from their parent block /// Child blocks cannot "see" values from their parent block
struct VmBlock<'a> { struct VmBlock<'a> {