Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,53 @@ jobs:
path: ./target/libmozjs-${{ matrix.target }}.tar.gz
name: libmozjs-${{ matrix.target }}.tar.gz

wasi:
name: wasm32-${{ matrix.target }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- wasip1
- wasip2
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@master
id: toolchain
with:
toolchain: "1.85.0"
targets: "wasm32-${{ matrix.target }}"
- uses: bytecodealliance/actions/wasmtime/setup@v1
- name: Install WASI-SDK
run: |
cd /tmp
curl --retry 5 --retry-all-errors -OL https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-linux.tar.gz
tar -xzf wasi-sdk-25.0-x86_64-linux.tar.gz
mv wasi-sdk-25.0-x86_64-linux wasi-sdk
- name: Build
run: |
cargo +${{ steps.toolchain.outputs.name }} build --no-default-features --features libz-rs,intl --target=wasm32-${{ matrix.target }}
env:
WASI_SDK_PATH: "/tmp/wasi-sdk"
- name: Test
run: |
export CARGO_TARGET_WASM32_WASIP1_RUNNER="wasmtime run --dir=$PWD::/cwd"
export CARGO_TARGET_WASM32_WASIP2_RUNNER="wasmtime run --dir=$PWD::/cwd"
cargo +${{ steps.toolchain.outputs.name }} test --tests --examples --no-default-features --features libz-rs,intl --target=wasm32-${{ matrix.target }}
env:
WASI_SDK_PATH: "/tmp/wasi-sdk"
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
if: ${{ inputs.release }}
with:
subject-path: "./target/libmozjs-wasm32-${{ matrix.target }}.tar.gz"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
path: ./target/libmozjs-wasm32-${{ matrix.target }}.tar.gz
name: libmozjs-wasm32-${{ matrix.target }}.tar.gz

linux-cross-compile:
name: linux (${{ matrix.target }})
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion mozjs-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "mozjs_sys"
description = "System crate for the Mozilla SpiderMonkey JavaScript engine."
repository.workspace = true
version = "0.140.0-5"
version = "0.140.0-6"
authors = ["Mozilla", "The Servo Project Developers"]
links = "mozjs"
license.workspace = true
Expand Down
46 changes: 45 additions & 1 deletion mozjs-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const SM_TARGET_ENV_VARS: &'static [&'static str] = &[
"CXXFLAGS",
"READELF",
"OBJCOPY",
"WASI_SDK_PATH",
];

const EXTRA_FILES: &'static [&'static str] = &["makefile.cargo"];
Expand All @@ -60,6 +61,18 @@ fn main() {
// https://github.com/servo/servo/issues/14759
env::set_var("MOZ_NO_DEBUG_RTL", "1");

if let Some(path) = wasi_sdk() {
env::set_var(
"WASI_SYSROOT",
PathBuf::from(&path).join("share").join("wasi-sysroot"),
);
env::set_var("TARGET_CC", PathBuf::from(&path).join("bin").join("clang"));
env::set_var(
"TARGET_CXX",
PathBuf::from(&path).join("bin").join("clang++"),
);
}

let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let build_dir = out_dir.join("build");

Expand Down Expand Up @@ -342,6 +355,12 @@ fn build_bindings(build_dir: &Path, target: BuildTarget) {
.formatter(Formatter::Rustfmt)
.clang_args(cc_flags(true));

if env::var("TARGET").unwrap().contains("wasi") {
builder = builder
.clang_arg("--sysroot")
.clang_arg(env::var("WASI_SYSROOT").unwrap().to_string());
}

if target == BuildTarget::JSGlue {
builder = builder
.parse_callbacks(Box::new(JSGlueCargoCallbacks::default()))
Expand Down Expand Up @@ -437,9 +456,15 @@ fn link_static_lib_binaries(build_dir: &Path) {
println!("cargo:rustc-link-lib=c++");
} else if target.contains("windows") && target.contains("gnu") {
println!("cargo:rustc-link-lib=stdc++");
} else if !target.contains("windows") {
} else if !target.contains("windows") && !target.contains("wasi") {
// The build works without this for WASI, and specifying it means
// needing to use the WASI-SDK's clang for linking, which is annoying.
println!("cargo:rustc-link-lib=stdc++")
}

if target.contains("wasi") {
println!("cargo:rustc-link-lib=wasi-emulated-getpid");
}
}

fn link_bindgen_static_lib_binaries(build_dir: &Path) {
Expand Down Expand Up @@ -518,6 +543,13 @@ fn cc_flags(bindgen: bool) -> Vec<&'static str> {
if env::var_os("CARGO_FEATURE_PROFILEMOZJS").is_some() {
flags.push("-fno-omit-frame-pointer");
}

if target.contains("wasi") {
// Unconditionally target p1 for now. Even if the application
// targets p2, an adapter will take care of it.
flags.push("--target=wasm32-wasip1");
flags.push("-fvisibility=default");
}
}

flags.extend(&["-DSTATIC_JS_API", "-DRUST_BINDGEN"]);
Expand All @@ -541,6 +573,10 @@ fn cc_flags(bindgen: bool) -> Vec<&'static str> {
flags.push("-stdlib=libc++");
}

if target.contains("wasi") {
flags.push("-D_WASI_EMULATED_GETPID");
}

flags
}

Expand All @@ -561,6 +597,14 @@ fn js_config_path(build_dir: &Path) -> String {
.to_string()
}

fn wasi_sdk() -> Option<OsString> {
if env::var("TARGET").unwrap().contains("wasi") {
get_cc_rs_env_os("WASI_SDK_PATH")
} else {
None
}
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum BuildTarget {
JSApi,
Expand Down
42 changes: 40 additions & 2 deletions mozjs-sys/makefile.cargo
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ ifeq (,$(CARGO_FEATURE_INTL))
endif

ifneq (,$(CARGO_FEATURE_DEBUGMOZJS))
CONFIGURE_FLAGS += --enable-debug --disable-optimize --enable-gczeal
CONFIGURE_FLAGS += --enable-debug --enable-gczeal
ifneq (,$(findstring -wasi,$(TARGET)))
# wasm-opt chokes on -O0 builds.
CONFIGURE_FLAGS += --enable-optimize=-O1
else
CONFIGURE_FLAGS += --disable-optimize
endif
endif

ifneq (,$(CARGO_FEATURE_PROFILEMOZJS))
Expand All @@ -29,6 +35,9 @@ endif

ifneq (,$(CARGO_FEATURE_LIBZ_RS))
CONFIGURE_FLAGS += --enable-libz-rs
else ifneq (,$(findstring wasi,$(TARGET)))
# system libz is not available on wasi
CONFIGURE_FLAGS += --enable-libz-rs
endif

ifneq (,$(CCACHE))
Expand Down Expand Up @@ -76,6 +85,32 @@ ifneq ($(HOST),$(TARGET))
TARGET = aarch64-linux-gnu
endif

ifneq (,$(findstring -wasi,$(TARGET)))
ifeq (,$(WASI_SDK_PATH))
$(error WASI_SDK_PATH environment variable must be set when building for wasm32)
endif
WASI_SYSROOT = $(WASI_SDK_PATH)/share/wasi-sysroot
CC = $(WASI_SDK_PATH)/bin/clang
CPP = $(WASI_SDK_PATH)/bin/clang -E
CXX = $(WASI_SDK_PATH)/bin/clang++
AR = $(WASI_SDK_PATH)/bin/ar
HOST_CC = clang
HOST_CXX = clang++
CONFIGURE_FLAGS += \
--enable-portable-baseline-interp \
--disable-clang-plugin \
--disable-jit \
--disable-shared-memory \
--with-sysroot=$(WASI_SDK_PATH)/share/wasi-sysroot \
$(NULL)
# LTO makes `cargo test --wasm32-wasi` take a very very long time. Since build scripts
# don't have a way to detect if the build is for `cargo test`, enable LTO for release
# builds only.
ifneq (debug,$(PROFILE))
CONFIGURE_FLAGS += --lto=thin
endif
endif

ifeq (android,$(findstring android,$(TARGET)))
# Force use of lld on android. Mozilla build system tries to use
# gold or bfd linker on Android to support their 'elfhack'functionality in
Expand Down Expand Up @@ -154,7 +189,7 @@ all: maybe-configure
JSSRC := '$(SRC_DIR)'/js/src
# Keep track of all input variables to configure, so we don't skip reconfigure
# when we do need to reconfigure
CONFIGURE_INPUTS := "$(CC)$(CFLAGS)$(CPP)$(CPPFLAGS)$(CXX)$(CXXFLAGS)$(AS)$(AR)$(CONFIGURE_FLAGS)"
CONFIGURE_INPUTS := "$(CC)$(CFLAGS)$(CPP)$(CPPFLAGS)$(CXX)$(CXXFLAGS)$(AS)$(AR)$(HOST_CC)$(HOST_CXX)$(WASI_SYSROOT)$(CONFIGURE_FLAGS)"
LAST_CONFIGURE_INPUTS := "$(shell cat reconfigure.inputs)"
maybe-configure:
[[ $(JSSRC)/configure -ot $(JSSRC)/configure.in ]] && touch $(JSSRC)/configure || true
Expand All @@ -165,6 +200,9 @@ maybe-configure:
CC="$(CC)" CFLAGS="$(CFLAGS)" \
CPP="$(CPP)" CPPFLAGS="$(CPPFLAGS)" \
CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS)" \
HOST_CC="$(HOST_CC)" \
HOST_CXX="$(HOST_CXX)" \
WASI_SYSROOT="$(WASI_SYSROOT)" \
AS="$(AS)" AR="$(AR)" \
$(JSSRC)/configure $(strip $(CONFIGURE_FLAGS)) || (cat config.log && exit 1) ; \
fi
4 changes: 2 additions & 2 deletions mozjs-sys/src/jsglue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ bool AppendToRootedObjectVector(JS::PersistentRootedObjectVector* v,

void DeleteRootedObjectVector(JS::PersistentRootedObjectVector* v) { delete v; }

#if defined(__linux__)
#if defined(__linux__) || defined(__wasi__)
# include <malloc.h>
#elif defined(__APPLE__)
# include <malloc/malloc.h>
Expand All @@ -897,7 +897,7 @@ void DeleteRootedObjectVector(JS::PersistentRootedObjectVector* v) { delete v; }

// SpiderMonkey-in-Rust currently uses system malloc, not jemalloc.
static size_t MallocSizeOf(const void* aPtr) {
#if defined(__linux__)
#if defined(__linux__) || defined(__wasi__)
return malloc_usable_size((void*)aPtr);
#elif defined(__APPLE__)
return malloc_size((void*)aPtr);
Expand Down
5 changes: 4 additions & 1 deletion mozjs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ libc.workspace = true
log = "0.4"
mozjs_sys = { path = "../mozjs-sys" }

[dev-dependencies]
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
criterion = { version = "0.6", default-features = false, features = ["html_reports"] }

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
criterion = "0.6"

[build-dependencies]
Expand Down
3 changes: 3 additions & 0 deletions mozjs/examples/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
//! and do some setup on both of these. You also need to enter a "realm"
//! (environment within one global object) before you can execute code.

// The wasm example does not work on wasm32 targets.
#![cfg(not(target_arch = "wasm32"))]

use ::std::ptr;
use ::std::ptr::null_mut;

Expand Down
2 changes: 2 additions & 0 deletions mozjs/tests/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![cfg(not(target_arch = "wasm32"))]

use std::ptr;
use std::sync::mpsc::channel;
use std::thread;
Expand Down
Loading