Skip to content

Commit e8a3745

Browse files
refactor(moonbit): use internal abi (#1243)
* fix(moonbit): adjust core api * refactor(moonbit): use internal abi * test(moonbit): adopt new test framework * fix(moonbit): correct bitcast behavior * test(moonbit): more test case
1 parent 5274c27 commit e8a3745

File tree

11 files changed

+469
-154
lines changed

11 files changed

+469
-154
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/moonbit/Cargo.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,4 @@ through the `wit-bindgen-cli` crate.
1515
anyhow = { workspace = true }
1616
wit-bindgen-core = { workspace = true }
1717
heck = { workspace = true }
18-
clap = { workspace = true, optional = true }
19-
20-
[dev-dependencies]
21-
test-helpers = { path = '../test-helpers' }
18+
clap = { workspace = true, optional = true }

crates/moonbit/src/lib.rs

Lines changed: 62 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,12 @@ pub extern "wasm" fn f32_to_i32(value : Float) -> Int =
7979
pub extern "wasm" fn f32_to_i64(value : Float) -> Int64 =
8080
#|(func (param f32) (result i64) local.get 0 f32.convert_i64_s)
8181
82-
extern "wasm" fn malloc_inline(size : Int) -> Int =
83-
#|(func (param i32) (result i32) local.get 0 call $moonbit.malloc)
84-
85-
pub fn malloc(size : Int) -> Int {
86-
let words = size / 4 + 1
87-
let address = malloc_inline(8 + words * 4)
88-
store32(address, 1)
89-
store32(address + 4, (words << 8) | 246)
90-
address + 8
91-
}
82+
// set pseudo header; allocate extra bytes for string
83+
pub extern "wasm" fn malloc(size : Int) -> Int =
84+
#|(func (param i32) (result i32) (local i32)
85+
#| local.get 0 i32.const 4 i32.add call $moonbit.gc.malloc
86+
#| local.tee 1 i32.const 0 call $moonbit.init_array8
87+
#| local.get 1 i32.const 8 i32.add)
9288
9389
pub extern "wasm" fn free(position : Int) =
9490
#|(func (param i32) local.get 0 i32.const 8 i32.sub call $moonbit.decref)
@@ -99,30 +95,20 @@ extern "wasm" fn copy(dest : Int, src : Int, len : Int) =
9995
pub extern "wasm" fn str2ptr(str : String) -> Int =
10096
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.add)
10197
102-
extern "wasm" fn ptr2str_ffi(ptr : Int) -> String =
103-
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub)
104-
105-
pub fn ptr2str(ptr : Int, len : Int) -> String {
106-
let words = len * 2 / 4 + 1
107-
let address = ptr - 8
108-
store32(address + 4, (words << 8) | 243)
109-
store8(address + words * 4 + 7, 3 - len * 2 % 4)
110-
ptr2str_ffi(ptr)
111-
}
98+
pub extern "wasm" fn ptr2str(ptr : Int, len : Int) -> String =
99+
#|(func (param i32) (param i32) (result i32) (local i32)
100+
#| local.get 0 i32.const 8 i32.sub local.tee 2
101+
#| local.get 1 call $moonbit.init_array16
102+
#| local.get 2)
112103
113104
pub extern "wasm" fn bytes2ptr(bytes : FixedArray[Byte]) -> Int =
114105
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.add)
115106
116-
extern "wasm" fn ptr2bytes_ffi(ptr : Int) -> FixedArray[Byte] =
117-
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub)
118-
119-
pub fn ptr2bytes(ptr : Int, len : Int) -> FixedArray[Byte] {
120-
let words = len / 4 + 1
121-
let address = ptr - 8
122-
store32(address + 4, (words << 8) | 246)
123-
store8(address + words * 4 + 7, 3 - len % 4)
124-
ptr2bytes_ffi(ptr)
125-
}
107+
pub extern "wasm" fn ptr2bytes(ptr : Int, len : Int) -> FixedArray[Byte] =
108+
#|(func (param i32) (param i32) (result i32) (local i32)
109+
#| local.get 0 i32.const 8 i32.sub local.tee 2
110+
#| local.get 1 call $moonbit.init_array8
111+
#| local.get 2)
126112
127113
pub extern "wasm" fn uint_array2ptr(array : FixedArray[UInt]) -> Int =
128114
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.add)
@@ -142,56 +128,41 @@ pub extern "wasm" fn float_array2ptr(array : FixedArray[Float]) -> Int =
142128
pub extern "wasm" fn double_array2ptr(array : FixedArray[Double]) -> Int =
143129
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.add)
144130
145-
extern "wasm" fn ptr2uint_array_ffi(ptr : Int) -> FixedArray[UInt] =
146-
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub)
147-
148-
pub fn ptr2uint_array(ptr : Int, len : Int) -> FixedArray[UInt] {
149-
set_header_ffi(ptr - 4, len)
150-
ptr2uint_array_ffi(ptr)
151-
}
152-
153-
extern "wasm" fn ptr2int_array_ffi(ptr : Int) -> FixedArray[Int] =
154-
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub)
155-
156-
pub fn ptr2int_array(ptr : Int, len : Int) -> FixedArray[Int] {
157-
set_header_ffi(ptr - 4, len)
158-
ptr2int_array_ffi(ptr)
159-
}
160-
161-
extern "wasm" fn ptr2float_array_ffi(ptr : Int) -> FixedArray[Float] =
162-
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub)
163-
164-
pub fn ptr2float_array(ptr : Int, len : Int) -> FixedArray[Float] {
165-
set_header_ffi(ptr - 4, len)
166-
ptr2float_array_ffi(ptr)
167-
}
168-
extern "wasm" fn ptr2uint64_array_ffi(ptr : Int) -> FixedArray[UInt64] =
169-
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub)
170-
171-
pub fn ptr2uint64_array(ptr : Int, len : Int) -> FixedArray[UInt64] {
172-
set_header_ffi(ptr - 4, len)
173-
ptr2uint64_array_ffi(ptr)
174-
}
175-
176-
extern "wasm" fn ptr2int64_array_ffi(ptr : Int) -> FixedArray[Int64] =
177-
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub)
178-
179-
pub fn ptr2int64_array(ptr : Int, len : Int) -> FixedArray[Int64] {
180-
set_header_ffi(ptr - 4, len)
181-
ptr2int64_array_ffi(ptr)
182-
}
183-
184-
extern "wasm" fn ptr2double_array_ffi(ptr : Int) -> FixedArray[Double] =
185-
#|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub)
186-
187-
pub fn ptr2double_array(ptr : Int, len : Int) -> FixedArray[Double] {
188-
set_header_ffi(ptr - 4, len)
189-
ptr2double_array_ffi(ptr)
190-
}
191-
192-
fn set_header_ffi(offset : Int, len : Int) -> Unit {
193-
store32(offset, len << 8 | 241)
194-
}
131+
pub extern "wasm" fn ptr2uint_array(ptr : Int, len : Int) -> FixedArray[UInt] =
132+
#|(func (param i32) (param i32) (result i32) (local i32)
133+
#| local.get 0 i32.const 8 i32.sub local.tee 2
134+
#| local.get 1 call $moonbit.init_array32
135+
#| local.get 2)
136+
137+
pub extern "wasm" fn ptr2int_array(ptr : Int, len : Int) -> FixedArray[Int] =
138+
#|(func (param i32) (param i32) (result i32) (local i32)
139+
#| local.get 0 i32.const 8 i32.sub local.tee 2
140+
#| local.get 1 call $moonbit.init_array32
141+
#| local.get 2)
142+
143+
pub extern "wasm" fn ptr2float_array(ptr : Int, len : Int) -> FixedArray[Float] =
144+
#|(func (param i32) (param i32) (result i32) (local i32)
145+
#| local.get 0 i32.const 8 i32.sub local.tee 2
146+
#| local.get 1 call $moonbit.init_array32
147+
#| local.get 2)
148+
149+
pub extern "wasm" fn ptr2uint64_array(ptr : Int, len : Int) -> FixedArray[UInt64] =
150+
#|(func (param i32) (param i32) (result i32) (local i32)
151+
#| local.get 0 i32.const 8 i32.sub local.tee 2
152+
#| local.get 1 call $moonbit.init_array64
153+
#| local.get 2)
154+
155+
pub extern "wasm" fn ptr2int64_array(ptr : Int, len : Int) -> FixedArray[Int64] =
156+
#|(func (param i32) (param i32) (result i32) (local i32)
157+
#| local.get 0 i32.const 8 i32.sub local.tee 2
158+
#| local.get 1 call $moonbit.init_array64
159+
#| local.get 2)
160+
161+
pub extern "wasm" fn ptr2double_array(ptr : Int, len : Int) -> FixedArray[Double] =
162+
#|(func (param i32) (param i32) (result i32) (local i32)
163+
#| local.get 0 i32.const 8 i32.sub local.tee 2
164+
#| local.get 1 call $moonbit.init_array64
165+
#| local.get 2)
195166
196167
pub fn cabi_realloc(
197168
src_offset : Int,
@@ -593,7 +564,10 @@ impl WorldGenerator for MoonBit {
593564
wit_bindgen_core::generated_preamble(&mut body, version);
594565
body.push_str(FFI);
595566
files.push(&format!("{FFI_DIR}/top.mbt"), indent(&body).as_bytes());
596-
files.push(&format!("{FFI_DIR}/moon.pkg.json"), "{}".as_bytes());
567+
files.push(
568+
&format!("{FFI_DIR}/moon.pkg.json"),
569+
"{ \"warn-list\": \"-44\", \"supported-targets\": [\"wasm\"] }".as_bytes(),
570+
);
597571

598572
// Export project files
599573
if !self.opts.ignore_stub && !self.opts.ignore_module_file {
@@ -2252,7 +2226,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
22522226
"{}str2ptr({op})",
22532227
self.gen.qualify_package(FFI_DIR)
22542228
));
2255-
results.push(format!("{op}.charcode_length()"));
2229+
results.push(format!("{op}.length()"));
22562230
if realloc.is_none() {
22572231
self.cleanup.push(Cleanup::Object(op.clone()));
22582232
}
@@ -2780,18 +2754,18 @@ impl Bindgen for FunctionBindgen<'_, '_> {
27802754
fn perform_cast(op: &str, cast: &Bitcast) -> String {
27812755
match cast {
27822756
Bitcast::I32ToF32 => {
2783-
format!("({op}).to_float()")
2757+
format!("({op}).reinterpret_as_float()")
27842758
}
2785-
Bitcast::I64ToF32 => format!("Int64::to_int({op}).to_float()"),
2759+
Bitcast::I64ToF32 => format!("({op}).to_int().reinterpret_as_float()"),
27862760
Bitcast::F32ToI32 => {
2787-
format!("@ffi.f32_to_i32({op})")
2761+
format!("({op}).reinterpret_as_int()")
27882762
}
2789-
Bitcast::F32ToI64 => format!("@ffi.f32_to_i64({op})"),
2763+
Bitcast::F32ToI64 => format!("({op}).reinterpret_as_int().to_int64()"),
27902764
Bitcast::I64ToF64 => {
2791-
format!("Int64::to_double({op})")
2765+
format!("({op}).reinterpret_as_double()")
27922766
}
27932767
Bitcast::F64ToI64 => {
2794-
format!("Double::to_int64({op})")
2768+
format!("({op}).reinterpret_as_int64()")
27952769
}
27962770
Bitcast::LToI64 | Bitcast::PToP64 | Bitcast::I32ToI64 => format!("Int::to_int64({op})"),
27972771
Bitcast::I64ToL | Bitcast::P64ToP | Bitcast::I64ToI32 => format!("Int64::to_int({op})"),

crates/moonbit/tests/codegen.rs

Lines changed: 0 additions & 61 deletions
This file was deleted.

crates/test/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod c;
1616
mod config;
1717
mod csharp;
1818
mod custom;
19+
mod moonbit;
1920
mod runner;
2021
mod rust;
2122
mod wat;
@@ -193,6 +194,7 @@ enum Language {
193194
Cpp,
194195
Wat,
195196
Csharp,
197+
MoonBit,
196198
Custom(custom::Language),
197199
}
198200

@@ -413,6 +415,7 @@ impl Runner<'_> {
413415
"cpp" => Language::Cpp,
414416
"wat" => Language::Wat,
415417
"cs" => Language::Csharp,
418+
"mbt" => Language::MoonBit,
416419
other => Language::Custom(custom::Language::lookup(self, other)?),
417420
};
418421

@@ -1201,6 +1204,7 @@ impl Language {
12011204
Language::Cpp,
12021205
Language::Wat,
12031206
Language::Csharp,
1207+
Language::MoonBit,
12041208
];
12051209

12061210
fn obj(&self) -> &dyn LanguageMethods {
@@ -1210,6 +1214,7 @@ impl Language {
12101214
Language::Cpp => &c::Cpp,
12111215
Language::Wat => &wat::Wat,
12121216
Language::Csharp => &csharp::Csharp,
1217+
Language::MoonBit => &moonbit::MoonBit,
12131218
Language::Custom(custom) => custom,
12141219
}
12151220
}

0 commit comments

Comments
 (0)