Expose capacity builtins

This commit is contained in:
Richard Feldman 2022-07-13 11:42:26 -04:00
parent 6ac9c37e06
commit 25facfa9c6
No known key found for this signature in database
GPG key ID: 7E4127D1E4241798
8 changed files with 67 additions and 1 deletions

View file

@ -243,6 +243,7 @@ impl<'a> LowLevelCall<'a> {
StrCountUtf8Bytes => {
self.load_args_and_call_zig(backend, bitcode::STR_COUNT_UTF8_BYTES)
}
StrGetCapacity => self.load_args_and_call_zig(backend, bitcode::STR_CAPACITY),
StrToNum => {
let number_layout = match self.ret_layout {
Layout::Struct { field_layouts, .. } => field_layouts[0],
@ -308,11 +309,27 @@ impl<'a> LowLevelCall<'a> {
let (local_id, offset) =
location.local_and_offset(backend.storage.stack_frame_pointer);
backend.code_builder.get_local(local_id);
// List is stored as (pointer, length, capacity),
// with each of those fields being 4 bytes on wasm.
// So the length is 4 bytes after the start of the struct.
backend.code_builder.i32_load(Align::Bytes4, offset + 4);
}
_ => internal_error!("invalid storage for List"),
},
ListGetCapacity => match backend.storage.get(&self.arguments[0]) {
StoredValue::StackMemory { location, .. } => {
let (local_id, offset) =
location.local_and_offset(backend.storage.stack_frame_pointer);
backend.code_builder.get_local(local_id);
// List is stored as (pointer, length, capacity),
// with each of those fields being 4 bytes on wasm.
// So the capacity is 8 bytes after the start of the struct.
backend.code_builder.i32_load(Align::Bytes4, offset + 8);
}
_ => internal_error!("invalid storage for List"),
},
ListIsUnique => self.load_args_and_call_zig(backend, bitcode::LIST_IS_UNIQUE),
ListMap | ListMap2 | ListMap3 | ListMap4 | ListSortWith | DictWalk => {
@ -1781,6 +1798,32 @@ impl<'a> LowLevelCall<'a> {
unreachable!("The {:?} operation is turned into mono Expr", self.lowlevel)
}
DictGetCapacity => match backend.storage.get(&self.arguments[0]) {
StoredValue::StackMemory { location, .. } => {
let (local_id, offset) =
location.local_and_offset(backend.storage.stack_frame_pointer);
backend.code_builder.get_local(local_id);
// Dict is stored as (pointer, length, capacity),
// with each of those fields being 4 bytes on wasm.
// So the capacity is 8 bytes after the start of the struct.
backend.code_builder.i32_load(Align::Bytes4, offset + 8);
}
_ => internal_error!("invalid storage for Dict"),
},
SetGetCapacity => match backend.storage.get(&self.arguments[0]) {
StoredValue::StackMemory { location, .. } => {
let (local_id, offset) =
location.local_and_offset(backend.storage.stack_frame_pointer);
backend.code_builder.get_local(local_id);
// Set is stored as (pointer, length, capacity),
// with each of those fields being 4 bytes on wasm.
// So the capacity is 8 bytes after the start of the struct.
backend.code_builder.i32_load(Align::Bytes4, offset + 8);
}
_ => internal_error!("invalid storage for Dict"),
},
Unreachable => match self.ret_storage {
StoredValue::VirtualMachineStack { value_type, .. }
| StoredValue::Local { value_type, .. } => match value_type {