Skip to content

Commit

Permalink
records types for imports in a non-recursive section
Browse files Browse the repository at this point in the history
  • Loading branch information
kritzcreek committed Nov 10, 2024
1 parent b15f36c commit 9178f28
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 47 deletions.
1 change: 1 addition & 0 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
57 changes: 21 additions & 36 deletions crates/backend/src/wasm_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ pub struct Builder<'a> {
types: Vec<SubType>,
datas: Vec<Vec<u8>>,
imports: HashMap<Name, ImportData>,
// Represents the first type index that doesn't describe an import
import_ty_watermark: Option<TypeIdx>,
exports: Vec<Export>,
start_fn: Option<FuncIdx>,
substitution: Substitution,
Expand Down Expand Up @@ -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(&[], &[]),
Expand All @@ -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<u8>, Ctx) {
let mut module = Module::new();
let ctx = self.ctx;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ fn main() -> Result<(), Box<dyn Error + Sync + Send>> {
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, ())?;
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/tests/run/arithmetic.nemo
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
5 changes: 3 additions & 2 deletions crates/cli/tests/run/poly.nemo
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
4 changes: 2 additions & 2 deletions crates/cli/tests/run/return.nemo
Original file line number Diff line number Diff line change
@@ -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());
}

Expand Down
2 changes: 1 addition & 1 deletion crates/cli/tests/snapshots/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ input_file: crates/cli/tests/run/poly.nemo
success: true
exit_code: 0
----- stdout -----
[Object: null prototype] {}
42

----- stderr -----
12 changes: 7 additions & 5 deletions crates/frontend/src/ir/names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions dev/wasm-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down

0 comments on commit 9178f28

Please sign in to comment.