From 9178f281fed6018d844ede46f35919b6860e8ba6 Mon Sep 17 00:00:00 2001 From: Christoph Hegemann Date: Sun, 10 Nov 2024 14:14:54 +0100 Subject: [PATCH] records types for imports in a non-recursive section --- crates/backend/src/codegen.rs | 1 + crates/backend/src/wasm_builder.rs | 57 +++++++------------ crates/cli/src/main.rs | 10 ++++ crates/cli/tests/run/arithmetic.nemo | 2 +- crates/cli/tests/run/poly.nemo | 5 +- crates/cli/tests/run/return.nemo | 4 +- .../cli/tests/snapshots/run@poly.nemo-2.snap | 2 +- crates/frontend/src/ir/names.rs | 12 ++-- dev/wasm-runner.ts | 1 + 9 files changed, 47 insertions(+), 47 deletions(-) diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 24a5f53f..11eb98f1 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -648,6 +648,7 @@ impl<'a> Codegen<'a> { for import in program.imports { self.builder.declare_import(import); } + self.builder.finish_imports(); // Variants need to be declared before structs for type_def in program.types.iter() { diff --git a/crates/backend/src/wasm_builder.rs b/crates/backend/src/wasm_builder.rs index d20559c9..3294056b 100644 --- a/crates/backend/src/wasm_builder.rs +++ b/crates/backend/src/wasm_builder.rs @@ -103,6 +103,8 @@ pub struct Builder<'a> { types: Vec, datas: Vec>, imports: HashMap, + // Represents the first type index that doesn't describe an import + import_ty_watermark: Option, exports: Vec, start_fn: Option, substitution: Substitution, @@ -135,6 +137,7 @@ impl<'a> Builder<'a> { closure_tys: HashMap::new(), func_refs: HashMap::new(), imports: HashMap::new(), + import_ty_watermark: None, exports: vec![], start_fn: None, substitution: Substitution::new(&[], &[]), @@ -154,31 +157,6 @@ impl<'a> Builder<'a> { // } // } - fn is_primitive_val_ty(ty: &ValType) -> bool { - matches!( - ty, - ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 - ) - } - fn is_primitive_ty(ty: &CompositeInnerType) -> Option<&FuncType> { - let CompositeInnerType::Func(func_ty) = ty else { - return None; - }; - if func_ty - .params() - .iter() - .all(|ty| Self::is_primitive_val_ty(ty)) - && func_ty - .results() - .iter() - .all(|ty| Self::is_primitive_val_ty(ty)) - { - Some(func_ty) - } else { - None - } - } - pub fn finish(self) -> (Vec, Ctx) { let mut module = Module::new(); let ctx = self.ctx; @@ -189,18 +167,17 @@ impl<'a> Builder<'a> { let mut type_section = TypeSection::new(); let mut all_field_names = IndirectNameMap::new(); - let mut subtys = vec![]; - for ty in self.types { - if let Some(func_ty) = Self::is_primitive_ty(&ty.composite_type.inner) { - type_section.ty().func_type(func_ty) - } else { - subtys.push(ty); - } - } - if !subtys.is_empty() { - type_section.ty().rec(subtys); + let import_ty_watermark = self + .import_ty_watermark + .expect("import section was never finished"); + let (imports_tys, program_tys) = self.types.split_at(import_ty_watermark as usize); + for ty in imports_tys { + let CompositeInnerType::Func(ref func_ty) = ty.composite_type.inner else { + panic!("imported type is not a function type") + }; + type_section.ty().func_type(func_ty); } - + type_section.ty().rec(program_tys.iter().cloned()); for (name, info) in self.structs { for (tys, type_idx) in &info.instances { let mut it = ctx.display_qualified_name(name); @@ -677,6 +654,14 @@ impl<'a> Builder<'a> { self.imports.get(name).map(|data| data.index) } + pub fn finish_imports(&mut self) { + assert!( + self.import_ty_watermark.is_none(), + "finish_imports called twice" + ); + self.import_ty_watermark = Some(self.types.len() as u32) + } + pub fn declare_global(&mut self, name: Name, ty: &Ty, init: ConstExpr) -> GlobalIdx { let index = self.globals.len() as u32; let val_type = self.val_ty(ty); diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index c85bd43b..83284746 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -107,6 +107,16 @@ fn main() -> Result<(), Box> { println!("{param}"); 0 })?; + linker.func_wrap("env", "log_f32", |param: f32| { + println!("{param}"); + 0 + })?; + linker.func_wrap("env", "print_char", |param: i32| { + print!("{}", char::from_u32(param as u32).unwrap()); + 0 + })?; + linker.func_wrap("env", "random", |_: i32| -> f32 { 0.0 })?; + let instance = linker.instantiate(&mut store, &module)?; let main_func = instance.get_typed_func::<(), i32>(&mut store, "main")?; let result = main_func.call(&mut store, ())?; diff --git a/crates/cli/tests/run/arithmetic.nemo b/crates/cli/tests/run/arithmetic.nemo index 67eb6e65..738e73a2 100644 --- a/crates/cli/tests/run/arithmetic.nemo +++ b/crates/cli/tests/run/arithmetic.nemo @@ -1,5 +1,5 @@ import log : fn (I32) -> Unit from log -import log_f32 : fn (F32) -> Unit from log +import log_f32 : fn (F32) -> Unit from log_f32 fn main() { log(1 + 1); diff --git a/crates/cli/tests/run/poly.nemo b/crates/cli/tests/run/poly.nemo index 03ea5de5..0daecc37 100644 --- a/crates/cli/tests/run/poly.nemo +++ b/crates/cli/tests/run/poly.nemo @@ -6,6 +6,7 @@ struct Box[a] { content : a } -fn main() -> Box[I32] { - Box #[I32] { content = 42 } +fn main() -> I32 { + let box = Box #[I32] { content = 42 }; + box.content } diff --git a/crates/cli/tests/run/return.nemo b/crates/cli/tests/run/return.nemo index 6e62a277..2d1e24a3 100644 --- a/crates/cli/tests/run/return.nemo +++ b/crates/cli/tests/run/return.nemo @@ -1,9 +1,9 @@ import log : fn (I32) -> Unit from log -import logf : fn (F32) -> Unit from log +import log_f32 : fn (F32) -> Unit from log_f32 fn main() -> I32 { log(early_return()); - logf(loop_return()); + log_f32(loop_return()); log(lambda_return()); } diff --git a/crates/cli/tests/snapshots/run@poly.nemo-2.snap b/crates/cli/tests/snapshots/run@poly.nemo-2.snap index 9ecaea63..96ec6390 100644 --- a/crates/cli/tests/snapshots/run@poly.nemo-2.snap +++ b/crates/cli/tests/snapshots/run@poly.nemo-2.snap @@ -14,6 +14,6 @@ input_file: crates/cli/tests/run/poly.nemo success: true exit_code: 0 ----- stdout ----- -[Object: null prototype] {} +42 ----- stderr ----- diff --git a/crates/frontend/src/ir/names.rs b/crates/frontend/src/ir/names.rs index 8dfea00a..e792c265 100644 --- a/crates/frontend/src/ir/names.rs +++ b/crates/frontend/src/ir/names.rs @@ -77,11 +77,13 @@ impl Ctx { ) } pub fn display_qualified_name(&self, name: Name) -> String { - format!( - "{}::{}", - self.get_module_name(name.module), - self.resolve(name).0 - ) + let module_name = self.get_module_name(name.module); + let name = self.resolve(name).0; + if module_name.is_empty() || module_name == "NOT INITIALIZED" { + name.to_string() + } else { + format!("{module_name}::{name}") + } } pub fn display_name(&self, name: Name) -> String { self.resolve(name).0 diff --git a/dev/wasm-runner.ts b/dev/wasm-runner.ts index 830027aa..c88f5a65 100644 --- a/dev/wasm-runner.ts +++ b/dev/wasm-runner.ts @@ -7,6 +7,7 @@ const encoder = new TextEncoder(); const imports = { env: { log: (arg: number) => console.log(arg), + log_f32: (arg: number) => console.log(arg), print_char: (cp: number) => Deno.stdout.writeSync(encoder.encode(String.fromCodePoint(cp))), random: () => Math.random(),