Push layout interner further through Layout

This commit is contained in:
Ayaz Hafiz 2022-08-31 14:14:34 -05:00
parent ed04c2040a
commit 3b4b1838b8
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
34 changed files with 1279 additions and 634 deletions

View file

@ -149,7 +149,7 @@ impl<'a> LowLevelCall<'a> {
&mut backend.code_builder,
self.arguments,
self.ret_symbol,
&WasmLayout::new(&self.ret_layout),
&WasmLayout::new(backend.env.layout_interner, &self.ret_layout),
CallConv::Zig,
)
}
@ -283,7 +283,7 @@ impl<'a> LowLevelCall<'a> {
&mut backend.code_builder,
self.arguments,
self.ret_symbol,
&WasmLayout::new(&self.ret_layout),
&WasmLayout::new(backend.env.layout_interner, &self.ret_layout),
CallConv::Zig,
);
backend.code_builder.i32_const(UPDATE_MODE_IMMUTABLE);
@ -358,7 +358,9 @@ impl<'a> LowLevelCall<'a> {
backend
.storage
.load_symbols(&mut backend.code_builder, &[index]);
let elem_size = self.ret_layout.stack_size(TARGET_INFO);
let elem_size = self
.ret_layout
.stack_size(backend.env.layout_interner, TARGET_INFO);
backend.code_builder.i32_const(elem_size as i32);
backend.code_builder.i32_mul(); // index*size
@ -415,15 +417,16 @@ impl<'a> LowLevelCall<'a> {
..
} if value_layout == *list_elem => {
let list_offset = 0;
let elem_offset =
Layout::Builtin(Builtin::List(list_elem)).stack_size(TARGET_INFO);
let elem_offset = Layout::Builtin(Builtin::List(list_elem))
.stack_size(backend.env.layout_interner, TARGET_INFO);
(list_offset, elem_offset, value_layout)
}
Layout::Struct {
field_layouts: &[value_layout, Layout::Builtin(Builtin::List(list_elem))],
..
} if value_layout == *list_elem => {
let list_offset = value_layout.stack_size(TARGET_INFO);
let list_offset =
value_layout.stack_size(backend.env.layout_interner, TARGET_INFO);
let elem_offset = 0;
(list_offset, elem_offset, value_layout)
}
@ -431,7 +434,7 @@ impl<'a> LowLevelCall<'a> {
};
let (elem_width, elem_alignment) =
elem_layout.stack_size_and_alignment(TARGET_INFO);
elem_layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
// Ensure the new element is stored in memory so we can pass a pointer to Zig
let (new_elem_local, new_elem_offset, _) =
@ -480,7 +483,8 @@ impl<'a> LowLevelCall<'a> {
let capacity: Symbol = self.arguments[0];
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
let (elem_width, elem_align) =
elem_layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
// Zig arguments Wasm types
// (return pointer) i32
@ -511,13 +515,14 @@ impl<'a> LowLevelCall<'a> {
&mut backend.code_builder,
self.arguments,
self.ret_symbol,
&WasmLayout::new(&self.ret_layout),
&WasmLayout::new(backend.env.layout_interner, &self.ret_layout),
CallConv::Zig,
);
// Load monomorphization constants
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
let (elem_width, elem_align) =
elem_layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
backend.code_builder.i32_const(elem_align as i32);
backend.code_builder.i32_const(elem_width as i32);
@ -531,7 +536,8 @@ impl<'a> LowLevelCall<'a> {
let spare: Symbol = self.arguments[1];
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
let (elem_width, elem_align) =
elem_layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
let (spare_local, spare_offset, _) = ensure_symbol_is_in_memory(
backend,
spare,
@ -553,7 +559,7 @@ impl<'a> LowLevelCall<'a> {
&mut backend.code_builder,
&[list],
self.ret_symbol,
&WasmLayout::new(&self.ret_layout),
&WasmLayout::new(backend.env.layout_interner, &self.ret_layout),
CallConv::Zig,
);
@ -579,7 +585,7 @@ impl<'a> LowLevelCall<'a> {
let elem: Symbol = self.arguments[1];
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
let elem_width = elem_layout.stack_size(TARGET_INFO);
let elem_width = elem_layout.stack_size(backend.env.layout_interner, TARGET_INFO);
let (elem_local, elem_offset, _) =
ensure_symbol_is_in_memory(backend, elem, *elem_layout, backend.env.arena);
@ -595,7 +601,7 @@ impl<'a> LowLevelCall<'a> {
&mut backend.code_builder,
&[list],
self.ret_symbol,
&WasmLayout::new(&self.ret_layout),
&WasmLayout::new(backend.env.layout_interner, &self.ret_layout),
CallConv::Zig,
);
@ -616,7 +622,8 @@ impl<'a> LowLevelCall<'a> {
let elem: Symbol = self.arguments[1];
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
let (elem_width, elem_align) =
elem_layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
let (elem_local, elem_offset, _) =
ensure_symbol_is_in_memory(backend, elem, *elem_layout, backend.env.arena);
@ -633,7 +640,7 @@ impl<'a> LowLevelCall<'a> {
&mut backend.code_builder,
&[list],
self.ret_symbol,
&WasmLayout::new(&self.ret_layout),
&WasmLayout::new(backend.env.layout_interner, &self.ret_layout),
CallConv::Zig,
);
@ -657,7 +664,8 @@ impl<'a> LowLevelCall<'a> {
let len: Symbol = self.arguments[2];
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
let (elem_width, elem_align) =
elem_layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
// The refcount function receives a pointer to an element in the list
// This is the same as a Struct containing the element
@ -682,7 +690,7 @@ impl<'a> LowLevelCall<'a> {
&mut backend.code_builder,
&[list],
self.ret_symbol,
&WasmLayout::new(&self.ret_layout),
&WasmLayout::new(backend.env.layout_interner, &self.ret_layout),
CallConv::Zig,
);
@ -701,7 +709,8 @@ impl<'a> LowLevelCall<'a> {
let drop_index: Symbol = self.arguments[1];
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
let (elem_width, elem_align) =
elem_layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
// The refcount function receives a pointer to an element in the list
// This is the same as a Struct containing the element
@ -726,7 +735,7 @@ impl<'a> LowLevelCall<'a> {
&mut backend.code_builder,
&[list],
self.ret_symbol,
&WasmLayout::new(&self.ret_layout),
&WasmLayout::new(backend.env.layout_interner, &self.ret_layout),
CallConv::Zig,
);
@ -746,7 +755,8 @@ impl<'a> LowLevelCall<'a> {
let index_2: Symbol = self.arguments[2];
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
let (elem_width, elem_align) =
elem_layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
// Zig arguments Wasm types
// (return pointer) i32
@ -763,7 +773,7 @@ impl<'a> LowLevelCall<'a> {
&mut backend.code_builder,
&[list],
self.ret_symbol,
&WasmLayout::new(&self.ret_layout),
&WasmLayout::new(backend.env.layout_interner, &self.ret_layout),
CallConv::Zig,
);
@ -1625,7 +1635,10 @@ impl<'a> LowLevelCall<'a> {
// In most languages this operation is for signed numbers, but Roc defines it on all integers.
// So the argument is implicitly converted to signed before the shift operator.
// We need to make that conversion explicit for i8 and i16, which use Wasm's i32 type.
let bit_width = 8 * self.ret_layout.stack_size(TARGET_INFO) as i32;
let bit_width = 8 * self
.ret_layout
.stack_size(backend.env.layout_interner, TARGET_INFO)
as i32;
if bit_width < 32 && !symbol_is_signed_int(backend, num) {
// Sign-extend the number by shifting left and right again
backend
@ -1670,7 +1683,9 @@ impl<'a> LowLevelCall<'a> {
// In most languages this operation is for unsigned numbers, but Roc defines it on all integers.
// So the argument is implicitly converted to unsigned before the shift operator.
// We need to make that conversion explicit for i8 and i16, which use Wasm's i32 type.
let bit_width = 8 * self.ret_layout.stack_size(TARGET_INFO);
let bit_width = 8 * self
.ret_layout
.stack_size(backend.env.layout_interner, TARGET_INFO);
if bit_width < 32 && symbol_is_signed_int(backend, bits) {
let mask = (1 << bit_width) - 1;
@ -1861,10 +1876,10 @@ impl<'a> LowLevelCall<'a> {
/// Equality and inequality
/// These can operate on any data type (except functions) so they're more complex than other operators.
fn eq_or_neq(&self, backend: &mut WasmBackend<'a>) {
let arg_layout =
backend.storage.symbol_layouts[&self.arguments[0]].runtime_representation();
let other_arg_layout =
backend.storage.symbol_layouts[&self.arguments[1]].runtime_representation();
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]]
.runtime_representation(backend.env.layout_interner);
let other_arg_layout = backend.storage.symbol_layouts[&self.arguments[1]]
.runtime_representation(backend.env.layout_interner);
debug_assert!(
arg_layout == other_arg_layout,
"Cannot do `==` comparison on different types: {:?} vs {:?}",
@ -2140,7 +2155,10 @@ pub fn call_higher_order_lowlevel<'a>(
.is_represented(backend.env.layout_interner)
.is_some()
{
(lambda_set.runtime_representation(), true)
(
lambda_set.runtime_representation(backend.env.layout_interner),
true,
)
} else {
// Closure data is a lambda set, which *itself* has no closure data!
// The higher-order wrapper doesn't need to pass this down, that's
@ -2164,6 +2182,7 @@ pub fn call_higher_order_lowlevel<'a>(
// make sure that the wrapping struct is available in stack memory, so we can hand out a
// pointer to it.
let wrapped_storage = backend.storage.allocate_var(
backend.env.layout_interner,
wrapped_captures_layout,
wrapped_closure_data_sym,
crate::storage::StoredVarKind::Variable,
@ -2326,7 +2345,8 @@ pub fn call_higher_order_lowlevel<'a>(
ListSortWith { xs } => {
let elem_layout = unwrap_list_elem_layout(backend.storage.symbol_layouts[xs]);
let (element_width, alignment) = elem_layout.stack_size_and_alignment(TARGET_INFO);
let (element_width, alignment) =
elem_layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
let cb = &mut backend.code_builder;
@ -2389,7 +2409,8 @@ fn list_map_n<'a>(
);
let elem_ret = unwrap_list_elem_layout(return_layout);
let (elem_ret_size, elem_ret_align) = elem_ret.stack_size_and_alignment(TARGET_INFO);
let (elem_ret_size, elem_ret_align) =
elem_ret.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
let cb = &mut backend.code_builder;
@ -2410,7 +2431,7 @@ fn list_map_n<'a>(
cb.i32_const(owns_captured_environment as i32);
cb.i32_const(elem_ret_align as i32);
for el in arg_elem_layouts.iter() {
cb.i32_const(el.stack_size(TARGET_INFO) as i32);
cb.i32_const(el.stack_size(backend.env.layout_interner, TARGET_INFO) as i32);
}
cb.i32_const(elem_ret_size as i32);
@ -2449,7 +2470,8 @@ fn ensure_symbol_is_in_memory<'a>(
(local, offset, layout)
}
_ => {
let (width, alignment) = layout.stack_size_and_alignment(TARGET_INFO);
let (width, alignment) =
layout.stack_size_and_alignment(backend.env.layout_interner, TARGET_INFO);
let (frame_ptr, offset) = backend
.storage
.allocate_anonymous_stack_memory(width, alignment);