wasm: delete CallConv, since now Zig==C (hopefully)

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

View file

@ -27,7 +27,7 @@ use roc_wasm_module::{
};
use crate::code_builder::CodeBuilder;
use crate::layout::{CallConv, ReturnMethod, WasmLayout};
use crate::layout::{ReturnMethod, WasmLayout};
use crate::low_level::{call_higher_order_lowlevel, LowLevelCall};
use crate::storage::{AddressValue, Storage, StoredValue, StoredVarKind};
use crate::{
@ -411,7 +411,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
use ReturnMethod::*;
let ret_layout = WasmLayout::new(self.layout_interner, proc.ret_layout);
let ret_type = match ret_layout.return_method(CallConv::C) {
let ret_type = match ret_layout.return_method() {
Primitive(ty, _) => Some(ty),
NoReturnValue => None,
WriteToPointerArg => {
@ -511,7 +511,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
};
let mut n_inner_wasm_args = 0;
let ret_type_and_size = match inner_ret_layout.return_method(CallConv::C) {
let ret_type_and_size = match inner_ret_layout.return_method() {
ReturnMethod::NoReturnValue => None,
ReturnMethod::Primitive(ty, size) => {
// If the inner function returns a primitive, load the address to store it at
@ -853,8 +853,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
}
let is_bool = matches!(cond_layout, Layout::BOOL);
let cond_type =
WasmLayout::new(self.layout_interner, cond_layout).arg_types(CallConv::C)[0];
let cond_type = WasmLayout::new(self.layout_interner, cond_layout).arg_types()[0];
// then, we jump whenever the value under scrutiny is equal to the value of a branch
for (i, (value, _, _)) in branches.iter().enumerate() {
@ -1351,7 +1350,6 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
arguments,
ret_sym,
&wasm_layout,
CallConv::C,
);
self.call_host_fn_after_loading_args(name, num_wasm_args, has_return_val)
}
@ -1382,7 +1380,6 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
arguments,
ret_sym,
&wasm_layout,
CallConv::C,
);
let roc_proc_index = self

View file

@ -105,7 +105,7 @@ impl WasmLayout {
/// The `ValueType`s to use for this layout when calling a Wasm function
/// One Roc argument can become 0, 1, or 2 Wasm arguments
pub fn arg_types(&self, conv: CallConv) -> &'static [ValueType] {
pub fn arg_types(&self) -> &'static [ValueType] {
use ValueType::*;
match self {
@ -116,87 +116,49 @@ impl WasmLayout {
Self::Primitive(F64, _) => &[F64],
// 1 Roc argument => 0-2 Wasm arguments (depending on size and calling convention)
Self::StackMemory { size, format, .. } => conv.stack_memory_arg_types(*size, *format),
Self::StackMemory { size, format, .. } => stack_memory_arg_types(*size, *format),
}
}
pub fn return_method(&self, conv: CallConv) -> ReturnMethod {
pub fn return_method(&self) -> ReturnMethod {
match self {
Self::Primitive(ty, size) => ReturnMethod::Primitive(*ty, *size),
Self::StackMemory { size, format, .. } => {
conv.stack_memory_return_method(*size, *format)
Self::StackMemory { size, format, .. } => stack_memory_return_method(*size, *format),
}
}
}
/// The Wasm argument types to use when passing structs or 128-bit numbers
pub fn stack_memory_arg_types(size: u32, format: StackMemoryFormat) -> &'static [ValueType] {
use StackMemoryFormat::*;
use ValueType::*;
match format {
Int128 | Decimal => &[I64, I64],
DataStructure => {
if size == 0 {
// Zero-size Roc values like `{}` => no Wasm arguments
&[]
} else {
&[I32] // Always pass structs by reference (pointer to stack memory)
}
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum CallConv {
/// The C calling convention, as defined here:
/// https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md
C,
/// The calling convention that Zig 0.9 generates for Wasm when we *ask* it
/// for the .C calling convention, due to bugs in the Zig compiler.
Zig,
}
pub fn stack_memory_return_method(size: u32, format: StackMemoryFormat) -> ReturnMethod {
use ReturnMethod::*;
use StackMemoryFormat::*;
impl CallConv {
/// The Wasm argument types to use when passing structs or 128-bit numbers
pub fn stack_memory_arg_types(
&self,
size: u32,
format: StackMemoryFormat,
) -> &'static [ValueType] {
use StackMemoryFormat::*;
use ValueType::*;
match format {
Int128 | Decimal => WriteToPointerArg,
match format {
Int128 | Decimal => &[I64, I64],
DataStructure => {
if size == 0 {
// Zero-size Roc values like `{}` => no Wasm arguments
return &[];
}
match self {
CallConv::C => {
&[I32] // Always pass structs by reference (pointer to stack memory)
}
CallConv::Zig => {
if size <= 4 {
&[I32] // Small struct: pass by value
} else if size <= 8 {
&[I64] // Small struct: pass by value
} else if size <= 12 {
&[I64, I32] // Medium struct: pass by value, as two Wasm arguments
} else if size <= 16 {
&[I64, I64] // Medium struct: pass by value, as two Wasm arguments
} else {
&[I32] // Large struct: pass by reference
}
}
}
}
}
}
pub fn stack_memory_return_method(&self, size: u32, format: StackMemoryFormat) -> ReturnMethod {
use ReturnMethod::*;
use StackMemoryFormat::*;
match format {
Int128 | Decimal => WriteToPointerArg,
DataStructure => {
if size == 0 {
return NoReturnValue;
}
match self {
CallConv::C => WriteToPointerArg,
CallConv::Zig => WriteToPointerArg,
}
DataStructure => {
if size == 0 {
NoReturnValue
} else {
WriteToPointerArg
}
}
}

View file

@ -10,7 +10,7 @@ use roc_mono::layout::{Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, Un
use roc_mono::low_level::HigherOrder;
use crate::backend::{ProcLookupData, ProcSource, WasmBackend};
use crate::layout::{CallConv, StackMemoryFormat, WasmLayout};
use crate::layout::{StackMemoryFormat, WasmLayout};
use crate::storage::{AddressValue, StackMemoryLocation, StoredValue};
use crate::PTR_TYPE;
use roc_wasm_module::{Align, LocalId, ValueType};
@ -142,7 +142,6 @@ impl<'a> LowLevelCall<'a> {
self.arguments,
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
)
}
@ -255,7 +254,6 @@ impl<'a> LowLevelCall<'a> {
self.arguments,
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
);
backend.code_builder.i32_const(UPDATE_MODE_IMMUTABLE);
backend.call_host_fn_after_loading_args(bitcode::STR_FROM_UTF8_RANGE, 6, false);
@ -478,7 +476,6 @@ impl<'a> LowLevelCall<'a> {
self.arguments,
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
);
// Load monomorphization constants
@ -518,7 +515,6 @@ impl<'a> LowLevelCall<'a> {
&[list],
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
);
backend.code_builder.i32_const(elem_align as i32);
@ -558,7 +554,6 @@ impl<'a> LowLevelCall<'a> {
&[list],
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
);
backend.code_builder.i32_const(elem_align as i32);
@ -598,7 +593,6 @@ impl<'a> LowLevelCall<'a> {
&[list],
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
);
backend.code_builder.get_local(elem_local);
@ -638,7 +632,6 @@ impl<'a> LowLevelCall<'a> {
&[list],
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
);
backend.code_builder.i32_const(elem_align as i32);
@ -691,7 +684,6 @@ impl<'a> LowLevelCall<'a> {
&[list],
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
);
backend.code_builder.i32_const(elem_align as i32);
@ -739,7 +731,6 @@ impl<'a> LowLevelCall<'a> {
&[list],
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
);
backend.code_builder.i32_const(elem_width as i32);
@ -778,7 +769,6 @@ impl<'a> LowLevelCall<'a> {
&[list],
self.ret_symbol,
&WasmLayout::new(backend.layout_interner, self.ret_layout),
CallConv::Zig,
);
backend.code_builder.i32_const(elem_align as i32);

View file

@ -7,7 +7,7 @@ use roc_module::symbol::Symbol;
use roc_mono::layout::{InLayout, STLayoutInterner};
use crate::code_builder::{CodeBuilder, VmSymbolState};
use crate::layout::{CallConv, ReturnMethod, StackMemoryFormat, WasmLayout};
use crate::layout::{stack_memory_arg_types, ReturnMethod, StackMemoryFormat, WasmLayout};
use crate::{copy_memory, CopyMemoryConfig, PTR_TYPE};
use roc_wasm_module::{round_up_to_alignment, Align, LocalId, ValueType};
@ -59,7 +59,7 @@ pub enum StoredValue {
impl StoredValue {
/// Value types to pass to Wasm functions
/// One Roc value can become 0, 1, or 2 Wasm arguments
pub fn arg_types(&self, conv: CallConv) -> &'static [ValueType] {
pub fn arg_types(&self) -> &'static [ValueType] {
use ValueType::*;
match self {
// Simple numbers: 1 Roc argument => 1 Wasm argument
@ -72,7 +72,7 @@ impl StoredValue {
}
}
// Stack memory values: 1 Roc argument => 0-2 Wasm arguments
Self::StackMemory { size, format, .. } => conv.stack_memory_arg_types(*size, *format),
Self::StackMemory { size, format, .. } => stack_memory_arg_types(*size, *format),
}
}
}
@ -249,7 +249,7 @@ impl<'a> Storage<'a> {
use StackMemoryFormat::*;
self.arg_types
.extend_from_slice(CallConv::C.stack_memory_arg_types(size, format));
.extend_from_slice(stack_memory_arg_types(size, format));
let location = match format {
Int128 | Decimal => {
@ -492,14 +492,13 @@ impl<'a> Storage<'a> {
arguments: &[Symbol],
return_symbol: Symbol,
return_layout: &WasmLayout,
call_conv: CallConv,
) -> (usize, bool) {
use ReturnMethod::*;
let mut num_wasm_args = 0;
let mut symbols_to_load = Vec::with_capacity_in(arguments.len() * 2 + 1, arena);
let return_method = return_layout.return_method(call_conv);
let return_method = return_layout.return_method();
let has_return_val = match return_method {
Primitive(..) => true,
NoReturnValue => false,
@ -512,7 +511,7 @@ impl<'a> Storage<'a> {
for arg in arguments {
let stored = self.symbol_storage_map.get(arg).unwrap();
let arg_types = stored.arg_types(call_conv);
let arg_types = stored.arg_types();
num_wasm_args += arg_types.len();
match arg_types.len() {
0 => {}
@ -530,10 +529,7 @@ impl<'a> Storage<'a> {
};
for arg in arguments {
match call_conv {
CallConv::C => self.load_symbol_ccc(code_builder, *arg),
CallConv::Zig => self.load_symbol_zig(code_builder, *arg),
}
self.load_symbol_ccc(code_builder, *arg);
}
}