wasm: delete ReturnMethod::ZigPackedStruct

This commit is contained in:
Brian Carroll 2022-09-09 18:38:38 +01:00 committed by Brendan Hansknecht
parent 564de99a43
commit cc2b8b5d19
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
4 changed files with 22 additions and 71 deletions

View file

@ -418,9 +418,6 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
self.storage.arg_types.push(PTR_TYPE);
None
}
ZigPackedStruct => {
internal_error!("C calling convention does not return Zig packed structs")
}
};
// Create a block so we can exit the function without skipping stack frame "pop" code.
@ -528,7 +525,6 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
n_inner_wasm_args += 1;
None
}
x => internal_error!("A Roc function should never use ReturnMethod {:?}", x),
};
// Load all the arguments for the inner function
@ -1349,16 +1345,14 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
} => {
let name = foreign_symbol.as_str();
let wasm_layout = WasmLayout::new(self.layout_interner, *ret_layout);
let (num_wasm_args, has_return_val, ret_zig_packed_struct) =
self.storage.load_symbols_for_call(
self.env.arena,
&mut self.code_builder,
arguments,
ret_sym,
&wasm_layout,
CallConv::C,
);
debug_assert!(!ret_zig_packed_struct); // only true in another place where we use the same helper fn
let (num_wasm_args, has_return_val) = self.storage.load_symbols_for_call(
self.env.arena,
&mut self.code_builder,
arguments,
ret_sym,
&wasm_layout,
CallConv::C,
);
self.call_host_fn_after_loading_args(name, num_wasm_args, has_return_val)
}
}
@ -1382,16 +1376,14 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
return self.expr_call_low_level(lowlevel, arguments, ret_sym, ret_layout, ret_storage);
}
let (num_wasm_args, has_return_val, ret_zig_packed_struct) =
self.storage.load_symbols_for_call(
self.env.arena,
&mut self.code_builder,
arguments,
ret_sym,
&wasm_layout,
CallConv::C,
);
debug_assert!(!ret_zig_packed_struct);
let (num_wasm_args, has_return_val) = self.storage.load_symbols_for_call(
self.env.arena,
&mut self.code_builder,
arguments,
ret_sym,
&wasm_layout,
CallConv::C,
);
let roc_proc_index = self
.proc_lookup

View file

@ -13,8 +13,6 @@ pub enum ReturnMethod {
WriteToPointerArg,
/// This layout is empty and requires no return value or argument (e.g. refcount helpers)
NoReturnValue,
/// This layout is returned as a packed struct in an integer. Only used by Zig, not C.
ZigPackedStruct,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -197,13 +195,7 @@ impl CallConv {
match self {
CallConv::C => WriteToPointerArg,
CallConv::Zig => {
if size <= 8 {
ZigPackedStruct
} else {
WriteToPointerArg
}
}
CallConv::Zig => WriteToPointerArg,
}
}
}

View file

@ -135,7 +135,7 @@ impl<'a> LowLevelCall<'a> {
/// For numerical ops, this just pushes the arguments to the Wasm VM's value stack
/// It implements the calling convention used by Zig for both numbers and structs
/// Result is the type signature of the call
fn load_args(&self, backend: &mut WasmBackend<'a, '_>) -> (usize, bool, bool) {
fn load_args(&self, backend: &mut WasmBackend<'a, '_>) -> (usize, bool) {
backend.storage.load_symbols_for_call(
backend.env.arena,
&mut backend.code_builder,
@ -147,29 +147,8 @@ impl<'a> LowLevelCall<'a> {
}
fn load_args_and_call_zig(&self, backend: &mut WasmBackend<'a, '_>, name: &'a str) {
let (num_wasm_args, has_return_val, ret_zig_packed_struct) = self.load_args(backend);
let (num_wasm_args, has_return_val) = self.load_args(backend);
backend.call_host_fn_after_loading_args(name, num_wasm_args, has_return_val);
if ret_zig_packed_struct {
match self.ret_storage {
StoredValue::StackMemory {
size,
alignment_bytes,
..
} => {
// The address of the return value was already loaded before the call
let align = Align::from(alignment_bytes);
if size > 4 {
backend.code_builder.i64_store(align, 0);
} else {
backend.code_builder.i32_store(align, 0);
}
}
_ => {
internal_error!("Zig packed struct should always be stored to StackMemory")
}
}
}
}
/// Wrap an integer that should have less than 32 bits, but is represented in Wasm as i32.

View file

@ -493,7 +493,7 @@ impl<'a> Storage<'a> {
return_symbol: Symbol,
return_layout: &WasmLayout,
call_conv: CallConv,
) -> (usize, bool, bool) {
) -> (usize, bool) {
use ReturnMethod::*;
let mut num_wasm_args = 0;
@ -508,14 +508,6 @@ impl<'a> Storage<'a> {
symbols_to_load.push(return_symbol);
false
}
ZigPackedStruct => {
// Workaround for Zig's incorrect implementation of the C calling convention.
// We need to copy the packed struct into the stack frame
// Load the address before the call so that afterward, it will be 2nd on the value stack,
// ready for the store instruction.
symbols_to_load.push(return_symbol);
true
}
};
for arg in arguments {
@ -533,7 +525,7 @@ impl<'a> Storage<'a> {
// If the symbols were already at the top of the stack, do nothing!
// Should be common for simple cases, due to the structure of the Mono IR
if !code_builder.verify_stack_match(&symbols_to_load) {
if matches!(return_method, WriteToPointerArg | ZigPackedStruct) {
if matches!(return_method, WriteToPointerArg) {
self.load_return_address_ccc(code_builder, return_symbol);
};
@ -545,11 +537,7 @@ impl<'a> Storage<'a> {
}
}
(
num_wasm_args,
has_return_val,
return_method == ZigPackedStruct,
)
(num_wasm_args, has_return_val)
}
/// Generate code to copy a StoredValue to an arbitrary memory location