mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 20:28:02 +00:00
wasm: delete CallConv, since now Zig==C (hopefully)
This commit is contained in:
parent
cc2b8b5d19
commit
4c4344b46c
4 changed files with 44 additions and 99 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue