Skip to content

Commit 499a888

Browse files
authored
Update StarlingMonkey (#325)
* Update StarlingMonkey submodule * Sync package-lock.json * Revert weval removal commit * Update wasi to 0.2.10 * Update tests * fix: do not relativize paths for weval * fix: account for global offset in import calculations * fix: apply clippy fixes * fix: format code * fix: bring back retry in CI * chore: bump to StarlingMonkey to v0.3.0 tag * feat: expose more programatic API via CLI
1 parent 8e88dc8 commit 499a888

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+2467
-2877
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ jobs:
102102
build-type:
103103
- 'release'
104104
- 'debug'
105+
- 'weval'
105106
steps:
106107
- uses: actions/checkout@v4
107108
with:
@@ -173,6 +174,7 @@ jobs:
173174
build-type:
174175
- 'release'
175176
- 'debug'
177+
- 'weval'
176178
steps:
177179
- uses: actions/checkout@v4
178180

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ examples/hello-world/guest/package-lock.json
1010
examples/hello-world/guest/hello.component.wasm
1111
/build-debug
1212
/build-release
13+
/build-release-weval
1314
.vscode
1415
/package-lock.json
1516
.idea

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ set(EMBEDDING_DEP "starling-raw.wasm")
2626
# Define output filenames based on build configuration
2727
set(OUTPUT_NAME_RELEASE "starlingmonkey_embedding.wasm")
2828
set(OUTPUT_NAME_DEBUG "starlingmonkey_embedding.debug.wasm")
29+
set(OUTPUT_NAME_WEVAL "starlingmonkey_embedding_weval.wasm")
2930

3031
# Set the appropriate name based on current configuration
3132
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
3233
set(OUTPUT_FILENAME ${OUTPUT_NAME_DEBUG})
34+
elseif(WEVAL)
35+
set(OUTPUT_FILENAME ${OUTPUT_NAME_WEVAL})
36+
set(EMBEDDING_DEP "starling-ics.wevalcache")
3337
else()
3438
set(OUTPUT_FILENAME ${OUTPUT_NAME_RELEASE})
3539
endif()

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ exclude = ["StarlingMonkey/crates/rust-url"]
44
resolver = "2"
55

66
[workspace.package]
7-
edition = "2021"
7+
edition = "2024"
88
version = "0.1.0"
99

1010
[workspace.lints.clippy]

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ STARLINGMONKEY_DEPS = $(STARLINGMONKEY_SRC)/cmake/* embedding/* $(STARLINGMONKEY
1515
all: release
1616
debug: lib/starlingmonkey_embedding.debug.wasm lib/spidermonkey-embedding-splicer.js
1717
release: lib/starlingmonkey_embedding.wasm lib/spidermonkey-embedding-splicer.js
18+
release-weval: lib/starlingmonkey_ics.wevalcache lib/spidermonkey-embedding-splicer.js
1819

1920
lib/spidermonkey-embedding-splicer.js: target/wasm32-wasip1/release/splicer_component.wasm crates/spidermonkey-embedding-splicer/wit/spidermonkey-embedding-splicer.wit | obj lib
2021
@$(JCO) new target/wasm32-wasip1/release/splicer_component.wasm -o obj/spidermonkey-embedding-splicer.wasm --wasi-reactor
@@ -27,6 +28,13 @@ lib/starlingmonkey_embedding.wasm: $(STARLINGMONKEY_DEPS) | lib
2728
cmake -B build-release -DCMAKE_BUILD_TYPE=Release
2829
make -j16 -C build-release starlingmonkey_embedding
2930

31+
lib/starlingmonkey_embedding_weval.wasm: $(STARLINGMONKEY_DEPS) | lib
32+
cmake -B build-release-weval -DCMAKE_BUILD_TYPE=Release -DUSE_WASM_OPT=OFF -DWEVAL=ON
33+
make -j16 -C build-release-weval starlingmonkey_embedding
34+
35+
lib/starlingmonkey_ics.wevalcache: lib/starlingmonkey_embedding_weval.wasm
36+
@cp build-release-weval/starling-raw.wasm/starling-ics.wevalcache $@
37+
3038

3139
lib/starlingmonkey_embedding.debug.wasm: $(STARLINGMONKEY_DEPS) | lib
3240
cmake -B build-debug -DCMAKE_BUILD_TYPE=RelWithDebInfo

README.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,21 @@ Establishing this initial prototype as a singular flexible engine foundation tha
5151

5252
### Weval AOT Compilation
5353

54-
Note: unfortunately Weval AOT Compilation is disabled for the time being, due to incompatibilities with newer versions of the LLVM toolchain used to compile StarlingMonkey. See [this](https://bytecodealliance.zulipchat.com/#narrow/channel/459697-StarlingMonkey/topic/Updating.20Gecko.20version/near/527089464) and the following messages for details.
54+
[Weval][weval] ahead-of-time (AOT) compilation can be enabled to improve runtime performance by pre-compiling JavaScript inline caches.
55+
56+
To enable AOT compilation, set the `enableAot: true` option or use the `--aot` CLI flag.
57+
58+
AOT compilation can also be configured with the following options:
59+
60+
| Option | Type | Example | Description |
61+
|------------------------|-------------------------------------|-----------------|--------------------------------------------------------------------------|
62+
| `aotMinStackSizeBytes` | `number | Number | bigint | BigInt` | `2_007_846_092` | The minimum stack size (via `RUST_MIN_STACK`) to set when running `weval` |
63+
64+
[weval]: https://github.com/bytecodealliance/weval
65+
66+
#### Custom `weval` binary for AOT
67+
68+
To use a custom (pre-downloaded) [`weval`][weval] binary, set the `wevalBin` option to the path to your desired weval binary.
5569

5670
## Platform APIs
5771

@@ -215,6 +229,18 @@ export function componentize(opts: {
215229
* Path to custom ComponentizeJS engine build to use
216230
*/
217231
engine?: string;
232+
/**
233+
* Path to custom weval cache to use
234+
*/
235+
aotCache?: string;
236+
/**
237+
* Enable AoT using weval
238+
*/
239+
enableAot?: boolean;
240+
/**
241+
* Use a pre-existing path to the `weval` binary, if present
242+
*/
243+
wevalBin?: string;
218244
/**
219245
* Use a pre-existing path to the `wizer` binary, if present
220246
*/
@@ -240,7 +266,7 @@ export function componentize(opts: {
240266
*/
241267
enableFeatures?: [];
242268
/**
243-
* Pass environment variables to the spawned Wizer Process
269+
* Pass environment variables to the spawned Wizer or Weval Process
244270
* If set to true, all host environment variables are passed
245271
* To pass only a subset, provide an object with the desired variables
246272
*/
@@ -319,6 +345,16 @@ npm install
319345
npm run build
320346
```
321347

348+
Before being able to use `componentize-js` with AOT support (ex. via `npm link`, from `jco`), you'll need to run:
349+
350+
```console
351+
npm run build:weval
352+
```
353+
354+
(`npm run build` will also execute the weval build)
355+
356+
This will produce `lib/starlingmonkey_embedding_weval.wasm` and `lib/starlingmonkey_ics.wevalcache`.
357+
322358
To clean up a local installation (i.e. remove the installation of StarlingMonkey):
323359

324360
```console
@@ -333,6 +369,12 @@ To run all tests:
333369
npm run test
334370
```
335371

372+
To run tests with AOT (weval) enabled:
373+
374+
```console
375+
npm run test:weval
376+
```
377+
336378
### Running a specific test
337379

338380
To run a specific test suite, you can pass an argument to [`vitest`][vitest]:

StarlingMonkey

Submodule StarlingMonkey updated 118 files

crates/spidermonkey-embedding-splicer/src/bindgen.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use heck::*;
66
use js_component_bindgen::function_bindgen::{
77
ErrHandling, FunctionBindgen, ResourceData, ResourceMap, ResourceTable,
88
};
9-
use js_component_bindgen::intrinsics::{render_intrinsics, Intrinsic};
9+
use js_component_bindgen::intrinsics::{Intrinsic, render_intrinsics};
1010
use js_component_bindgen::names::LocalNames;
1111
use js_component_bindgen::source::Source;
1212
use wit_bindgen_core::abi::{self, LiftLower};
@@ -359,8 +359,6 @@ pub fn componentize_bindgen(
359359
let repCnt = 1;
360360
let repTable = new Map();
361361
362-
contentGlobal.Symbol.dispose = Symbol.dispose = Symbol.for('dispose');
363-
364362
let [$memory, $realloc{}] = $bindings;
365363
delete globalThis.$bindings;
366364
@@ -1119,12 +1117,11 @@ impl EsmBindgen {
11191117
} else {
11201118
expt_name
11211119
};
1122-
if let Some(alias) = interface_name_from_string(expt_name_sans_version) {
1123-
if !self.exports.contains_key(&alias)
1124-
&& !self.export_aliases.values().any(|_alias| &alias == _alias)
1125-
{
1126-
self.export_aliases.insert(expt_name.to_string(), alias);
1127-
}
1120+
if let Some(alias) = interface_name_from_string(expt_name_sans_version)
1121+
&& !self.exports.contains_key(&alias)
1122+
&& !self.export_aliases.values().any(|_alias| &alias == _alias)
1123+
{
1124+
self.export_aliases.insert(expt_name.to_string(), alias);
11281125
}
11291126
}
11301127
}
@@ -1240,9 +1237,15 @@ impl EsmBindgen {
12401237
"verifyInterfaceFn"
12411238
};
12421239
if let Some(alias) = self.export_aliases.get(export_name) {
1243-
uwriteln!(bind_exports, "{verify_name}({local_name}, '{export_name}', '{external_name}', '{alias}');");
1240+
uwriteln!(
1241+
bind_exports,
1242+
"{verify_name}({local_name}, '{export_name}', '{external_name}', '{alias}');"
1243+
);
12441244
} else {
1245-
uwriteln!(bind_exports, "{verify_name}({local_name}, '{export_name}', '{external_name}', null);");
1245+
uwriteln!(
1246+
bind_exports,
1247+
"{verify_name}({local_name}, '{export_name}', '{external_name}', null);"
1248+
);
12461249
};
12471250
}
12481251
}
@@ -1288,12 +1291,12 @@ fn interface_name_from_string(name: &str) -> Option<String> {
12881291
let name = &name[path_idx + 1..];
12891292
let at_idx = name.rfind('@');
12901293
let alias = name[..at_idx.unwrap_or(name.len())].to_lower_camel_case();
1291-
let iface_name = Some(if let Some(at_idx) = at_idx {
1294+
1295+
Some(if let Some(at_idx) = at_idx {
12921296
format!("{alias}_{}", name[at_idx + 1..].replace(['.', '-'], "_"))
12931297
} else {
12941298
alias
1295-
});
1296-
iface_name
1299+
})
12971300
}
12981301

12991302
fn binding_name(func_name: &str, iface_name: &Option<String>) -> String {

crates/spidermonkey-embedding-splicer/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::path::Path;
22

3-
use anyhow::{bail, Context, Result};
3+
use anyhow::{Context, Result, bail};
44
use wit_parser::{PackageId, Resolve};
55

66
pub mod bindgen;

crates/spidermonkey-embedding-splicer/src/splice.rs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ use wasmparser::ExternalKind;
66
use wasmparser::MemArg;
77
use wasmparser::Operator;
88
use wirm::ir::function::{FunctionBuilder, FunctionModifier};
9-
use wirm::ir::id::{ExportsID, FunctionID, LocalID};
9+
use wirm::ir::id::{ExportsID, FunctionID, GlobalID, LocalID};
1010
use wirm::ir::module::Module;
11-
use wirm::ir::types::{BlockType, ElementItems, InstrumentationMode};
11+
use wirm::ir::module::module_globals::GlobalKind;
12+
use wirm::ir::types::{BlockType, ElementItems, InitInstr, InstrumentationMode, Value};
1213
use wirm::module_builder::AddLocal;
1314
use wirm::opcode::{Inject, InjectAt};
1415
use wirm::{DataType, Opcode};
15-
use wit_component::metadata::{decode, Bindgen};
1616
use wit_component::StringEncoding;
17+
use wit_component::metadata::{Bindgen, decode};
1718
use wit_parser::Resolve;
1819

1920
use crate::bindgen::BindingItem;
@@ -562,11 +563,11 @@ fn synthesize_import_functions(
562563

563564
// stack the return arg now as it chains with the
564565
// args we're about to add to the stack
565-
if impt_sig.ret.is_some() {
566+
if let Some(ret) = impt_sig.ret {
566567
func.local_get(vp_arg);
567568

568569
// if an i64 return, then we need to stack the extra BigInt constructor arg for that now
569-
if matches!(impt_sig.ret.unwrap(), CoreTy::I64) {
570+
if matches!(ret, CoreTy::I64) {
570571
func.local_get(ctx_arg);
571572
}
572573
}
@@ -725,7 +726,7 @@ fn synthesize_import_functions(
725726

726727
// create imported function table
727728
let els = module.elements.iter_mut().next().unwrap();
728-
if let ElementItems::Functions(ref mut funcs) = &mut els.items {
729+
if let ElementItems::Functions(funcs) = &mut els.items {
729730
for fid in import_fnids {
730731
funcs.push(fid);
731732
}
@@ -757,7 +758,27 @@ fn synthesize_import_functions(
757758
.get_fn_modifier(coreabi_get_import_fid)
758759
.unwrap();
759760

760-
// Find the I32Const base index and compute the delta to new base
761+
// Save the idx parameter to local at the start of the function,
762+
// so that original code does not overwrite it.
763+
let idx_local = builder.add_local(DataType::I32);
764+
builder.inject_at(
765+
0,
766+
InstrumentationMode::Before,
767+
Operator::LocalGet {
768+
local_index: *arg_idx,
769+
},
770+
);
771+
builder.inject_at(
772+
0,
773+
InstrumentationMode::Before,
774+
Operator::LocalSet {
775+
local_index: *idx_local,
776+
},
777+
);
778+
779+
// Find the I32Const base index and compute the delta to new base.
780+
// The codegen may split the base index into:
781+
// `global.get N` + `i32.const X` where the global is a constant.
761782
let mut table_instr_idx = 0usize;
762783
let mut delta: i32 = 0;
763784
{
@@ -769,7 +790,20 @@ fn synthesize_import_functions(
769790
if *value < 1000 || *value > 5000 {
770791
continue;
771792
}
772-
delta = import_fn_table_start_idx - *value;
793+
// Check if instruction just before is a global.get with a
794+
// constant value and if so, include the global's init value
795+
// in the base computation.
796+
let mut base = *value;
797+
if idx > 0
798+
&& let Operator::GlobalGet { global_index } = &ops_ro[idx - 1]
799+
&& let GlobalKind::Local(local_global) =
800+
module.globals.get_kind(GlobalID(*global_index))
801+
&& let [InitInstr::Value(Value::I32(v))] =
802+
local_global.init_expr.instructions()
803+
{
804+
base += v;
805+
}
806+
delta = import_fn_table_start_idx - base;
773807
table_instr_idx = idx;
774808
break;
775809
}
@@ -780,7 +814,7 @@ fn synthesize_import_functions(
780814
table_instr_idx,
781815
InstrumentationMode::Before,
782816
Operator::LocalGet {
783-
local_index: *arg_idx,
817+
local_index: *idx_local,
784818
},
785819
);
786820
builder.inject_at(

0 commit comments

Comments
 (0)