This page contains notes about using Rust.
See Rust Host for a Rust Accessor Host.
Getting Started
Duktape and Rust
The idea would be to use Rust to interface to Duktape
- One negative is that Duktape is unsafe, so we would be losing a bunch of safety issues from Duktape
- One positive is that this could possibly work sooner rather than later
- We could port eduk to Rust and then start working on a porting Duktape to Rust.
Duktape Rust Interfaces.
JavaScript and Rust
We need a JavaScript interpreter written in Rust.
Servo
- https://servo.org/ - "Servo is a modern, high-performance browser engine designed for both application and embedded use."... "Sponsored by Mozilla and written in the new systems programming language Rust, the Servo project aims to achieve better parallelism, security, modularity, and performance. "
- https://en.wikipedia.org/wiki/Servo_(layout_engine)
One idea would be to use the JavaScript interpreter that is presumably part of Servo. It looks like this is possible, though the resulting binary is 19.6Mb in size. Note that the example is merely invoking SpiderMonkey, which is written in C/C++. See below for detail for how to evaluate JavaScript from Rust.
- https://github.com/servo/servo/wiki/Design#javascript-and-dom-bindings: "JavaScript and DOM bindings: We are currently using SpiderMonkey, although pluggable engines is a long-term, low-priority goal. Each content task gets its own JavaScript runtime. DOM bindings use the native JavaScript engine API instead of XPCOM. Automatic generation of bindings from WebIDL is a priority."
- Mac build instructions:
sudo port install py-virtualenv
git clone https://github.com/servo/servo
cd servo
# "To build Servo in development mode. This is useful for development, but the resulting binary is very slow."
./mach build --dev
./mach run tests/html/about-mozilla.html
# "For benchmarking, performance testing, or real-world use, add the --release flag to create an optimized build:"
./mach build --release
./mach run --release tests/html/about-mozilla.html
rust-mozjs
Instead of using all of Servo, we can use rust-mozj
, which uses fewer dependencies.
This uses Mozilla SpiderMonkey, but it seems like it is not necessary to install SpiderMonkey separately.
Building rust-mozjs
rust-mozjs uses #[feature]]
, which requires the nightly build, so as yourself, not as root, install rustup
curl https://sh.rustup.rs -sSf | sh
source ~/.cargo/env
rustup default nightly
- Download
git clone https://github.com/servo/rust-mozjs
- Build:
cd rust-mozjs
cargo build
target/debug/libjs.rlib
is created
- How can I load an execute some JS code in spider monkey?
- Suggests https://github.com/servo/rust-mozjs/blob/master/examples/callback.rs, which does not exist
- However, a copy may be found at https://github.com/servo/rust-mozjs/blob/const-static/examples/callback.rs
- https://github.com/servo/rust-mozjs/pull/165 merged in on July 2, 2015 describes how the code was added
- The suggested build command was
cargo run --features debugmozjs --example callback
- Build instructions:
rustup default nightly
git clone https://github.com/servo/rust-mozjs
cd rust-mozjs
mkdir examples
wget -O examples/callback.rs https://raw.githubusercontent.com/servo/rust-mozjs/const-static/examples/callback.rs
cargo run --example callback
- Building failed:
error[E0432]: unresolved import `js::JSCLASS_RESERVED_SLOTS_SHIFT`
--> examples/callback.rs:12:38
|
12 | use js::{JSCLASS_RESERVED_SLOTS_MASK,JSCLASS_RESERVED_SLOTS_SHIFT,JSCLASS_GLOBAL_SLOT_COUNT,JSCLASS_IS_GLOBAL};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `JSCLASS_RESERVED_SLOTS_SHIFT` in `js`. Did you mean to use `JSCLASS_RESERVED_SLOTS_MASK`?
- Fix:
< use js::{JSCLASS_RESERVED_SLOTS_MASK,JSCLASS_RESERVED_SLOTS_SHIFT,JSCLASS_GLOBAL_SLOT_COUNT,JSCLASS_IS_GLOBAL};
---
> //use js::{JSCLASS_RESERVED_SLOTS_MASK,JSCLASS_RESERVED_SLOTS_SHIFT,JSCLASS_GLOBAL_SLOT_COUNT,JSCLASS_IS_GLOBAL};
> use js::{JSCLASS_RESERVED_SLOTS_MASK,JSCLASS_GLOBAL_SLOT_COUNT,JSCLASS_IS_GLOBAL};
> use js::jsapi::{JSCLASS_RESERVED_SLOTS_SHIFT};
- Building failed:
rror[E0560]: struct `js::jsapi::JSClass` has no field named `addProperty`
--> examples/callback.rs:25:5
|
25 | addProperty: None,
| ^^^^^^^^^^^^ field does not exist - did you mean `cOps`?
- Solution! Ben Zhang suggested copying
tests/callback.rs
to examples/callback.rs
and then changing the callback
to main
. It is also necessary to remove #[test]
. The diff is below:
bash-3.2$ diff tests/callback.rs examples/callback.rs
26,27c26
< #[test]
< fn callback() {
---
> fn main() {
bash-3.2$
- With the above change, we can compile and run
bash-3.2$ cargo run --example callback
Compiling js v0.1.3 (file:///Users/cxh/src/rust/rust-mozjs)
Finished debug [unoptimized + debuginfo] target(s) in 10.77 secs
Running `target/debug/examples/callback`
Test Iñtërnâtiônàlizætiøn ┬─┬ノ( º _ ºノ)
bash-3.2$
- The binary that is created is 24.5Mb, which can be stripped to 19.6Mb and links to a few system libraries:
bash-3.2$ ls -l ./target/debug/examples/callback
-rwxr-xr-x 1 cxh staff 24529272 Oct 30 16:38 ./target/debug/examples/callback
bash-3.2$ strip !$
strip ./target/debug/examples/callback
bash-3.2$ ls -l ./target/debug/examples/callback
-rwxr-xr-x 1 cxh staff 19561328 Oct 30 16:39 ./target/debug/examples/callback
bash-3.2$ otool -L ./target/debug/examples/callback
./target/debug/examples/callback:
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1\
)
bash-3.2$
rust-mozjs
seems to have these dependencies:
bash-3.2$ ls -l target/debug/deps/
total 660608
-rw-r--r-- 1 cxh staff 193566 Oct 30 14:17 libbuild-493a7b0628804707.rlib
-rw-r--r-- 1 cxh staff 792298 Oct 30 14:17 libcmake-830f3a153d2e04e4.rlib
-rw-r--r-- 1 cxh staff 1332660 Oct 30 14:17 libgcc-41d62055fc225d58.rlib
-rw-r--r-- 1 cxh staff 47978 Oct 30 14:17 libheapsize-c3a4dd1c77b5ddc8.rlib
-rw-r--r-- 2 cxh staff 3488460 Oct 30 16:38 libjs.rlib
-rw-r--r-- 1 cxh staff 6686 Oct 30 14:17 libkernel32-df86a08647459244.rlib
-rw-r--r-- 1 cxh staff 9558 Oct 30 14:17 liblazy_static-359f5533c970cd71.rlib
-rw-r--r-- 1 cxh staff 438742 Oct 30 14:17 liblibc-ad32fde1bd850538.rlib
-rw-r--r-- 1 cxh staff 18694 Oct 30 14:17 liblibz_sys-3ed6726e0477f97a.rlib
-rw-r--r-- 1 cxh staff 252172 Oct 30 14:17 liblog-bf16bb9a4912b11d.rlib
-rw-r--r-- 1 cxh staff 330085660 Oct 30 14:19 libmozjs_sys-572528194a83d174.rlib
-rw-r--r-- 1 cxh staff 670792 Oct 30 14:17 libnum_traits-92bb90166cd1857c.rlib
-rw-r--r-- 1 cxh staff 771040 Oct 30 14:17 libpkg_config-7cc12d9787dada57.rlib
-rw-r--r-- 1 cxh staff 92406 Oct 30 14:17 libwinapi-0889532d327ff4e2.rlib
bash-3.2$
Using rust-mozjs
SpiderMonkey
To use rust-mozjs, you may need to install SpiderMonkey, see https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Build_Documentation
The fastest way seems to be:
git clone --depth 1 https://github.com/mozilla/gecko-dev.git
cd gecko-dev/js/src
cargo build
JavaScript Rust dead ends
Don't try these: