Skip to content

Commit

Permalink
Support weval-based ahead-of-time compilation of JavaScript. (#91)
Browse files Browse the repository at this point in the history
* Support weval-based ahead-of-time compilation of JavaScript.

When the `WEVAL` option is turned on (`cmake -DWEVAL=ON`), this PR adds:

- Integration to the CMake machinery to fetch a PBL+weval-ified version
  of SpiderMonkey artifacts;
- Likewise, to fetch weval binaries;
- A rule to pre-build a compilation cache of IC bodies specific to the
  StarlingMonkey build, so weval can use this cache and spend time only
  on user-provided code on first run;
- Integration in `componentize.sh`.

When built with:

```
$ mkdir build/; cd build/
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DUSE_WASM_OPT=OFF -DWEVAL=ON
$ make
```

We can then do:

```
$ build/componentize.sh file.js --aot -o file.wasm
$ wasmtime serve -S cli=y file.wasm
```

Using the Richards Octane benchmark adapted slightly with a `main()` for
the HTTP server world [1], I get the following results:

```
%  build/componentize.sh
richards.js --aot -o weval.wasm
Componentizing richards.js into weval.wasm
[ verbose weval progress output ]

% wasmtime serve -S cli=y weval.wasm
Serving HTTP on http://0.0.0.0:8080/
stdout [0] :: Log: Richards: 676
stdout [0] :: Log: ----
stdout [0] :: Log: Score (version 9): 676

% wasmtime serve -S cli=y base.wasm
Serving HTTP on http://0.0.0.0:8080/
stdout [0] :: Log: Richards: 189
stdout [0] :: Log: ----
stdout [0] :: Log: Score (version 9): 189
```

[1]: https://gist.github.com/cfallin/4b18da12413e93f7e88568a92d09e4b7

* support weval testing

* add ci workflow for Weval test suite

* Update weval, resolving two test failures.

This commit updates to weval v0.2.7 which has no output by default,
allowing the expected-failure tests checking syntax error messages to
pass; we now pass 9/10 integration tests.

It also updates the flags on `componentize.sh`: a `--verbose` flag to
allow the user to see weval progress messages (perhaps useful if the
build is taking a long time, or to see the stats on function
specializations); and removal of the `--aot` flag, because there is only
one valid setting for a build configuration and it is not baked into the
shell script automatically.

* Update SpiderMonkey version to include two fixes (bytecodealliance/spidermonkey-wasi-embedding#19).

---------

Co-authored-by: Guy Bedford <[email protected]>
  • Loading branch information
cfallin and guybedford authored Jul 31, 2024
1 parent 1a1dc3d commit f7e2745
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 9 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,34 @@ jobs:
run: |
CTEST_OUTPUT_ON_FAILURE=1 ctest --test-dir cmake-build-debug -j4
test-weval:
name: Test Weval
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2

- name: Install Rust 1.77.1
run: |
rustup toolchain install 1.77.1
rustup target add wasm32-wasi --toolchain 1.77.1
- uses: actions/setup-node@v2
with:
node-version: 'lts/*'

- name: Build StarlingMonkey
run: |
cmake -S . -B cmake-build-weval -DCMAKE_BUILD_TYPE=Release -DUSE_WASM_OPT=OFF -DWEVAL=ON
cmake --build cmake-build-weval --parallel 4 --target all integration-test-server
- name: StarlingMonkey E2E & Integration Tests
run: |
CTEST_OUTPUT_ON_FAILURE=1 ctest --test-dir cmake-build-weval -j4
wpt:
name: Web Platform Tests
strategy:
Expand Down
22 changes: 21 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ include("init-corrosion")
include("wasm-tools")
include("binaryen")
include("wizer")
include("weval")
include("wasmtime")

include("fmt")
Expand Down Expand Up @@ -90,9 +91,28 @@ endif()

target_link_libraries(starling.wasm PRIVATE host_api extension_api builtins spidermonkey rust-url)

# build a compilation cache of ICs
if(WEVAL)
include("weval")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/null.js "function main() {}")
add_custom_target(
starling-ics.wevalcache
ALL
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND rm -f starling-ics.wevalcache
COMMAND echo ./null.js | ${WEVAL_BIN} weval --dir . --show-stats --cache starling-ics.wevalcache -w -i starling.wasm -o /dev/null
DEPENDS starling.wasm
VERBATIM
)
set(WEVAL_CACHE_FILE "starling-ics.wevalcache")
set(AOT 1)
else()
set(AOT 0)
endif()

set(RUNTIME_FILE "starling.wasm")
set(ADAPTER_FILE "preview1-adapter.wasm")
configure_file("componentize.sh" "${CMAKE_CURRENT_BINARY_DIR}/componentize.sh" COPYONLY)
configure_file("componentize.sh" "${CMAKE_CURRENT_BINARY_DIR}/componentize.sh" @ONLY)
configure_file(${ADAPTER} "${CMAKE_CURRENT_BINARY_DIR}/${ADAPTER_FILE}" COPYONLY)
configure_file(spin.toml spin.toml COPYONLY)

Expand Down
10 changes: 9 additions & 1 deletion cmake/spidermonkey.cmake
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
set(SM_REV ffbf1c4641440e74174199def6558c710b3ac323)
set(SM_REV 99d3bca2aa1f477d3f7f3dcbad2ef2218c14f41b)

if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(SM_BUILD_TYPE debug)
else()
set(SM_BUILD_TYPE release)
endif()
set(SM_BUILD_TYPE_DASH ${SM_BUILD_TYPE})

option(WEVAL "Build with a SpiderMonkey variant that supports weval-based AOT compilation" OFF)

if (WEVAL)
set(SM_BUILD_TYPE_DASH "${SM_BUILD_TYPE}-weval")
set(SM_BUILD_TYPE "${SM_BUILD_TYPE}_weval")
endif()

# If the developer has specified an alternate local set of SpiderMonkey
# artifacts, use them. This allows for local/in-tree development without
Expand Down
6 changes: 6 additions & 0 deletions cmake/weval.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set(WEVAL_VERSION v0.2.7)

set(WEVAL_URL https://github.com/cfallin/weval/releases/download/${WEVAL_VERSION}/weval-${WEVAL_VERSION}-${HOST_ARCH}-${HOST_OS}.tar.xz)
CPMAddPackage(NAME weval URL ${WEVAL_URL} DOWNLOAD_ONLY TRUE)
set(WEVAL_DIR ${CPM_PACKAGE_weval_SOURCE_DIR})
set(WEVAL_BIN ${WEVAL_DIR}/weval)
27 changes: 23 additions & 4 deletions componentize.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

wizer="${WIZER:-wizer}"
wasm_tools="${WASM_TOOLS:-wasm-tools}"
weval="${WEVAL:-@WEVAL_BIN@}"
aot=@AOT@

usage() {
echo "Usage: $(basename "$0") [input.js] [-o output.wasm]"
echo "Usage: $(basename "$0") [input.js] [--verbose] [-o output.wasm]"
echo " Providing an input file but no output uses the input base name with a .wasm extension"
echo " Providing an output file but no input creates a component without running any top-level script"
exit 1
Expand All @@ -19,6 +21,7 @@ fi

IN_FILE=""
OUT_FILE=""
VERBOSE=0

while [ $# -gt 0 ]
do
Expand All @@ -27,6 +30,10 @@ do
OUT_FILE="$2"
shift 2
;;
--verbose)
VERBOSE=1
shift
;;
*)
if [ -n "$IN_FILE" ] && [ -z "$OUT_FILE" ] && [ $# -eq 1 ]
then
Expand Down Expand Up @@ -62,8 +69,20 @@ else
echo "Creating runtime-script component $OUT_FILE"
fi

if [[ $aot -ne 0 ]]; then
WEVAL_VERBOSE=""
if [[ $VERBOSE -ne 0 ]]; then
WEVAL_VERBOSE="--verbose --show-stats"
fi

echo "$IN_FILE" | WASMTIME_BACKTRACE_DETAILS=1 $wizer --allow-wasi --wasm-bulk-memory true \
--inherit-stdio true --inherit-env true $PREOPEN_DIR -o "$OUT_FILE" \
-- "$(dirname "$0")/starling.wasm"
echo "$IN_FILE" | WASMTIME_BACKTRACE_DETAILS=1 $weval weval -w $PREOPEN_DIR \
--cache-ro "$(dirname "$0")/starling-ics.wevalcache" \
$WEVAL_VERBOSE \
-o "$OUT_FILE" \
-i "$(dirname "$0")/starling.wasm"
else
echo "$IN_FILE" | WASMTIME_BACKTRACE_DETAILS=1 $wizer --allow-wasi --wasm-bulk-memory true \
--inherit-stdio true --inherit-env true $PREOPEN_DIR -o "$OUT_FILE" \
-- "$(dirname "$0")/starling.wasm"
fi
$wasm_tools component new -v --adapt "wasi_snapshot_preview1=$(dirname "$0")/preview1-adapter.wasm" --output "$OUT_FILE" "$OUT_FILE"
3 changes: 2 additions & 1 deletion tests/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ test_runtime="$1"
test_component="${3:-}"
test_name="$(basename $test_dir)"
test_serve_path="${4:-}"
componentize_flags="${COMPONENTIZE_FLAGS:-}"

wasmtime="${WASMTIME:-wasmtime}"

Expand All @@ -24,7 +25,7 @@ if [ -z "$test_component" ]; then

# Run Wizer
set +e
"$test_runtime/componentize.sh" "$test_dir/$test_name.js" "$test_component" 1> "$stdout_log" 2> "$stderr_log"
"$test_runtime/componentize.sh" $componentize_flags "$test_dir/$test_name.js" "$test_component" 1> "$stdout_log" 2> "$stderr_log"
wizer_result=$?
set -e

Expand Down
1 change: 1 addition & 0 deletions tests/tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ enable_testing()
find_program(BASH_PROGRAM bash)
include("wizer")
include("wasmtime")
include("weval")

function(test_e2e TEST_NAME)
get_target_property(RUNTIME_DIR starling.wasm BINARY_DIR)
Expand Down
4 changes: 3 additions & 1 deletion tests/wpt-harness/build-wpt-runtime.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

set -euo pipefail

componentize_flags="${COMPONENTIZE_FLAGS:-}"

if [ -z "${WPT_ROOT:-}" ]; then
echo "The WPT_ROOT environment variable is not set"
exit 1
Expand All @@ -16,4 +18,4 @@ inputs=(
)

cat "${inputs[@]}" > wpt-test-runner.js
./componentize.sh wpt-test-runner.js wpt-runtime.wasm
./componentize.sh $componentize_flags wpt-test-runner.js wpt-runtime.wasm
9 changes: 8 additions & 1 deletion tests/wpt-harness/wpt.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
enable_testing()

include("wasmtime")
include("weval")

if(WEVAL)
set(COMPONENTIZE_FLAGS "--aot")
else()
set(COMPONENTIZE_FLAGS "")
endif()

if(DEFINED ENV{WPT_ROOT})
set(WPT_ROOT ENV{WPT_ROOT})
Expand All @@ -21,7 +28,7 @@ add_builtin(wpt_support
add_custom_command(
OUTPUT wpt-runtime.wasm
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E env PATH=${WASM_TOOLS_DIR}:${WIZER_DIR}:$ENV{PATH} WPT_ROOT=${WPT_ROOT} ${CMAKE_CURRENT_SOURCE_DIR}/tests/wpt-harness/build-wpt-runtime.sh
COMMAND ${CMAKE_COMMAND} -E env PATH=${WASM_TOOLS_DIR}:${WIZER_DIR}:$ENV{PATH} env "COMPONENTIZE_FLAGS=${COMPONENTIZE_FLAGS}" WPT_ROOT=${WPT_ROOT} ${CMAKE_CURRENT_SOURCE_DIR}/tests/wpt-harness/build-wpt-runtime.sh
DEPENDS starling.wasm componentize.sh tests/wpt-harness/build-wpt-runtime.sh tests/wpt-harness/pre-harness.js tests/wpt-harness/post-harness.js
VERBATIM
)
Expand Down

0 comments on commit f7e2745

Please sign in to comment.