Skip to content
This repository was archived by the owner on Nov 12, 2022. It is now read-only.

Commit c1e5ad8

Browse files
author
bors-servo
authored
Auto merge of #489 - jhwgh1968:crate-doc, r=jdm
Add crate docstring and two code examples In the hopes of embedding SpiderMonkey into a non-Servo Rust project, I spent some time digging into these bindings. Unfortunately, it was very easy to get lost. This PR is my attempt to make it easier for the next person who attempts my exercise by adding a few sign posts I would have found helpful, and translating one of the basic examples from the SpiderMonkey User Guide on MDN to Rust. Documenting the entire crate (and where it dips directly into ``mozjs_sys``) is a task too big for any one person, I think. EDIT: removed WIP comment
2 parents eb411fc + 58bc43c commit c1e5ad8

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed

Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ license = "MPL-2.0"
1010
[build-dependencies]
1111
cc = "1"
1212

13+
[[example]]
14+
name = "minimal"
15+
[[example]]
16+
name = "eval"
17+
1318
[[test]]
1419
name = "callback"
1520
[[test]]

examples/eval.rs

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#![allow(
2+
non_upper_case_globals,
3+
non_camel_case_types,
4+
non_snake_case,
5+
improper_ctypes
6+
)]
7+
8+
//! # Running scripts
9+
//! Here is the code under "Running scripts" in the MDN User Guide[1] translated into Rust. This
10+
//! only shows the ``run()`` function's contents because the original does as well.
11+
//!
12+
//! The actual code that is run is designed to be testable, unlike the example given.
13+
//! [1]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
14+
//!
15+
16+
use std::ptr;
17+
18+
#[macro_use]
19+
extern crate mozjs;
20+
use mozjs::jsapi::*;
21+
use mozjs::jsval::UndefinedValue;
22+
use mozjs::rust::SIMPLE_GLOBAL_CLASS;
23+
use mozjs::rust::{JSEngine, RealmOptions, Runtime};
24+
25+
fn run(rt: Runtime) {
26+
let options = RealmOptions::default();
27+
rooted!(in(rt.cx()) let global = unsafe {
28+
JS_NewGlobalObject(rt.cx(), &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
29+
OnNewGlobalHookOption::FireOnNewGlobalHook,
30+
&*options)
31+
});
32+
33+
/* These should indicate source location for diagnostics. */
34+
let filename: &'static str = "inline.js";
35+
let lineno: u32 = 1;
36+
37+
/*
38+
* The return value comes back here. If it could be a GC thing, you must add it to the
39+
* GC's "root set" with the rooted! macro.
40+
*/
41+
rooted!(in(rt.cx()) let mut rval = UndefinedValue());
42+
43+
/*
44+
* Some example source in a string. This is equivalent to JS_EvaluateScript in C++.
45+
*/
46+
let source: &'static str = "40 + 2";
47+
48+
let res = rt.evaluate_script(global.handle(), source, filename, lineno, rval.handle_mut());
49+
50+
if res.is_ok() {
51+
/* Should get a number back from the example source. */
52+
assert!(rval.get().is_int32());
53+
assert_eq!(rval.get().to_int32(), 42);
54+
}
55+
}
56+
57+
fn main() {
58+
let engine = JSEngine::init().expect("failed to initalize JS engine");
59+
let runtime = Runtime::new(engine.handle());
60+
assert!(!runtime.cx().is_null(), "failed to create JSContext");
61+
run(runtime);
62+
}

examples/minimal.rs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
* You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
#![allow(
6+
non_upper_case_globals,
7+
non_camel_case_types,
8+
non_snake_case,
9+
improper_ctypes
10+
)]
11+
12+
//! # A minimal example
13+
//! Here is the code under "A minimal example" in the MDN User Guide[1] translated into Rust.
14+
//! [1]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
15+
16+
use std::ptr;
17+
18+
#[macro_use]
19+
extern crate mozjs;
20+
use mozjs::rust::SIMPLE_GLOBAL_CLASS;
21+
use mozjs::{jsapi::*, rust::JSEngine, rust::RealmOptions, rust::Runtime};
22+
23+
fn main() {
24+
// Initialize the JS engine. This handle must be kept alive in order to create new Runtimes.
25+
let engine = JSEngine::init().expect("failed to initalize JS engine");
26+
27+
// Create a Runtime -- wraps a JSContext in the C++ API.
28+
let runtime = Runtime::new(engine.handle());
29+
assert!(!runtime.cx().is_null(), "failed to create JSContext");
30+
31+
run(runtime);
32+
33+
// There is no need for the shut down block in the C++, because rust destructors and Arc
34+
// reference counts will clean up everything.
35+
}
36+
37+
fn run(rt: Runtime) {
38+
let cx = rt.cx();
39+
// In addition to what the C++ interface requires, define a global scope for the code.
40+
//
41+
// This demonstrates the way Rust uses the C++ garbage collector: using the rooted! macro to
42+
// indicate when the GC can collect them.
43+
let options = RealmOptions::default();
44+
rooted!(in(cx) let _global = unsafe {
45+
JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
46+
OnNewGlobalHookOption::FireOnNewGlobalHook,
47+
&*options)
48+
});
49+
50+
// Your application code here. This may include JSAPI calls to create your
51+
// own custom JS objects and run scripts.
52+
}

src/lib.rs

+17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@
77

88
#![allow(non_upper_case_globals, non_camel_case_types, non_snake_case, improper_ctypes)]
99

10+
//!
11+
//! This crate contains Rust bindings to the [SpiderMonkey Javascript engine][1]
12+
//! developed by Mozilla.
13+
//!
14+
//! These bindings are designed to be a fairly straightforward translation to the C++ API, while
15+
//! taking advantage of Rust's memory safety. For more about the Spidermonkey API, see the
16+
//! [API Reference][2] and the [User Guide][3] on MDN, and the [embedding examples][4] on GitHub.
17+
//!
18+
//! The code from User Guide sections [A minimal example](../../../examples/minimal.rs) and
19+
//! [Running scripts](../../../examples/eval.rs) are also included.
20+
//!
21+
//! [1]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey
22+
//! [2]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference
23+
//! [3]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
24+
//! [4]: https://github.com/mozilla-spidermonkey/spidermonkey-embedding-examples/
25+
//!
26+
1027
#[macro_use]
1128
extern crate lazy_static;
1229
extern crate libc;

0 commit comments

Comments
 (0)