use wasm_encoder::{TypeSection, ValType};
#[derive(Debug, Clone, Copy, Default)]
pub struct AverRuntimeImports {
pub rt_alloc: u32,
pub rt_truncate: u32,
pub rt_obj_kind: u32,
pub rt_obj_tag: u32,
pub rt_obj_meta: u32,
pub rt_obj_field: u32,
pub rt_obj_field_f64: u32,
pub rt_obj_field_i32: u32,
pub rt_unwrap: u32,
pub rt_unwrap_f64: u32,
pub rt_unwrap_i32: u32,
pub rt_wrap: u32,
pub rt_wrap_f64: u32,
pub rt_wrap_i32: u32,
pub rt_str_eq: u32,
pub rt_str_concat: u32,
pub rt_list_cons: u32,
pub rt_list_cons_f64: u32,
pub rt_str_byte_len: u32,
pub rt_str_find: u32,
pub rt_str_starts_with: u32,
pub rt_str_ends_with: u32,
pub rt_str_contains: u32,
pub rt_list_take: u32,
pub rt_list_drop: u32,
pub rt_list_concat: u32,
pub rt_list_reverse: u32,
pub rt_list_contains: u32,
pub rt_list_zip: u32,
pub rt_map_get: u32,
pub rt_map_set: u32,
pub rt_map_set_owned: u32,
pub rt_map_has: u32,
pub rt_map_keys: u32,
pub rt_map_entries: u32,
pub rt_map_len: u32,
pub rt_map_from_list: u32,
pub rt_vec_from_list: u32,
pub rt_vec_get: u32,
pub rt_vec_len: u32,
pub rt_vec_set: u32,
pub rt_vec_new: u32,
pub rt_vec_to_list: u32,
pub rt_int_to_str: u32,
pub rt_float_to_str: u32,
pub rt_i64_to_str_obj: u32,
pub rt_f64_to_str_obj: u32,
pub rt_str_len: u32,
pub rt_char_to_code: u32,
pub rt_byte_to_hex: u32,
pub rt_byte_from_hex: u32,
pub rt_char_from_code: u32,
pub rt_str_char_at: u32,
pub rt_str_to_lower: u32,
pub rt_str_to_upper: u32,
pub rt_str_trim: u32,
pub rt_str_slice: u32,
pub rt_str_chars: u32,
pub rt_str_split: u32,
pub rt_str_join: u32,
pub rt_str_replace: u32,
pub rt_int_from_str: u32,
pub rt_float_from_str: u32,
pub rt_collect_begin: u32,
pub rt_rebase_i32: u32,
pub rt_collect_end: u32,
pub rt_retain_i32: u32,
pub rt_buffer_new: u32,
pub rt_buffer_append_str: u32,
pub rt_buffer_finalize: u32,
}
#[derive(Debug, Clone, Copy)]
pub struct RuntimeFuncIndices {
pub alloc: u32, pub truncate: u32, pub collect_begin: u32, pub collect_end: u32, pub rebase_i32: u32, pub retain_i32: u32, pub wrap: u32, pub wrap_f64: u32, pub wrap_i32: u32, pub unwrap: u32, pub unwrap_f64: u32, pub unwrap_i32: u32, pub obj_kind: u32, pub obj_tag: u32, pub obj_meta: u32, pub obj_field: u32, pub obj_field_f64: u32, pub obj_field_i32: u32, pub list_cons: u32, pub list_cons_f64: u32, pub int_to_str: u32, pub float_to_str: u32, pub str_eq: u32, pub str_concat: u32, pub i64_to_str_obj: u32, pub f64_to_str_obj: u32, pub list_take: u32, pub list_drop: u32, pub list_concat: u32, pub list_reverse: u32, pub list_contains: u32, pub list_zip: u32, pub map_get: u32, pub map_set: u32, pub map_set_owned: u32, pub map_has: u32, pub map_keys: u32, pub map_entries: u32, pub map_len: u32, pub map_from_list: u32, pub vec_from_list: u32, pub vec_get: u32, pub vec_len: u32, pub vec_set: u32, pub vec_new: u32, pub vec_to_list: u32, pub str_len: u32, pub str_byte_len: u32, pub str_find: u32, pub str_starts_with: u32, pub str_ends_with: u32, pub str_contains: u32, pub str_char_at: u32, pub char_from_code: u32, pub char_to_code: u32, pub byte_to_hex: u32, pub byte_from_hex: u32, pub str_trim: u32, pub str_slice: u32, pub str_chars: u32, pub str_split: u32, pub str_join: u32, pub str_replace: u32, pub str_to_lower: u32, pub str_to_upper: u32, pub int_from_str: u32, pub float_from_str: u32, pub buffer_new: u32, pub buffer_append_str: u32, pub buffer_finalize: u32, pub count: u32,
pub adapter: super::super::WasmAdapter,
}
impl RuntimeFuncIndices {
pub fn new(_base: u32, imports: AverRuntimeImports) -> Self {
RuntimeFuncIndices {
alloc: imports.rt_alloc,
truncate: imports.rt_truncate,
collect_begin: imports.rt_collect_begin,
collect_end: imports.rt_collect_end,
rebase_i32: imports.rt_rebase_i32,
retain_i32: imports.rt_retain_i32,
wrap: imports.rt_wrap,
wrap_f64: imports.rt_wrap_f64,
wrap_i32: imports.rt_wrap_i32,
unwrap: imports.rt_unwrap,
unwrap_f64: imports.rt_unwrap_f64,
unwrap_i32: imports.rt_unwrap_i32,
obj_kind: imports.rt_obj_kind,
obj_tag: imports.rt_obj_tag,
obj_meta: imports.rt_obj_meta,
obj_field: imports.rt_obj_field,
obj_field_f64: imports.rt_obj_field_f64,
obj_field_i32: imports.rt_obj_field_i32,
list_cons: imports.rt_list_cons,
list_cons_f64: imports.rt_list_cons_f64,
int_to_str: imports.rt_int_to_str,
float_to_str: imports.rt_float_to_str,
str_eq: imports.rt_str_eq,
str_concat: imports.rt_str_concat,
i64_to_str_obj: imports.rt_i64_to_str_obj,
f64_to_str_obj: imports.rt_f64_to_str_obj,
list_take: imports.rt_list_take,
list_drop: imports.rt_list_drop,
list_concat: imports.rt_list_concat,
list_reverse: imports.rt_list_reverse,
list_contains: imports.rt_list_contains,
list_zip: imports.rt_list_zip,
map_get: imports.rt_map_get,
map_set: imports.rt_map_set,
map_set_owned: imports.rt_map_set_owned,
map_has: imports.rt_map_has,
map_keys: imports.rt_map_keys,
map_entries: imports.rt_map_entries,
map_len: imports.rt_map_len,
map_from_list: imports.rt_map_from_list,
vec_from_list: imports.rt_vec_from_list,
vec_get: imports.rt_vec_get,
vec_len: imports.rt_vec_len,
vec_set: imports.rt_vec_set,
vec_new: imports.rt_vec_new,
vec_to_list: imports.rt_vec_to_list,
str_len: imports.rt_str_len,
str_byte_len: imports.rt_str_byte_len,
str_find: imports.rt_str_find,
str_starts_with: imports.rt_str_starts_with,
str_ends_with: imports.rt_str_ends_with,
str_contains: imports.rt_str_contains,
str_char_at: imports.rt_str_char_at,
char_from_code: imports.rt_char_from_code,
char_to_code: imports.rt_char_to_code,
byte_to_hex: imports.rt_byte_to_hex,
byte_from_hex: imports.rt_byte_from_hex,
str_trim: imports.rt_str_trim,
str_slice: imports.rt_str_slice,
str_chars: imports.rt_str_chars,
str_split: imports.rt_str_split,
str_join: imports.rt_str_join,
str_replace: imports.rt_str_replace,
str_to_lower: imports.rt_str_to_lower,
str_to_upper: imports.rt_str_to_upper,
int_from_str: imports.rt_int_from_str,
float_from_str: imports.rt_float_from_str,
buffer_new: imports.rt_buffer_new,
buffer_append_str: imports.rt_buffer_append_str,
buffer_finalize: imports.rt_buffer_finalize,
count: 0,
adapter: super::super::WasmAdapter::Aver,
}
}
pub fn name_pairs(&self) -> Vec<(u32, &'static str)> {
vec![
(self.alloc, "alloc"),
(self.truncate, "truncate"),
(self.collect_begin, "collect_begin"),
(self.collect_end, "collect_end"),
(self.rebase_i32, "rebase_i32"),
(self.retain_i32, "retain_i32"),
(self.wrap, "wrap"),
(self.wrap_f64, "wrap_f64"),
(self.wrap_i32, "wrap_i32"),
(self.unwrap, "unwrap"),
(self.unwrap_f64, "unwrap_f64"),
(self.unwrap_i32, "unwrap_i32"),
(self.obj_kind, "obj_kind"),
(self.obj_tag, "obj_tag"),
(self.obj_meta, "obj_meta"),
(self.obj_field, "obj_field"),
(self.obj_field_f64, "obj_field_f64"),
(self.obj_field_i32, "obj_field_i32"),
(self.list_cons, "list_cons"),
(self.list_cons_f64, "list_cons_f64"),
(self.int_to_str, "int_to_str"),
(self.float_to_str, "float_to_str"),
(self.str_eq, "str_eq"),
(self.str_concat, "str_concat"),
(self.i64_to_str_obj, "i64_to_str_obj"),
(self.f64_to_str_obj, "f64_to_str_obj"),
(self.list_take, "list_take"),
(self.list_drop, "list_drop"),
(self.list_concat, "list_concat"),
(self.list_reverse, "list_reverse"),
(self.list_contains, "list_contains"),
(self.list_zip, "list_zip"),
(self.map_get, "map_get"),
(self.map_set, "map_set"),
(self.map_set_owned, "map_set_owned"),
(self.map_has, "map_has"),
(self.map_keys, "map_keys"),
(self.map_entries, "map_entries"),
(self.map_len, "map_len"),
(self.map_from_list, "map_from_list"),
(self.vec_from_list, "vec_from_list"),
(self.vec_get, "vec_get"),
(self.vec_len, "vec_len"),
(self.vec_set, "vec_set"),
(self.vec_new, "vec_new"),
(self.vec_to_list, "vec_to_list"),
(self.str_len, "str_len"),
(self.str_byte_len, "str_byte_len"),
(self.str_find, "str_find"),
(self.str_starts_with, "str_starts_with"),
(self.str_ends_with, "str_ends_with"),
(self.str_contains, "str_contains"),
(self.str_char_at, "str_char_at"),
(self.char_from_code, "char_from_code"),
(self.char_to_code, "char_to_code"),
(self.byte_to_hex, "byte_to_hex"),
(self.byte_from_hex, "byte_from_hex"),
(self.str_trim, "str_trim"),
(self.str_slice, "str_slice"),
(self.str_chars, "str_chars"),
(self.str_split, "str_split"),
(self.str_join, "str_join"),
(self.str_replace, "str_replace"),
(self.str_to_lower, "str_to_lower"),
(self.str_to_upper, "str_to_upper"),
(self.int_from_str, "int_from_str"),
(self.float_from_str, "float_from_str"),
(self.buffer_new, "buffer_new"),
(self.buffer_append_str, "buffer_append_str"),
(self.buffer_finalize, "buffer_finalize"),
]
}
}
#[derive(Default)]
struct TypeRegistry {
entries: Vec<(Vec<ValType>, Vec<ValType>)>,
}
impl TypeRegistry {
fn intern(
&mut self,
type_section: &mut TypeSection,
params: &[ValType],
results: &[ValType],
) -> u32 {
if let Some((idx, _)) = self
.entries
.iter()
.enumerate()
.find(|(_, (ps, rs))| ps.as_slice() == params && rs.as_slice() == results)
{
return idx as u32;
}
let idx = self.entries.len() as u32;
type_section
.ty()
.function(params.to_vec(), results.to_vec());
self.entries.push((params.to_vec(), results.to_vec()));
idx
}
fn count(&self) -> u32 {
self.entries.len() as u32
}
}
#[derive(Debug, Clone, Copy)]
pub struct RtTypeIndices {
pub alloc: u32, pub i32_to_empty: u32, pub wrap_i64: u32, pub wrap_f64: u32, pub wrap_i32: u32, pub unwrap_i64: u32, pub unwrap_f64: u32, pub unwrap_i32: u32, pub obj_kind: u32, pub obj_tag: u32, pub obj_meta: u32, pub obj_field_i64: u32, pub obj_field_f64: u32, pub obj_field_i32: u32, pub list_cons_i64: u32, pub list_cons_f64: u32, pub print_i64: u32, pub print_f64: u32, pub print_i32: u32, pub int_to_str: u32, pub float_to_str: u32, pub fd_write_buf: u32, pub wasi_fd_write: u32, pub i32_i32_to_i32: u32, pub i64_i32_to_i32: u32, pub i64_to_i32: u32, pub f64_to_i32: u32, pub i32_i64_to_i32: u32, pub i32_i64_i32_to_i32: u32, pub i32_i32_i64_to_i32: u32, pub i32_i32_i64_i32_to_i32: u32, pub i32_i64_i32_i64_i32_to_i32: u32, pub i32_i64_i64_to_i32: u32, pub i64_i64_to_i32: u32, pub i64_i64_i32_to_i32: u32, pub f64_to_f64: u32, pub f64_f64_to_f64: u32, pub i32_i32_i32_to_i32: u32, pub empty_to_i32: u32, pub empty_to_i32_i32: u32, pub i32_to_i32_i32: u32, pub i32_i64_to_empty: u32, pub i32_i32_i32_i32_to_empty: u32, pub i32_i32_to_i64_i32_i32: u32, pub i32x8_to_i64_i32_i32: u32, pub i32x8_to_i64_i32_i32_i32: u32, pub i32_i64_to_i32_i32: u32, pub i64_i64_to_i64: u32, pub empty_to_i64: u32, pub empty_to_f64: u32, pub empty_to_empty: u32, pub count: u32, }
pub fn emit_base_type_section(type_section: &mut TypeSection) -> RtTypeIndices {
let mut registry = TypeRegistry::default();
let alloc = registry.intern(type_section, &[ValType::I32], &[ValType::I32]);
let i32_to_empty = registry.intern(type_section, &[ValType::I32], &[]);
let wrap_i64 = registry.intern(
type_section,
&[ValType::I32, ValType::I64, ValType::I32],
&[ValType::I32],
);
let wrap_f64 = registry.intern(type_section, &[ValType::I32, ValType::F64], &[ValType::I32]);
let wrap_i32 = registry.intern(
type_section,
&[ValType::I32, ValType::I32, ValType::I32],
&[ValType::I32],
);
let unwrap_i64 = registry.intern(type_section, &[ValType::I32], &[ValType::I64]);
let unwrap_f64 = registry.intern(type_section, &[ValType::I32], &[ValType::F64]);
let unwrap_i32 = registry.intern(type_section, &[ValType::I32], &[ValType::I32]);
let obj_field_i64 =
registry.intern(type_section, &[ValType::I32, ValType::I32], &[ValType::I64]);
let obj_field_f64 =
registry.intern(type_section, &[ValType::I32, ValType::I32], &[ValType::F64]);
let list_cons_i64 = registry.intern(
type_section,
&[ValType::I64, ValType::I32, ValType::I32],
&[ValType::I32],
);
let list_cons_f64 =
registry.intern(type_section, &[ValType::F64, ValType::I32], &[ValType::I32]);
let print_i64 = registry.intern(type_section, &[ValType::I64], &[]);
let print_f64 = registry.intern(type_section, &[ValType::F64], &[]);
let print_i32 = registry.intern(type_section, &[ValType::I32], &[]);
let fd_write_buf = registry.intern(type_section, &[ValType::I32, ValType::I32], &[]);
let wasi_fd_write = registry.intern(
type_section,
&[ValType::I32, ValType::I32, ValType::I32, ValType::I32],
&[ValType::I32],
);
let i32_i32_to_i32 =
registry.intern(type_section, &[ValType::I32, ValType::I32], &[ValType::I32]);
let i64_i32_to_i32 =
registry.intern(type_section, &[ValType::I64, ValType::I32], &[ValType::I32]);
let i64_to_i32 = registry.intern(type_section, &[ValType::I64], &[ValType::I32]);
let f64_to_i32 = registry.intern(type_section, &[ValType::F64], &[ValType::I32]);
let i32_i64_to_i32 =
registry.intern(type_section, &[ValType::I32, ValType::I64], &[ValType::I32]);
let i32_i64_i32_to_i32 = registry.intern(
type_section,
&[ValType::I32, ValType::I64, ValType::I32],
&[ValType::I32],
);
let i32_i32_i64_to_i32 = registry.intern(
type_section,
&[ValType::I32, ValType::I32, ValType::I64],
&[ValType::I32],
);
let i32_i32_i64_i32_to_i32 = registry.intern(
type_section,
&[ValType::I32, ValType::I32, ValType::I64, ValType::I32],
&[ValType::I32],
);
let i32_i64_i32_i64_i32_to_i32 = registry.intern(
type_section,
&[
ValType::I32,
ValType::I64,
ValType::I32,
ValType::I64,
ValType::I32,
],
&[ValType::I32],
);
let i32_i64_i64_to_i32 = registry.intern(
type_section,
&[ValType::I32, ValType::I64, ValType::I64],
&[ValType::I32],
);
let i64_i64_to_i32 =
registry.intern(type_section, &[ValType::I64, ValType::I64], &[ValType::I32]);
let i64_i64_i32_to_i32 = registry.intern(
type_section,
&[ValType::I64, ValType::I64, ValType::I32],
&[ValType::I32],
);
let f64_to_f64 = registry.intern(type_section, &[ValType::F64], &[ValType::F64]);
let f64_f64_to_f64 =
registry.intern(type_section, &[ValType::F64, ValType::F64], &[ValType::F64]);
let i32_i32_i32_to_i32 = registry.intern(
type_section,
&[ValType::I32, ValType::I32, ValType::I32],
&[ValType::I32],
);
let empty_to_i32 = registry.intern(type_section, &[], &[ValType::I32]);
let empty_to_i32_i32 = registry.intern(type_section, &[], &[ValType::I32, ValType::I32]);
let i32_to_i32_i32 =
registry.intern(type_section, &[ValType::I32], &[ValType::I32, ValType::I32]);
let i32_i64_to_empty = registry.intern(type_section, &[ValType::I32, ValType::I64], &[]);
let i32_i32_i32_i32_to_empty = registry.intern(
type_section,
&[ValType::I32, ValType::I32, ValType::I32, ValType::I32],
&[],
);
let i32_i32_to_i64_i32_i32 = registry.intern(
type_section,
&[ValType::I32, ValType::I32],
&[ValType::I64, ValType::I32, ValType::I32],
);
let i32x8_to_i64_i32_i32 = registry.intern(
type_section,
&[
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
],
&[ValType::I64, ValType::I32, ValType::I32],
);
let i32x8_to_i64_i32_i32_i32 = registry.intern(
type_section,
&[
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
],
&[ValType::I64, ValType::I32, ValType::I32, ValType::I32],
);
let i32_i64_to_i32_i32 = registry.intern(
type_section,
&[ValType::I32, ValType::I64],
&[ValType::I32, ValType::I32],
);
let i64_i64_to_i64 =
registry.intern(type_section, &[ValType::I64, ValType::I64], &[ValType::I64]);
let empty_to_i64 = registry.intern(type_section, &[], &[ValType::I64]);
let empty_to_f64 = registry.intern(type_section, &[], &[ValType::F64]);
let empty_to_empty = registry.intern(type_section, &[], &[]);
RtTypeIndices {
alloc,
i32_to_empty,
wrap_i64,
wrap_f64,
wrap_i32,
unwrap_i64,
unwrap_f64,
unwrap_i32,
obj_kind: unwrap_i32,
obj_tag: unwrap_i32,
obj_meta: unwrap_i32,
obj_field_i64,
obj_field_f64,
obj_field_i32: i32_i32_to_i32,
list_cons_i64,
list_cons_f64,
print_i64,
print_f64,
print_i32,
int_to_str: i64_i32_to_i32,
float_to_str: list_cons_f64,
fd_write_buf,
wasi_fd_write,
i32_i32_to_i32,
i64_i32_to_i32,
i64_to_i32,
f64_to_i32,
i32_i64_to_i32,
i32_i64_i32_to_i32,
i32_i32_i64_to_i32,
i32_i32_i64_i32_to_i32,
i32_i64_i32_i64_i32_to_i32,
i32_i64_i64_to_i32,
i64_i64_to_i32,
i64_i64_i32_to_i32,
f64_to_f64,
f64_f64_to_f64,
i32_i32_i32_to_i32,
empty_to_i32,
empty_to_i32_i32,
i32_to_i32_i32,
i32_i64_to_empty,
i32_i32_i32_i32_to_empty,
i32_i32_to_i64_i32_i32,
i32x8_to_i64_i32_i32,
i32x8_to_i64_i32_i32_i32,
i32_i64_to_i32_i32,
i64_i64_to_i64,
empty_to_i64,
empty_to_f64,
empty_to_empty,
count: registry.count(),
}
}
pub fn lookup_type_index(
rti: &RtTypeIndices,
params: &[ValType],
results: &[ValType],
) -> Option<u32> {
if params == [ValType::I32] && results.is_empty() {
return Some(rti.i32_to_empty);
}
if params == [ValType::I32] && results == [ValType::I32] {
return Some(rti.unwrap_i32);
}
if params == [ValType::I32, ValType::I64, ValType::I32] && results == [ValType::I32] {
return Some(rti.wrap_i64);
}
if params == [ValType::I32, ValType::F64] && results == [ValType::I32] {
return Some(rti.wrap_f64);
}
if params == [ValType::I32, ValType::I32, ValType::I32] && results == [ValType::I32] {
return Some(rti.wrap_i32);
}
if params == [ValType::I32] && results == [ValType::I64] {
return Some(rti.unwrap_i64);
}
if params == [ValType::I32] && results == [ValType::F64] {
return Some(rti.unwrap_f64);
}
if params == [ValType::I32, ValType::I32] && results == [ValType::I64] {
return Some(rti.obj_field_i64);
}
if params == [ValType::I32, ValType::I32] && results == [ValType::F64] {
return Some(rti.obj_field_f64);
}
if params == [ValType::I32, ValType::I32] && results == [ValType::I32] {
return Some(rti.i32_i32_to_i32);
}
if params == [ValType::I64, ValType::I32, ValType::I32] && results == [ValType::I32] {
return Some(rti.list_cons_i64);
}
if params == [ValType::F64, ValType::I32] && results == [ValType::I32] {
return Some(rti.list_cons_f64);
}
if params == [ValType::I64] && results.is_empty() {
return Some(rti.print_i64);
}
if params == [ValType::F64] && results.is_empty() {
return Some(rti.print_f64);
}
if params == [ValType::I32] && results.is_empty() {
return Some(rti.print_i32);
}
if params == [ValType::I32, ValType::I32] && results.is_empty() {
return Some(rti.fd_write_buf);
}
if params == [ValType::I32, ValType::I32, ValType::I32, ValType::I32]
&& results == [ValType::I32]
{
return Some(rti.wasi_fd_write);
}
if params == [ValType::I64, ValType::I32] && results == [ValType::I32] {
return Some(rti.i64_i32_to_i32);
}
if params == [ValType::I64] && results == [ValType::I32] {
return Some(rti.i64_to_i32);
}
if params == [ValType::F64] && results == [ValType::I32] {
return Some(rti.f64_to_i32);
}
if params == [ValType::I32, ValType::I64] && results == [ValType::I32] {
return Some(rti.i32_i64_to_i32);
}
if params == [ValType::I32, ValType::I64, ValType::I32] && results == [ValType::I32] {
return Some(rti.i32_i64_i32_to_i32);
}
if params == [ValType::I32, ValType::I32, ValType::I64] && results == [ValType::I32] {
return Some(rti.i32_i32_i64_to_i32);
}
if params == [ValType::I32, ValType::I32, ValType::I64, ValType::I32]
&& results == [ValType::I32]
{
return Some(rti.i32_i32_i64_i32_to_i32);
}
if params
== [
ValType::I32,
ValType::I64,
ValType::I32,
ValType::I64,
ValType::I32,
]
&& results == [ValType::I32]
{
return Some(rti.i32_i64_i32_i64_i32_to_i32);
}
if params == [ValType::I32, ValType::I64, ValType::I64] && results == [ValType::I32] {
return Some(rti.i32_i64_i64_to_i32);
}
if params == [ValType::I64, ValType::I64] && results == [ValType::I32] {
return Some(rti.i64_i64_to_i32);
}
if params == [ValType::I64, ValType::I64, ValType::I32] && results == [ValType::I32] {
return Some(rti.i64_i64_i32_to_i32);
}
if params == [ValType::F64] && results == [ValType::F64] {
return Some(rti.f64_to_f64);
}
if params == [ValType::F64, ValType::F64] && results == [ValType::F64] {
return Some(rti.f64_f64_to_f64);
}
if params == [ValType::I32, ValType::I32, ValType::I32] && results == [ValType::I32] {
return Some(rti.i32_i32_i32_to_i32);
}
if params.is_empty() && results == [ValType::I32] {
return Some(rti.empty_to_i32);
}
if params.is_empty() && results == [ValType::I32, ValType::I32] {
return Some(rti.empty_to_i32_i32);
}
if params == [ValType::I32] && results == [ValType::I32, ValType::I32] {
return Some(rti.i32_to_i32_i32);
}
if params == [ValType::I32, ValType::I64] && results.is_empty() {
return Some(rti.i32_i64_to_empty);
}
if params == [ValType::I32, ValType::I32, ValType::I32, ValType::I32] && results.is_empty() {
return Some(rti.i32_i32_i32_i32_to_empty);
}
if params == [ValType::I32, ValType::I32]
&& results == [ValType::I64, ValType::I32, ValType::I32]
{
return Some(rti.i32_i32_to_i64_i32_i32);
}
if params
== [
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
]
&& results == [ValType::I64, ValType::I32, ValType::I32]
{
return Some(rti.i32x8_to_i64_i32_i32);
}
if params
== [
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
ValType::I32,
]
&& results == [ValType::I64, ValType::I32, ValType::I32, ValType::I32]
{
return Some(rti.i32x8_to_i64_i32_i32_i32);
}
if params == [ValType::I32, ValType::I64] && results == [ValType::I32, ValType::I32] {
return Some(rti.i32_i64_to_i32_i32);
}
if params == [ValType::I64, ValType::I64] && results == [ValType::I64] {
return Some(rti.i64_i64_to_i64);
}
if params.is_empty() && results == [ValType::I64] {
return Some(rti.empty_to_i64);
}
if params.is_empty() && results == [ValType::F64] {
return Some(rti.empty_to_f64);
}
if params.is_empty() && results.is_empty() {
return Some(rti.empty_to_empty);
}
None
}
pub fn rt_type_index(
_rt: &RuntimeFuncIndices,
_rti: &RtTypeIndices,
func_idx: u32,
import_func_count: u32,
) -> u32 {
panic!(
"Unknown runtime function index: {} (base={})",
func_idx, import_func_count
);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn base_type_section_interns_shared_signatures() {
let mut type_section = TypeSection::new();
let rti = emit_base_type_section(&mut type_section);
assert_eq!(rti.alloc, rti.unwrap_i32);
assert_eq!(rti.obj_kind, rti.unwrap_i32);
assert_eq!(rti.obj_tag, rti.unwrap_i32);
assert_eq!(rti.obj_meta, rti.unwrap_i32);
assert_eq!(rti.list_cons_f64, rti.float_to_str);
}
#[test]
fn abi_lookup_covers_effect_signatures() {
let mut type_section = TypeSection::new();
let rti = emit_base_type_section(&mut type_section);
assert_eq!(
lookup_type_index(&rti, &[ValType::I64, ValType::I64], &[ValType::I64]),
Some(rti.i64_i64_to_i64)
);
assert_eq!(
lookup_type_index(&rti, &[], &[ValType::I64]),
Some(rti.empty_to_i64)
);
assert_eq!(
lookup_type_index(
&rti,
&[ValType::I32, ValType::I64],
&[ValType::I32, ValType::I32]
),
Some(rti.i32_i64_to_i32_i32)
);
}
}