Mozjs
Servo's SpiderMonkey fork
Install / Use
/learn @servo/MozjsREADME
Mozjs (Rust bindings for SpiderMonkey)
This repository contains Rust bindings for SpiderMonkey that are battle-tested in Servo, split in two crates:
mozjs-sys: SpiderMonkey and low-level Rust bindings to its C++ API.mozjs: Higher-level bindings to the SpiderMonkey API.
Mozjs is currently tracking SpiderMonkey on mozilla-esr140 branch (currently version 140.5).
Building from Pre-built Archive
SpiderMonkey is very large and can take a long time to compile. If building with default
features, mozjs provides a pre-built archive which can be linked against. You can also create
your own archive and link to it. mozjs currently offers two environment variables to enable
this feature:
MOZJS_CREATE_ARCHIVE=1will create a SpiderMonkey binary archive for release usage. It will be created in thetargetdirectory.MOZJS_ARCHIVEcan be used to build against a pre-built archive. Using this flag, compiling SpiderMonkey and the bindgen wrappers is unnecessary. There are two ways to use it:MOZJS_ARCHIVE=path/to/libmozjs.tar.gz: This option will look for the archive at the local path, extract it, and then link against the static libraries included in the archive.MOZJS_ARCHIVE=https://url/to/release/page: This option will download the archive from the provided base URL, extract it, and then link against the static libraries included in the archive. The base URL should be similar tohttps://github.com/servo/mozjs/releases. The build script will append the version and target accordingly. See the files at the example URL for more details.
MOZJS_ATTESTATIONallows uses Github Attestations to verify the integrity of the prebuilt archive and that the archive was built by in CI, for a valid commit on the main branch of the servo/mozjs repo. Attestation verification requires having a recent version of the github cli tool gh installed. If artifact verification is enabled and reports an error, the prebuilt archive will be discarded and mozjs will be built from source instead. Available values are:- unset (default): Equivalent to
off. MOZJS_ATTESTATION=<0|false|off>: Disable artifact verification.MOZJS_ATTESTATION=<1|true|on|lenient>: Enable artifact verification and fallback to compiling from source if verification fails or is not possible.MOZJS_ATTESTATION=<2|strict|force>: Fail the build if artifact verification fails.
- unset (default): Equivalent to
Building from Source
If MOZJS_FROM_SOURCE=1 or MOZJS_CREATE_ARCHIVE are enabled or linking against a
pre-built archive fails, mozjs will build SpiderMonkey from source.
Linux
Install Python, Clang and build-essential, for example on a Debian-based Linux:
sudo apt-get install build-essential python3 python3-distutils llvm libclang-dev clang curl
If you have more than one version of Clang installed, you can set the LIBCLANG_PATH
environment variable, for example:
export LIBCLANG_PATH=/usr/lib/clang/4.0/lib
Windows
-
Download and unzip MozTools 4.0.
-
Download and install Clang (LLVM version 14 or greater) for Windows (64 bit) from https://releases.llvm.org/download.html.
-
Download and install
Visual Studio 2019orVisual Studio 2022with theC++ desktop developmentcomponent and the following features:- Windows 10 SDK
- ATL
To install these dependencies from the command line, you can download vs_buildtools.exe and run the following command:
vs_BuildTools.exe^ --add Microsoft.VisualStudio.Workload.MSBuildTools^ --add Microsoft.VisualStudio.Component.Windows11SDK^ --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64^ --add Microsoft.VisualStudio.Component.VC.ATL^ -
Install Python 3.11.
- Ensure that Python is added to the system
PATH - Ensure that a
PYTHONandPYTHON3environment variable point to the Python binary (ieC:\Python311\python.exe
-
Set the following environment variables according to where you installed the dependencies above:
$env:LIBCLANG_PATH="C:\Program Files\LLVM\lib" $env:MOZTOOLS_PATH="C:\path\to\moztools-4.0" $env:CC="clang-cl" $env:CXX="clang-cl" $env:LD="lld-link"
Run Cargo
You can now build and test the crate using cargo:
cargo build
cargo test
cargo build --features debugmozjs
cargo test --features debugmozjs
Usage for downstream consumers
Both mozjs and mozjs_sys crates are published on crates.io.
Building servo against your local mozjs
Assuming your local servo and mozjs directories are siblings, you can build servo against mozjs by adding the following to servo/Cargo.toml:
[patch."https://github.com/servo/mozjs"]
mozjs = { path = "../mozjs/mozjs" }
Upgrading
In order to upgrade to a new version of SpiderMonkey:
-
Find the mozilla-esr140 commit for the desired version of SpiderMonkey, at https://treeherder.mozilla.org/#/jobs?repo=mozilla-esr140&filter-searchStr=spidermonkey%20pkg. You are looking for an SM(pkg) tagged with FIREFOX_RELEASE. Take a note of the commit number to the left (a hex number such as ac4fbb7aaca0).
-
Click on the SM(pkg) link, which will open a panel with details of the commit, including an artefact uploaded link, with a name of the form mozjs-version.tar.xz. Download it and save it locally.
-
Go to https://treeherder.mozilla.org/jobs?repo=mozilla-esr140&revision=${COMMIT} and download artifacts
allFUnctions.txt.gzandgcFunctions.txt.gzfrom job Linux debug > H -
Create a new release on github with all files you downloaded. Name the new tag
mozjs-source-${COMMIT}. -
Look at the patches in
mozjs-sys/etc/patches/*.patch, and remove any that no longer apply (with a bit of luck this will be all of them). -
Run
python3 ./mozjs-sys/etc/update.py path/to/tarball. -
Update
mozjs-sys/etc/COMMITwith the commit number and mozjs-sys version with SpiderMonkey version. -
Run
./mozjs/src/dl_and_gen_noGC.pyand./mozjs/src/generate_wrappers.pyto regenerate wrappers. -
Build and test the bindings as above.
-
Submit a PR!
-
Send companion PR to servo, as SpiderMonkey bump PR will not be merged until it's tested against servo.
NixOS users
To get a dev environment with shell.nix:
nix-shell
To configure rust-analyzer in Visual Studio Code:
{
"rust-analyzer.check.overrideCommand": ["nix-shell", "--run", "cargo check --message-format=json"],
"rust-analyzer.cargo.buildScripts.overrideCommand": ["nix-shell", "--run", "cargo check --message-format=json"],
"rust-analyzer.rustfmt.overrideCommand": ["nix-shell", "--run", "cargo fmt"],
}
Editor support
If you are working on the Rust code only, rust-analyzer should work perfectly out of the box, though NixOS users will need to configure rust-analyzer to wrap cargo invocations (see above).
But if you are working on the C++ code, editor support is only really possible in upstream SpiderMonkey (aka “mozilla-central”), but once you’ve set up your editor in your upstream checkout, you can work on your changes there, then import them here as needed for local testing.
This guide assumes that your code is checked out at:
- ~/code/mozjs for this repo
- ~/code/mozilla-unified for upstream SpiderMonkey
- (NixOS users only) ~/code/nixpkgs-mozilla for mozilla/nixpkgs-mozilla
NixOS users: some steps have a note in [brackets] saying they need to be wrapped in nix-shell. Those commands should be wrapped as follows:
nix-shell ~/code/nixpkgs-mozilla/release.nix -A gecko.x86_64-linux.clang --run '...'
C++ editor setup
Start by checking out mozilla-unified (Building Firefox on Linux §§ 1 and 2).
NixOS users: it’s ok if the bootstrap command fails with a NotImplementedError due to NixOS not being a supported distro.
Now create your MOZCONFIG file (Building and testing SpiderMonkey). I recommend (and this guide assumes) that the file is named debug.mozconfig, because simple names like debug can cause MozconfigFindException problems. The file should look like this:
# Build only the JS shell
ac_add_options --enable-project=js
# Enable the debugging tools: Assertions, debug only code etc.
ac_add_options --enable-debug
# Enable optimizations as well so that the test suite runs much faster. If
# you are having trouble using a debugger, you should disable optimization.
ac_add_options --enable-optimize
# Use a dedicated objdir for SpiderMonkey debug builds to avoid
# conflicting with Firefox build with default configuration.
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-debug-@CONFIG_GUESS@
If you are a NixOS user, clone mozilla/nixpkgs-mozilla next to your mozilla-unified checkout, and add the following line to the start of your debug.mozconfig:
. ./.mozconfig.nix-shell
You will need to generate your Visual Studio Code config and compilation database against central at least once, before you can do so against the commit we forked from (mozjs/etc/COMMIT).
~/code/mozilla-unified $ MOZCONFIG=debug.mozconfig ./mach ide vsco
