diff --git a/.justfile b/.justfile index 92ff4740..47378129 100644 --- a/.justfile +++ b/.justfile @@ -6,3 +6,6 @@ clippy: add-header: hawkeye format + +install-moonrun: + cargo install --path ./crates/moonrun --debug --offline --root ~/.moon --force --locked diff --git a/Cargo.lock b/Cargo.lock index 4207ecf8..85bc4307 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2544,9 +2544,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "v8" -version = "0.102.0" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a710d5b95bff79a90708203cf9f74384e080d21fc6664aa4df463f2c66ac83" +checksum = "a381badc47c6f15acb5fe0b5b40234162349ed9d4e4fd7c83a7f5547c0fc69c5" dependencies = [ "bindgen", "bitflags 2.6.0", diff --git a/crates/moonrun/Cargo.toml b/crates/moonrun/Cargo.toml index c458e104..35940854 100644 --- a/crates/moonrun/Cargo.toml +++ b/crates/moonrun/Cargo.toml @@ -31,7 +31,7 @@ serde_json_lenient.workspace = true rand = "0.8.5" tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } -v8 = "0.102.0" +v8 = "0.106.0" [build-dependencies] vergen = { version = "8.0.0", features = ["build", "git", "gitcl"] } diff --git a/crates/moonrun/src/main.rs b/crates/moonrun/src/main.rs index bd3e1d25..c30b42d6 100644 --- a/crates/moonrun/src/main.rs +++ b/crates/moonrun/src/main.rs @@ -19,6 +19,7 @@ use clap::Parser; use std::any::Any; use std::io::{self, Write}; +use std::path::Path; use std::{cell::Cell, io::Read, path::PathBuf, time::Instant}; mod fs_api_temp; @@ -191,6 +192,24 @@ fn read_char( } } +fn read_file_to_bytes( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let arg = args.get(0); + let path = PathBuf::from(arg.to_rust_string_lossy(scope)); + let bytes = std::fs::read(path).unwrap(); + let buffer = v8::ArrayBuffer::new(scope, bytes.len()); + let ab = v8::Uint8Array::new(scope, buffer, 0, bytes.len()).unwrap(); + + unsafe { + std::ptr::copy(bytes.as_ptr(), get_array_buffer_ptr(buffer), bytes.len()); + } + + ret.set(ab.into()); +} + fn write_char( scope: &mut v8::HandleScope, args: v8::FunctionCallbackArguments, @@ -317,6 +336,14 @@ fn init_env(dtors: &mut Vec>, scope: &mut v8::HandleScope, args: &[ let obj = fs_api_temp::init_fs(obj, scope); global_proxy.set(scope, identifier.into(), obj.into()); + { + let identifier = v8::String::new(scope, "read_file_to_bytes").unwrap(); + let value = v8::Function::builder(read_file_to_bytes) + .build(scope) + .unwrap(); + global_proxy.set(scope, identifier.into(), value.into()); + } + { let identifier = v8::String::new(scope, "__moonbit_io_unstable").unwrap(); let obj = v8::Object::new(scope); @@ -384,12 +411,13 @@ fn create_script_origin<'s>(scope: &mut v8::HandleScope<'s>, name: &str) -> v8:: } fn wasm_mode( - file: &PathBuf, + file: &Path, args: &[String], no_stack_trace: bool, test_mode: bool, ) -> anyhow::Result<()> { v8::V8::set_flags_from_string("--experimental-wasm-exnref"); + v8::V8::set_flags_from_string("--experimental-wasm-imported-strings"); let platform = v8::new_default_platform(0, false).make_shared(); v8::V8::initialize_platform(platform); v8::V8::initialize(); @@ -402,11 +430,11 @@ fn wasm_mode( { let global_proxy = scope.get_current_context().global(scope); - let file = std::fs::read(file)?; - let wasm_mod = v8::WasmModuleObject::compile(scope, &file) - .ok_or_else(|| anyhow::format_err!("Failed to compile wasm module"))?; - let module_key = v8::String::new(scope, "module").unwrap().into(); - global_proxy.set(scope, module_key, wasm_mod.into()); + let module_key = v8::String::new(scope, "module_name").unwrap().into(); + let module_name = v8::String::new(scope, file.to_string_lossy().as_ref()) + .unwrap() + .into(); + global_proxy.set(scope, module_key, module_name); } let mut dtors = Vec::new(); diff --git a/crates/moonrun/src/template/js_glue.js b/crates/moonrun/src/template/js_glue.js index 54d8e57e..5d5f0e17 100644 --- a/crates/moonrun/src/template/js_glue.js +++ b/crates/moonrun/src/template/js_glue.js @@ -35,6 +35,8 @@ const spectest = { }; try { + let bytes = read_file_to_bytes(module_name); + let module = new WebAssembly.Module(bytes, { builtins: ['js-string'], importedStringConstants: "moonbit:constant_strings" }); let instance = new WebAssembly.Instance(module, spectest); if (test_mode) { for (param of testParams) {