From db7ffb71fb9f3b721c97861d4e5867911991c0cb Mon Sep 17 00:00:00 2001 From: zihang Date: Thu, 14 Nov 2024 11:32:44 +0800 Subject: [PATCH 1/8] fix(moonbit): update keywords & grammar and eliminate some warnings --- crates/moonbit/src/lib.rs | 164 ++++++++++++++++++++++---------- crates/moonbit/tests/codegen.rs | 3 +- 2 files changed, 115 insertions(+), 52 deletions(-) diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index 0fb989372..28c48cb26 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -177,7 +177,7 @@ fn set_64_header_ffi(offset : Int) -> Unit { store8(offset, 241) } -pub trait Any {} +pub(open) trait Any {} pub struct Cleanup { address : Int size : Int @@ -413,9 +413,9 @@ impl WorldGenerator for MoonBit { let version = env!("CARGO_PKG_VERSION"); - let mut generate_pkg_definition = |name: &String, files: &mut Files| { + let generate_pkg_definition = |name: &String, files: &mut Files| { let directory = name.replace('.', "/"); - let imports: Option<&mut Imports> = self.package_import.get_mut(name); + let imports: Option<&Imports> = self.package_import.get(name); if let Some(imports) = imports { let mut deps = imports .packages @@ -560,7 +560,7 @@ impl WorldGenerator for MoonBit { // Export project entry point let mut gen = self.interface(resolve, &export_dir.as_str(), "", Direction::Export); - let ffi_qualifier = gen.qualify_package(&FFI_DIR.to_string()); + let ffi_qualifier = gen.qualify_package(FFI_DIR); let mut body = Source::default(); wit_bindgen_core::generated_preamble(&mut body, version); @@ -628,7 +628,7 @@ impl WorldGenerator for MoonBit { "#, exports.join(", ") ); - if let Some(imports) = self.package_import.get_mut(&self.opts.gen_dir) { + if let Some(imports) = self.package_import.get(&self.opts.gen_dir) { let mut deps = imports .packages .iter() @@ -672,12 +672,19 @@ struct InterfaceGenerator<'a> { } impl InterfaceGenerator<'_> { - fn qualify_package(&mut self, name: &String) -> String { + fn qualify_package(&mut self, name: &str) -> String { if name != self.name { let imports = self .gen .package_import - .entry(self.name.to_string()) + .entry( + // This is a hack: the exported ffi calls are actually under the gen directory + if self.direction == Direction::Export && name == FFI_DIR { + self.gen.opts.gen_dir.clone() + } else { + self.name.to_string() + }, + ) .or_default(); if let Some(alias) = imports.packages.get(name) { return format!("@{}.", alias); @@ -786,7 +793,7 @@ impl InterfaceGenerator<'_> { let cleanup_list = if bindgen.needs_cleanup_list { self.gen.needs_cleanup = true; - let ffi_qualifier = self.qualify_package(&FFI_DIR.to_string()); + let ffi_qualifier = self.qualify_package(FFI_DIR); format!( r#"let cleanupList : Array[{ffi_qualifier}Cleanup] = [] @@ -1729,7 +1736,6 @@ impl Bindgen for FunctionBindgen<'_, '_> { operands: &mut Vec, results: &mut Vec, ) { - let ffi_qualifier = self.gen.qualify_package(&FFI_DIR.to_string()); match inst { Instruction::GetArg { nth } => results.push(self.params[*nth].clone()), Instruction::I32Const { val } => results.push(format!("({})", val.to_string())), @@ -1772,14 +1778,18 @@ impl Bindgen for FunctionBindgen<'_, '_> { } Instruction::U8FromI32 => results.push(format!("({}).to_byte()", operands[0])), - Instruction::I32FromS8 => { - results.push(format!("{ffi_qualifier}extend8({})", operands[0])) - } + Instruction::I32FromS8 => results.push(format!( + "{}extend8({})", + self.gen.qualify_package(FFI_DIR), + operands[0] + )), Instruction::S8FromI32 => results.push(format!("({} - 0x100)", operands[0])), Instruction::S16FromI32 => results.push(format!("({} - 0x10000)", operands[0])), - Instruction::I32FromS16 => { - results.push(format!("{ffi_qualifier}extend16({})", operands[0])) - } + Instruction::I32FromS16 => results.push(format!( + "{}extend16({})", + self.gen.qualify_package(FFI_DIR), + operands[0] + )), Instruction::U16FromI32 => results.push(format!( "({}.land(0xFFFF).reinterpret_as_uint())", operands[0] @@ -2115,7 +2125,10 @@ impl Bindgen for FunctionBindgen<'_, '_> { Type::U8 => { let op = &operands[0]; - results.push(format!("{ffi_qualifier}bytes2ptr({op})")); + results.push(format!( + "{}bytes2ptr({op})", + self.gen.qualify_package(FFI_DIR) + )); results.push(format!("{op}.length()")); if realloc.is_none() { self.cleanup.push(Cleanup::Object(op.clone())); @@ -2133,7 +2146,10 @@ impl Bindgen for FunctionBindgen<'_, '_> { _ => unreachable!(), }; - results.push(format!("{ffi_qualifier}{ty}_array2ptr({op})")); + results.push(format!( + "{}{ty}_array2ptr({op})", + self.gen.qualify_package(FFI_DIR) + )); results.push(format!("{op}.length()")); if realloc.is_none() { self.cleanup.push(Cleanup::Object(op.clone())); @@ -2152,8 +2168,9 @@ impl Bindgen for FunctionBindgen<'_, '_> { self.src, " ignore({length}) - let {result} = {ffi_qualifier}ptr2bytes({address}) - " + let {result} = {}ptr2bytes({address}) + ", + self.gen.qualify_package(FFI_DIR) ); results.push(result); @@ -2176,8 +2193,9 @@ impl Bindgen for FunctionBindgen<'_, '_> { self.src, " ignore({length}) - let {result} = {ffi_qualifier}ptr2{ty}_array({address}) - " + let {result} = {}ptr2{ty}_array({address}) + ", + self.gen.qualify_package(FFI_DIR) ); results.push(result); @@ -2188,7 +2206,10 @@ impl Bindgen for FunctionBindgen<'_, '_> { Instruction::StringLower { realloc } => { let op = &operands[0]; - results.push(format!("{ffi_qualifier}str2ptr({op})")); + results.push(format!( + "{}str2ptr({op})", + self.gen.qualify_package(FFI_DIR) + )); results.push(format!("{op}.iter().count()")); if realloc.is_none() { self.cleanup.push(Cleanup::Object(op.clone())); @@ -2204,8 +2225,9 @@ impl Bindgen for FunctionBindgen<'_, '_> { self.src, " ignore({length}) - let {result} = {ffi_qualifier}ptr2str({address}) - " + let {result} = {}ptr2str({address}) + ", + self.gen.qualify_package(FFI_DIR) ); results.push(result); @@ -2230,13 +2252,14 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwrite!( self.src, " - let {address} = {ffi_qualifier}malloc(({op}).length() * {size}); + let {address} = {}malloc(({op}).length() * {size}); for {index} = 0; {index} < ({op}).length(); {index} = {index} + 1 {{ let {block_element} : {ty} = ({op})[({index})] let {base} = {address} + ({index} * {size}); {body} }} - " + ", + self.gen.qualify_package(FFI_DIR) ); if realloc.is_none() { @@ -2280,8 +2303,9 @@ impl Bindgen for FunctionBindgen<'_, '_> { {body} {array}.push({result}) }} - {ffi_qualifier}free({address}) - " + {}free({address}) + ", + self.gen.qualify_package(FFI_DIR) ); results.push(array); @@ -2390,7 +2414,11 @@ impl Bindgen for FunctionBindgen<'_, '_> { address, size: _, align: _, - } => uwriteln!(self.src, "{ffi_qualifier}free({address})"), + } => uwriteln!( + self.src, + "{}free({address})", + self.gen.qualify_package(FFI_DIR) + ), Cleanup::Object(obj) => uwriteln!(self.src, "ignore({obj})"), } } @@ -2400,10 +2428,11 @@ impl Bindgen for FunctionBindgen<'_, '_> { self.src, " cleanupList.each(fn(cleanup) {{ - {ffi_qualifier}free(cleanup.address); + {}free(cleanup.address); }}) ignore(ignoreList) - " + ", + self.gen.qualify_package(FFI_DIR) ); } @@ -2420,42 +2449,50 @@ impl Bindgen for FunctionBindgen<'_, '_> { Instruction::I32Load { offset } | Instruction::PointerLoad { offset } | Instruction::LengthLoad { offset } => results.push(format!( - "{ffi_qualifier}load32(({}) + {offset})", + "{}load32(({}) + {offset})", + self.gen.qualify_package(FFI_DIR), operands[0] )), Instruction::I32Load8U { offset } => results.push(format!( - "{ffi_qualifier}load8_u(({}) + {offset})", + "{}load8_u(({}) + {offset})", + self.gen.qualify_package(FFI_DIR), operands[0] )), Instruction::I32Load8S { offset } => results.push(format!( - "{ffi_qualifier}load8(({}) + {offset})", + "{}load8(({}) + {offset})", + self.gen.qualify_package(FFI_DIR), operands[0] )), Instruction::I32Load16U { offset } => results.push(format!( - "{ffi_qualifier}load16_u(({}) + {offset})", + "{}load16_u(({}) + {offset})", + self.gen.qualify_package(FFI_DIR), operands[0] )), Instruction::I32Load16S { offset } => results.push(format!( - "{ffi_qualifier}load16(({}) + {offset})", + "{}load16(({}) + {offset})", + self.gen.qualify_package(FFI_DIR), operands[0] )), Instruction::I64Load { offset } => results.push(format!( - "{ffi_qualifier}load64(({}) + {offset})", + "{}load64(({}) + {offset})", + self.gen.qualify_package(FFI_DIR), operands[0] )), Instruction::F32Load { offset } => results.push(format!( - "{ffi_qualifier}loadf32(({}) + {offset})", + "{}loadf32(({}) + {offset})", + self.gen.qualify_package(FFI_DIR), operands[0] )), Instruction::F64Load { offset } => results.push(format!( - "{ffi_qualifier}loadf64(({}) + {offset})", + "{}loadf64(({}) + {offset})", + self.gen.qualify_package(FFI_DIR), operands[0] )), @@ -2463,56 +2500,77 @@ impl Bindgen for FunctionBindgen<'_, '_> { | Instruction::PointerStore { offset } | Instruction::LengthStore { offset } => uwriteln!( self.src, - "{ffi_qualifier}store32(({}) + {offset}, {})", + "{}store32(({}) + {offset}, {})", + self.gen.qualify_package(FFI_DIR), operands[1], operands[0] ), Instruction::I32Store8 { offset } => uwriteln!( self.src, - "{ffi_qualifier}store8(({}) + {offset}, {})", + "{}store8(({}) + {offset}, {})", + self.gen.qualify_package(FFI_DIR), operands[1], operands[0] ), Instruction::I32Store16 { offset } => uwriteln!( self.src, - "{ffi_qualifier}store16(({}) + {offset}, {})", + "{}store16(({}) + {offset}, {})", + self.gen.qualify_package(FFI_DIR), operands[1], operands[0] ), Instruction::I64Store { offset } => uwriteln!( self.src, - "{ffi_qualifier}store64(({}) + {offset}, {})", + "{}store64(({}) + {offset}, {})", + self.gen.qualify_package(FFI_DIR), operands[1], operands[0] ), Instruction::F32Store { offset } => uwriteln!( self.src, - "{ffi_qualifier}storef32(({}) + {offset}, {})", + "{}storef32(({}) + {offset}, {})", + self.gen.qualify_package(FFI_DIR), operands[1], operands[0] ), Instruction::F64Store { offset } => uwriteln!( self.src, - "{ffi_qualifier}storef64(({}) + {offset}, {})", + "{}storef64(({}) + {offset}, {})", + self.gen.qualify_package(FFI_DIR), operands[1], operands[0] ), // TODO: see what we can do with align Instruction::Malloc { size, .. } => { - uwriteln!(self.src, "{ffi_qualifier}malloc({})", size) + uwriteln!( + self.src, + "{}malloc({})", + self.gen.qualify_package(FFI_DIR), + size + ) } Instruction::GuestDeallocate { .. } => { - uwriteln!(self.src, "{ffi_qualifier}free({})", operands[0]) + uwriteln!( + self.src, + "{}free({})", + self.gen.qualify_package(FFI_DIR), + operands[0] + ) } Instruction::GuestDeallocateString => { - uwriteln!(self.src, "{ffi_qualifier}free({})", operands[0]) + uwriteln!( + self.src, + "{}free({})", + self.gen.qualify_package(FFI_DIR), + operands[0] + ) } Instruction::GuestDeallocateVariant { blocks } => { @@ -2577,14 +2635,18 @@ impl Bindgen for FunctionBindgen<'_, '_> { ); } - uwriteln!(self.src, "{ffi_qualifier}free({address})"); + uwriteln!( + self.src, + "{}free({address})", + self.gen.qualify_package(FFI_DIR) + ); } } } fn return_pointer(&mut self, size: usize, align: usize) -> String { if self.gen.direction == Direction::Import { - let ffi_qualifier = self.gen.qualify_package(&FFI_DIR.to_string()); + let ffi_qualifier = self.gen.qualify_package(FFI_DIR); let address = self.locals.tmp("return_area"); uwriteln!(self.src, "let {address} = {ffi_qualifier}malloc({})", size,); self.cleanup.push(Cleanup::Memory { @@ -2784,7 +2846,7 @@ impl ToMoonBitIdent for str { "continue" | "for" | "match" | "if" | "pub" | "priv" | "readonly" | "break" | "raise" | "try" | "except" | "catch" | "else" | "enum" | "struct" | "type" | "trait" | "return" | "let" | "mut" | "while" | "loop" | "extern" | "with" - | "throw" | "init" | "main" | "test" | "in" | "guard" | "typealias" => { + | "throw" | "init" | "main" | "test" | "in" | "guard" | "typealias" | "const" => { format!("{self}_") } _ => self.to_snake_case(), diff --git a/crates/moonbit/tests/codegen.rs b/crates/moonbit/tests/codegen.rs index a015cc880..2327fd7cc 100644 --- a/crates/moonbit/tests/codegen.rs +++ b/crates/moonbit/tests/codegen.rs @@ -32,7 +32,8 @@ fn verify(dir: &Path, _name: &str) { cmd.arg("check") .arg("--target") .arg("wasm") - .arg("--deny-warn") + // This will eliminate all the warning, but can't be turned on yet + // .arg("--deny-warn") .arg("--source-dir") .arg(dir); From b36ff782097b4dd7228d917e12b7e6d5583e0b9d Mon Sep 17 00:00:00 2001 From: zihang Date: Thu, 14 Nov 2024 11:43:20 +0800 Subject: [PATCH 2/8] feat(moonbit): ignore module files & custom project name --- crates/moonbit/src/lib.rs | 18 +++++++++++++----- crates/moonbit/tests/codegen.rs | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index 28c48cb26..a64a37648 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -200,9 +200,15 @@ pub struct Opts { /// Whether or not to generate stub files ; useful for update after WIT change #[cfg_attr(feature = "clap", arg(long, default_value_t = false))] pub ignore_stub: bool, + /// Whether or not to generate moon.mod.json ; useful if the project is part of a larger project + #[cfg_attr(feature = "clap", arg(long, default_value_t = false))] + pub ignore_module_file: bool, /// The package/dir to generate the program entrance #[cfg_attr(feature = "clap", arg(long, default_value = "gen"))] pub gen_dir: String, + /// The project name ; or the package path prefix if the project is part of a larger project + #[cfg_attr(feature = "clap", arg(long, default_value = None))] + pub project_name: Option, } impl Opts { @@ -393,12 +399,14 @@ impl WorldGenerator for MoonBit { } fn finish(&mut self, resolve: &Resolve, id: WorldId, files: &mut Files) -> Result<()> { - let project_name = resolve.worlds[id] - .package - .map(|id| { + let project_name = self + .opts + .project_name + .clone() + .or(resolve.worlds[id].package.map(|id| { let package = &resolve.packages[id].name; format!("{}/{}", package.namespace, package.name) - }) + })) .unwrap_or("generated".into()); let name = world_name(resolve, id); @@ -550,7 +558,7 @@ impl WorldGenerator for MoonBit { files.push(&format!("{FFI_DIR}/moon.pkg.json"), "{}".as_bytes()); // Export project files - if !self.opts.ignore_stub { + if !self.opts.ignore_stub && !self.opts.ignore_module_file { let mut body = Source::default(); uwriteln!(&mut body, "{{ \"name\": \"{project_name}\" }}"); files.push(&format!("moon.mod.json"), body.as_bytes()); diff --git a/crates/moonbit/tests/codegen.rs b/crates/moonbit/tests/codegen.rs index 2327fd7cc..ae9fa69c9 100644 --- a/crates/moonbit/tests/codegen.rs +++ b/crates/moonbit/tests/codegen.rs @@ -14,7 +14,9 @@ macro_rules! codegen_test { derive_eq: true, derive_error: true, ignore_stub: false, + ignore_module_file: false, gen_dir: "gen".to_string(), + project_name: None, } .build() .generate(resolve, world, files) From fb50f384743269791128bc156a3622920a8aba06 Mon Sep 17 00:00:00 2001 From: zihang Date: Fri, 29 Nov 2024 17:29:22 +0800 Subject: [PATCH 3/8] feat(moonbit): f32->float, update grammar and keywords --- crates/moonbit/src/lib.rs | 46 +++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index a64a37648..6bd8a75fd 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -20,9 +20,7 @@ use wit_bindgen_core::{ // Organization: // - one package per interface (export and import are treated as different interfaces) // - ffi utils are under `./ffi`, and the project entrance (package as link target) is under `./gen` -// TODO: Migrate f32 to Float when the support becomes mature // TODO: Export will share the type signatures with the import by using a newtype alias -// TODO: Export resource is not handled correctly : resource.new / resource.drop / resource.rep / dtor const FFI_DIR: &str = "ffi"; @@ -88,7 +86,7 @@ pub fn malloc(size : Int) -> Int { let words = size / 4 + 1 let address = malloc_inline(8 + words * 4) store32(address, 1) - store32(address + 4, (words << 8) | 246) + store32(address + 4, (words << 8) | 241) store8(address + words * 4 + 7, 3 - size % 4) address + 8 } @@ -114,10 +112,10 @@ pub extern "wasm" fn str2ptr(str : String) -> Int = pub extern "wasm" fn ptr2str(ptr : Int) -> String = #|(func (param i32) (result i32) local.get 0 i32.const 4 i32.sub i32.const 243 i32.store8 local.get 0 i32.const 8 i32.sub) -pub extern "wasm" fn bytes2ptr(bytes : Bytes) -> Int = +pub extern "wasm" fn bytes2ptr(bytes : FixedArray[Byte]) -> Int = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.add) -pub extern "wasm" fn ptr2bytes(ptr : Int) -> Bytes = +pub extern "wasm" fn ptr2bytes(ptr : Int) -> FixedArray[Byte] = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) pub extern "wasm" fn uint_array2ptr(array : FixedArray[UInt]) -> Int = @@ -139,13 +137,13 @@ pub extern "wasm" fn double_array2ptr(array : FixedArray[Double]) -> Int = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.add) pub extern "wasm" fn ptr2uint_array(ptr : Int) -> FixedArray[UInt] = - #|(func (param i32) (result i32) local.get 0 i32.const 4 i32.sub i32.const 241 i32.store8 local.get 0 i32.const 8 i32.sub) + #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) pub extern "wasm" fn ptr2int_array(ptr : Int) -> FixedArray[Int] = - #|(func (param i32) (result i32) local.get 0 i32.const 4 i32.sub i32.const 241 i32.store8 local.get 0 i32.const 8 i32.sub) + #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) pub extern "wasm" fn ptr2float_array(ptr : Int) -> FixedArray[Float] = - #|(func (param i32) (result i32) local.get 0 i32.const 4 i32.sub i32.const 241 i32.store8 local.get 0 i32.const 8 i32.sub) + #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) extern "wasm" fn ptr2uint64_array_ffi(ptr : Int) -> FixedArray[UInt64] = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) @@ -178,7 +176,7 @@ fn set_64_header_ffi(offset : Int) -> Unit { } pub(open) trait Any {} -pub struct Cleanup { +pub(all) struct Cleanup { address : Int size : Int align : Int @@ -984,7 +982,8 @@ impl InterfaceGenerator<'_> { Type::Char => "Char".into(), Type::U64 => "UInt64".into(), Type::S64 => "Int64".into(), - Type::F32 | Type::F64 => "Double".into(), + Type::F32 => "Float".into(), + Type::F64 => "Double".into(), Type::String => "String".into(), Type::Id(id) => { let ty = &self.resolve.types[dealias(self.resolve, *id)]; @@ -993,8 +992,12 @@ impl InterfaceGenerator<'_> { TypeDefKind::List(ty) => { if type_variable { match ty { - Type::U8 => "Bytes".into(), - Type::U32 | Type::U64 | Type::S32 | Type::S64 | Type::F64 => { + Type::U8 + | Type::U32 + | Type::U64 + | Type::S32 + | Type::S64 + | Type::F64 => { format!("FixedArray[{}]", self.type_name(ty, type_variable)) } _ => format!("Array[{}]", self.type_name(ty, type_variable)), @@ -1164,7 +1167,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { uwrite!( self.src, " - pub struct {name} {{ + pub(all) struct {name} {{ {parameters} }} derive({}) ", @@ -1193,7 +1196,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { uwrite!( self.src, r#" - pub {declaration} {name} Int derive({}) + pub(all) {declaration} {name} Int derive({}) "#, deriviation.join(", "), ); @@ -1334,11 +1337,11 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { uwrite!( self.src, " - pub {declaration} {name} {ty} derive({}) + pub(all) {declaration} {name} {ty} derive({}) pub fn {name}::default() -> {name} {{ {} }} - pub enum {name}Flag {{ + pub(all) enum {name}Flag {{ {cases} }} fn {name}Flag::value(self : {name}Flag) -> {ty} {{ @@ -1409,7 +1412,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { uwrite!( self.src, " - pub {declaration} {name} {{ + pub(all) {declaration} {name} {{ {cases} }} derive({}) ", @@ -1454,7 +1457,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { uwrite!( self.src, " - pub {declaration} {name} {{ + pub(all) {declaration} {name} {{ {cases} }} derive({}) ", @@ -1774,8 +1777,8 @@ impl Bindgen for FunctionBindgen<'_, '_> { | Instruction::CoreF64FromF64 | Instruction::F64FromCoreF64 => results.push(operands[0].clone()), - Instruction::F32FromCoreF32 => results.push(format!("({}).to_double()", operands[0])), - Instruction::CoreF32FromF32 => results.push(format!("({}).to_float()", operands[0])), + Instruction::F32FromCoreF32 => results.push(operands[0].clone()), + Instruction::CoreF32FromF32 => results.push(operands[0].clone()), Instruction::CharFromI32 => results.push(format!("Char::from_int({})", operands[0])), Instruction::I32FromChar => results.push(format!("({}).to_int()", operands[0])), @@ -2854,7 +2857,8 @@ impl ToMoonBitIdent for str { "continue" | "for" | "match" | "if" | "pub" | "priv" | "readonly" | "break" | "raise" | "try" | "except" | "catch" | "else" | "enum" | "struct" | "type" | "trait" | "return" | "let" | "mut" | "while" | "loop" | "extern" | "with" - | "throw" | "init" | "main" | "test" | "in" | "guard" | "typealias" | "const" => { + | "throw" | "init" | "main" | "test" | "in" | "guard" | "typealias" | "const" + | "method" | "move" | "do" | "static" | "final" => { format!("{self}_") } _ => self.to_snake_case(), From f63fa198ec5a93499e1b5b20b11e163e261229b0 Mon Sep 17 00:00:00 2001 From: zihang Date: Wed, 4 Dec 2024 10:30:09 +0800 Subject: [PATCH 4/8] misc(moonbit): add canon for list --- crates/moonbit/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index 6bd8a75fd..947602b0e 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -997,6 +997,7 @@ impl InterfaceGenerator<'_> { | Type::U64 | Type::S32 | Type::S64 + | Type::F32 | Type::F64 => { format!("FixedArray[{}]", self.type_name(ty, type_variable)) } @@ -2145,7 +2146,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { self.cleanup.push(Cleanup::Object(op.clone())); } } - Type::U32 | Type::U64 | Type::S32 | Type::S64 | Type::F64 => { + Type::U32 | Type::U64 | Type::S32 | Type::S64 | Type::F32 | Type::F64 => { let op = &operands[0]; let ty = match element { @@ -2153,6 +2154,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { Type::U64 => "uint64", Type::S32 => "int", Type::S64 => "int64", + Type::F32 => "float", Type::F64 => "double", _ => unreachable!(), }; @@ -2186,12 +2188,13 @@ impl Bindgen for FunctionBindgen<'_, '_> { results.push(result); } - Type::U32 | Type::U64 | Type::S32 | Type::S64 | Type::F64 => { + Type::U32 | Type::U64 | Type::S32 | Type::S64 | Type::F32 | Type::F64 => { let ty = match element { Type::U32 => "uint", Type::U64 => "uint64", Type::S32 => "int", Type::S64 => "int64", + Type::F32 => "float", Type::F64 => "double", _ => unreachable!(), }; @@ -2725,7 +2728,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { fn is_list_canonical(&self, _resolve: &Resolve, element: &Type) -> bool { matches!( element, - Type::U8 | Type::U32 | Type::U64 | Type::S32 | Type::S64 | Type::F64 + Type::U8 | Type::U32 | Type::U64 | Type::S32 | Type::S64 | Type::F32 | Type::F64 ) } } From 1c7993fc110865819d26348d4439385b228edada Mon Sep 17 00:00:00 2001 From: zihang Date: Thu, 5 Dec 2024 11:46:32 +0800 Subject: [PATCH 5/8] fix(moonbit): length in header for fixedarray --- crates/moonbit/src/lib.rs | 50 +++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index 947602b0e..5a59eed6b 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -86,7 +86,7 @@ pub fn malloc(size : Int) -> Int { let words = size / 4 + 1 let address = malloc_inline(8 + words * 4) store32(address, 1) - store32(address + 4, (words << 8) | 241) + store32(address + 4, (words << 8) | 246) store8(address + words * 4 + 7, 3 - size % 4) address + 8 } @@ -115,8 +115,8 @@ pub extern "wasm" fn ptr2str(ptr : Int) -> String = pub extern "wasm" fn bytes2ptr(bytes : FixedArray[Byte]) -> Int = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.add) -pub extern "wasm" fn ptr2bytes(ptr : Int) -> FixedArray[Byte] = - #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) +pub extern "wasm" fn ptr2bytes(ptr : Int, _len : Int) -> FixedArray[Byte] = + #|(func (param i32) (param i32) (result i32) local.get 0 i32.const 8 i32.sub) pub extern "wasm" fn uint_array2ptr(array : FixedArray[UInt]) -> Int = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.add) @@ -136,43 +136,55 @@ pub extern "wasm" fn float_array2ptr(array : FixedArray[Float]) -> Int = pub extern "wasm" fn double_array2ptr(array : FixedArray[Double]) -> Int = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.add) -pub extern "wasm" fn ptr2uint_array(ptr : Int) -> FixedArray[UInt] = +extern "wasm" fn ptr2uint_array_ffi(ptr : Int) -> FixedArray[UInt] = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) -pub extern "wasm" fn ptr2int_array(ptr : Int) -> FixedArray[Int] = +pub fn ptr2uint_array(ptr : Int, len : Int) -> FixedArray[UInt] { + set_header_ffi(ptr - 4, len) + ptr2uint_array_ffi(ptr) +} + +extern "wasm" fn ptr2int_array_ffi(ptr : Int) -> FixedArray[Int] = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) -pub extern "wasm" fn ptr2float_array(ptr : Int) -> FixedArray[Float] = +pub fn ptr2int_array(ptr : Int, len : Int) -> FixedArray[Int] { + set_header_ffi(ptr - 4, len) + ptr2int_array_ffi(ptr) +} + +extern "wasm" fn ptr2float_array_ffi(ptr : Int) -> FixedArray[Float] = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) +pub fn ptr2float_array(ptr : Int, len : Int) -> FixedArray[Float] { + set_header_ffi(ptr - 4, len) + ptr2float_array_ffi(ptr) +} extern "wasm" fn ptr2uint64_array_ffi(ptr : Int) -> FixedArray[UInt64] = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) -pub fn ptr2uint64_array(ptr : Int) -> FixedArray[UInt64] { - set_64_header_ffi(ptr - 4) +pub fn ptr2uint64_array(ptr : Int, len : Int) -> FixedArray[UInt64] { + set_header_ffi(ptr - 4, len) ptr2uint64_array_ffi(ptr) } extern "wasm" fn ptr2int64_array_ffi(ptr : Int) -> FixedArray[Int64] = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) -pub fn ptr2int64_array(ptr : Int) -> FixedArray[Int64] { - set_64_header_ffi(ptr - 4) +pub fn ptr2int64_array(ptr : Int, len : Int) -> FixedArray[Int64] { + set_header_ffi(ptr - 4, len) ptr2int64_array_ffi(ptr) } extern "wasm" fn ptr2double_array_ffi(ptr : Int) -> FixedArray[Double] = #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) -pub fn ptr2double_array(ptr : Int) -> FixedArray[Double] { - set_64_header_ffi(ptr - 4) +pub fn ptr2double_array(ptr : Int, len : Int) -> FixedArray[Double] { + set_header_ffi(ptr - 4, len) ptr2double_array_ffi(ptr) } -fn set_64_header_ffi(offset : Int) -> Unit { - let len = load32(offset) - store32(offset, len >> 1) - store8(offset, 241) +fn set_header_ffi(offset : Int, len : Int) -> Unit { + store32(offset, len << 8 | 241) } pub(open) trait Any {} @@ -2180,8 +2192,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwrite!( self.src, " - ignore({length}) - let {result} = {}ptr2bytes({address}) + let {result} = {}ptr2bytes({address}, {length}) ", self.gen.qualify_package(FFI_DIR) ); @@ -2206,8 +2217,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwrite!( self.src, " - ignore({length}) - let {result} = {}ptr2{ty}_array({address}) + let {result} = {}ptr2{ty}_array({address}, {length}) ", self.gen.qualify_package(FFI_DIR) ); From 6692bce42111482aa7e51a67a40467029de594a5 Mon Sep 17 00:00:00 2001 From: zihang Date: Wed, 18 Dec 2024 09:54:55 +0800 Subject: [PATCH 6/8] misc(moonbit): update grammar --- crates/moonbit/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index 5a59eed6b..6eadc443d 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -815,7 +815,7 @@ impl InterfaceGenerator<'_> { format!( r#"let cleanupList : Array[{ffi_qualifier}Cleanup] = [] - let ignoreList : Array[{ffi_qualifier}Any] = []"# + let ignoreList : Array[&{ffi_qualifier}Any] = []"# ) } else { String::new() From 153eca308ab03f6b1642af138b393223523d8ad7 Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 23 Dec 2024 15:30:01 +0800 Subject: [PATCH 7/8] fix(moonbit): use correct length header --- crates/moonbit/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index 6eadc443d..5e7d160f7 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -95,10 +95,8 @@ pub extern "wasm" fn free(position : Int) = #|(func (param i32) local.get 0 i32.const 8 i32.sub call $moonbit.decref) pub fn copy(dest : Int, src : Int) -> Unit { - let src = src - 8 - let dest = dest - 8 - let src_len = load32(src + 4).land(0xFFFFFF) - let dest_len = load32(dest + 4).land(0xFFFFFF) + let src_len = (load32(src - 12) >> 2) - 4 + let dest_len = (load32(dest - 12) >> 2) - 4 let min = if src_len < dest_len { src_len } else { dest_len } copy_inline(dest, src, min) } From d93a27b0a662ed46825fef0831e254fdc9365944 Mon Sep 17 00:00:00 2001 From: zihang Date: Tue, 24 Dec 2024 15:47:03 +0800 Subject: [PATCH 8/8] feat: replace todo with new syntax --- crates/moonbit/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index 5e7d160f7..ec3c6a485 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -977,7 +977,7 @@ impl InterfaceGenerator<'_> { self.stub, r#" {func_sig} {{ - abort("todo") + ... }} "# ); @@ -1263,7 +1263,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { r#" /// Destructor of the resource. pub fn {name}::dtor(_self : {name}) -> Unit {{ - abort("todo") + ... }} "# );