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

Commit

Permalink
Auto merge of #489 - jhwgh1968:crate-doc, r=jdm
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors-servo authored Feb 24, 2020
2 parents eb411fc + 58bc43c commit c1e5ad8
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ license = "MPL-2.0"
[build-dependencies]
cc = "1"

[[example]]
name = "minimal"
[[example]]
name = "eval"

[[test]]
name = "callback"
[[test]]
Expand Down
62 changes: 62 additions & 0 deletions examples/eval.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#![allow(
non_upper_case_globals,
non_camel_case_types,
non_snake_case,
improper_ctypes
)]

//! # Running scripts
//! Here is the code under "Running scripts" in the MDN User Guide[1] translated into Rust. This
//! only shows the ``run()`` function's contents because the original does as well.
//!
//! The actual code that is run is designed to be testable, unlike the example given.
//! [1]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
//!
use std::ptr;

#[macro_use]
extern crate mozjs;
use mozjs::jsapi::*;
use mozjs::jsval::UndefinedValue;
use mozjs::rust::SIMPLE_GLOBAL_CLASS;
use mozjs::rust::{JSEngine, RealmOptions, Runtime};

fn run(rt: Runtime) {
let options = RealmOptions::default();
rooted!(in(rt.cx()) let global = unsafe {
JS_NewGlobalObject(rt.cx(), &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
OnNewGlobalHookOption::FireOnNewGlobalHook,
&*options)
});

/* These should indicate source location for diagnostics. */
let filename: &'static str = "inline.js";
let lineno: u32 = 1;

/*
* The return value comes back here. If it could be a GC thing, you must add it to the
* GC's "root set" with the rooted! macro.
*/
rooted!(in(rt.cx()) let mut rval = UndefinedValue());

/*
* Some example source in a string. This is equivalent to JS_EvaluateScript in C++.
*/
let source: &'static str = "40 + 2";

let res = rt.evaluate_script(global.handle(), source, filename, lineno, rval.handle_mut());

if res.is_ok() {
/* Should get a number back from the example source. */
assert!(rval.get().is_int32());
assert_eq!(rval.get().to_int32(), 42);
}
}

fn main() {
let engine = JSEngine::init().expect("failed to initalize JS engine");
let runtime = Runtime::new(engine.handle());
assert!(!runtime.cx().is_null(), "failed to create JSContext");
run(runtime);
}
52 changes: 52 additions & 0 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */

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

//! # A minimal example
//! Here is the code under "A minimal example" in the MDN User Guide[1] translated into Rust.
//! [1]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
use std::ptr;

#[macro_use]
extern crate mozjs;
use mozjs::rust::SIMPLE_GLOBAL_CLASS;
use mozjs::{jsapi::*, rust::JSEngine, rust::RealmOptions, rust::Runtime};

fn main() {
// Initialize the JS engine. This handle must be kept alive in order to create new Runtimes.
let engine = JSEngine::init().expect("failed to initalize JS engine");

// Create a Runtime -- wraps a JSContext in the C++ API.
let runtime = Runtime::new(engine.handle());
assert!(!runtime.cx().is_null(), "failed to create JSContext");

run(runtime);

// There is no need for the shut down block in the C++, because rust destructors and Arc
// reference counts will clean up everything.
}

fn run(rt: Runtime) {
let cx = rt.cx();
// In addition to what the C++ interface requires, define a global scope for the code.
//
// This demonstrates the way Rust uses the C++ garbage collector: using the rooted! macro to
// indicate when the GC can collect them.
let options = RealmOptions::default();
rooted!(in(cx) let _global = unsafe {
JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
OnNewGlobalHookOption::FireOnNewGlobalHook,
&*options)
});

// Your application code here. This may include JSAPI calls to create your
// own custom JS objects and run scripts.
}
17 changes: 17 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@

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

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

0 comments on commit c1e5ad8

Please sign in to comment.