├── .gitignore ├── .cargo └── config ├── README.md ├── tests ├── runtime_no_outlive.rs ├── custom_auto_rooter_macro.rs ├── evaluate.rs ├── stack_limit.rs ├── custom_auto_rooter.rs ├── typedarray_panic.rs ├── panic.rs ├── enumerate.rs ├── runtime.rs ├── capture_stack.rs ├── callback.rs ├── vec_conversion.rs ├── property_descriptor.rs ├── typedarray.rs └── rooting.rs ├── src ├── consts.rs ├── generate_wrappers.sh ├── panic.rs ├── lib.rs ├── glue_wrappers.in ├── error.rs ├── typedarray.rs ├── glue.rs ├── conversions.rs └── jsapi_wrappers.in ├── gen.py ├── Cargo.toml ├── examples ├── minimal.rs └── eval.rs ├── .github └── workflows │ └── rust.yml └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | libmozjs.so 2 | *~ 3 | vc*.pdb 4 | js 5 | /doc 6 | /target 7 | /Cargo.lock 8 | -------------------------------------------------------------------------------- /.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-pc-windows-msvc] 2 | linker = "lld-link.exe" 3 | 4 | [target.i686-pc-windows-msvc] 5 | linker = "lld-link.exe" 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-mozjs 2 | 3 | Rust bindings to SpiderMonkey, now living in [servo/mozjs](https://github.com/servo/mozjs/tree/master/rust-mozjs). 4 | -------------------------------------------------------------------------------- /tests/runtime_no_outlive.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | extern crate mozjs; 6 | 7 | use mozjs::rust::{JSEngine, Runtime}; 8 | 9 | #[test] 10 | #[should_panic] 11 | fn runtime() { 12 | let engine = JSEngine::init().unwrap(); 13 | let runtime = Runtime::new(engine.handle()); 14 | let _parent = runtime.prepare_for_new_child(); 15 | drop(runtime); 16 | } 17 | -------------------------------------------------------------------------------- /src/consts.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | pub const default_heapsize: u32 = 32_u32 * 1024_u32 * 1024_u32; 6 | 7 | pub use jsapi::JSCLASS_IS_DOMJSCLASS; 8 | pub use jsapi::JSCLASS_USERBIT1; 9 | 10 | pub use jsapi::JSCLASS_RESERVED_SLOTS_MASK; 11 | 12 | pub use jsapi::JSCLASS_HIGH_FLAGS_SHIFT; 13 | 14 | pub use jsapi::JSCLASS_IS_GLOBAL; 15 | 16 | pub use jsapi::JSCLASS_IS_PROXY; 17 | 18 | pub use jsapi::JSCLASS_GLOBAL_SLOT_COUNT; 19 | -------------------------------------------------------------------------------- /src/generate_wrappers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is one big heuristic but seems to work well enough 3 | grep_heur() { 4 | grep -v "link_name" "$1" | \ 5 | grep -v '"\]' | \ 6 | grep -F -v '/\*\*' | \ 7 | sed -z 's/,\n */, /g' | \ 8 | sed -z 's/:\n */: /g' | \ 9 | sed -z 's/\n *->/ ->/g' | \ 10 | grep -v '^\}$' | \ 11 | sed 's/^ *pub/pub/' | \ 12 | sed -z 's/\;\n/\n/g' | \ 13 | grep 'pub fn' | \ 14 | grep Handle | \ 15 | grep -v roxyHandler | \ 16 | grep -v '\bIdVector\b' | # name clash between rust::IdVector and JS::IdVector \ 17 | grep -v 'pub fn Unbox' | # this function seems to be platform specific \ 18 | grep -v 'CopyAsyncStack' | # arch-specific bindgen output 19 | sed 's/root:://g' | 20 | sed 's/JS:://g' | 21 | sed 's/js:://g' | 22 | sed 's/mozilla:://g' | 23 | sed 's/Handle<\*mut JSObject>/HandleObject/g' 24 | } 25 | 26 | grep_heur ../target/debug/build/mozjs_sys-*/out/build/jsapi.rs | sed 's/\(.*\)/wrap!(jsapi: \1);/g' > jsapi_wrappers.in 27 | grep_heur glue.rs | sed 's/\(.*\)/wrap!(glue: \1);/g' > glue_wrappers.in 28 | -------------------------------------------------------------------------------- /src/panic.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | use std::any::Any; 6 | use std::cell::RefCell; 7 | use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe}; 8 | 9 | thread_local!(static PANIC_PAYLOAD: RefCell>> = RefCell::new(None)); 10 | 11 | /// If there is a pending panic, resume unwinding. 12 | pub fn maybe_resume_unwind() { 13 | if let Some(error) = PANIC_PAYLOAD.with(|result| result.borrow_mut().take()) { 14 | resume_unwind(error); 15 | } 16 | } 17 | 18 | /// Generic wrapper for JS engine callbacks panic-catching 19 | // https://github.com/servo/servo/issues/26585 20 | #[inline(never)] 21 | pub fn wrap_panic(function: &mut dyn FnMut()) { 22 | match catch_unwind(AssertUnwindSafe(function)) { 23 | Ok(()) => {} 24 | Err(payload) => { 25 | PANIC_PAYLOAD.with(|opt_payload| { 26 | let mut opt_payload = opt_payload.borrow_mut(); 27 | assert!(opt_payload.is_none()); 28 | *opt_payload = Some(payload); 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/custom_auto_rooter_macro.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate mozjs; 7 | 8 | use std::cell::Cell; 9 | 10 | use mozjs::jsapi::{GCReason, JSTracer, JS_GC}; 11 | use mozjs::rust::{CustomTrace, JSEngine, Runtime}; 12 | 13 | struct TraceCheck { 14 | trace_was_called: Cell, 15 | } 16 | 17 | impl TraceCheck { 18 | fn new() -> TraceCheck { 19 | TraceCheck { 20 | trace_was_called: Cell::new(false), 21 | } 22 | } 23 | } 24 | 25 | unsafe impl CustomTrace for TraceCheck { 26 | fn trace(&self, _: *mut JSTracer) { 27 | self.trace_was_called.set(true); 28 | } 29 | } 30 | 31 | #[test] 32 | fn custom_auto_rooter_macro() { 33 | let engine = JSEngine::init().unwrap(); 34 | let runtime = Runtime::new(engine.handle()); 35 | let context = runtime.cx(); 36 | 37 | auto_root!(in(context) let vec = vec![TraceCheck::new(), TraceCheck::new()]); 38 | 39 | unsafe { 40 | JS_GC(context, GCReason::API); 41 | } 42 | 43 | vec.iter() 44 | .for_each(|elem| assert!(elem.trace_was_called.get())); 45 | } 46 | -------------------------------------------------------------------------------- /tests/evaluate.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate mozjs; 7 | 8 | use std::ptr; 9 | 10 | use mozjs::jsapi::{JS_NewGlobalObject, OnNewGlobalHookOption}; 11 | use mozjs::jsval::UndefinedValue; 12 | use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 13 | 14 | #[test] 15 | fn evaluate() { 16 | let engine = JSEngine::init().unwrap(); 17 | let runtime = Runtime::new(engine.handle()); 18 | let context = runtime.cx(); 19 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 20 | let c_option = RealmOptions::default(); 21 | 22 | unsafe { 23 | rooted!(in(context) let global = JS_NewGlobalObject( 24 | context, 25 | &SIMPLE_GLOBAL_CLASS, 26 | ptr::null_mut(), 27 | h_option, 28 | &*c_option, 29 | )); 30 | 31 | rooted!(in(context) let mut rval = UndefinedValue()); 32 | assert!(runtime 33 | .evaluate_script(global.handle(), "1 + 1", "test", 1, rval.handle_mut()) 34 | .is_ok()); 35 | assert_eq!(rval.get().to_int32(), 2); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gen.py: -------------------------------------------------------------------------------- 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 | import argparse, subprocess; 6 | 7 | bindgen = "bindgen"; 8 | 9 | jsapi = "../mozjs/js/src/jsapi.h" 10 | includes = [ 11 | "-I", "../mozjs/js/src/dist/include", 12 | ] 13 | sysincludes = [ 14 | "-isystem", "/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5/include", 15 | "-isystem", "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include", 16 | ] 17 | 18 | args = [ 19 | bindgen, 20 | "-l", "mozjs", 21 | "-o", "jsapi.rs", 22 | "-match" ,"js", 23 | jsapi] 24 | args += includes + sysincludes 25 | 26 | subprocess.call(args) 27 | 28 | # To generate jsglue: 29 | # DYLD_LIBRARY_PATH=~/versioned/rust-mozilla/build/llvm/x86_64-apple-darwin/Release+Asserts/lib/ ~/versioned/rust-bindgen/bindgen ./jsglue.c -I ../../build/src/mozjs/dist/include/ -match glue > glue.rs 30 | 31 | # jdm used 32 | # LD_LIBRARY_PATH=~/sdb/rust/build/llvm/x86_64-unknown-linux-gnu/Release+Asserts/lib/ ~/sdb/rust-bindgen/bindgen ./jsglue.c -I ../../build/src/mozjs/dist/include/ -isystem /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/ -match glue >glue.rs 33 | # on Fedora 17 34 | # 35 | # and remember to mark all generated functions as #[rust_stack] 36 | -------------------------------------------------------------------------------- /tests/stack_limit.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate mozjs; 7 | 8 | use std::ptr; 9 | 10 | use mozjs::jsapi::{JS_NewGlobalObject, OnNewGlobalHookOption}; 11 | use mozjs::jsval::UndefinedValue; 12 | use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 13 | 14 | #[test] 15 | fn stack_limit() { 16 | let engine = JSEngine::init().unwrap(); 17 | let runtime = Runtime::new(engine.handle()); 18 | let context = runtime.cx(); 19 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 20 | let c_option = RealmOptions::default(); 21 | 22 | unsafe { 23 | rooted!(in(context) let global = JS_NewGlobalObject( 24 | context, 25 | &SIMPLE_GLOBAL_CLASS, 26 | ptr::null_mut(), 27 | h_option, 28 | &*c_option, 29 | )); 30 | rooted!(in(context) let mut rval = UndefinedValue()); 31 | assert!(runtime 32 | .evaluate_script( 33 | global.handle(), 34 | "function f() { f.apply() } f()", 35 | "test", 36 | 1, 37 | rval.handle_mut() 38 | ) 39 | .is_err()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mozjs" 3 | description = "Rust bindings to the Mozilla SpiderMonkey JavaScript engine." 4 | repository = "https://github.com/servo/rust-mozjs" 5 | version = "0.14.1" 6 | authors = ["The Servo Project Developers"] 7 | build = "build.rs" 8 | license = "MPL-2.0" 9 | 10 | [build-dependencies] 11 | cc = "1" 12 | 13 | [[example]] 14 | name = "minimal" 15 | [[example]] 16 | name = "eval" 17 | 18 | [[test]] 19 | name = "callback" 20 | [[test]] 21 | name = "capture_stack" 22 | [[test]] 23 | name = "custom_auto_rooter" 24 | [[test]] 25 | name = "custom_auto_rooter_macro" 26 | [[test]] 27 | name = "enumerate" 28 | [[test]] 29 | name = "evaluate" 30 | [[test]] 31 | name = "panic" 32 | [[test]] 33 | name = "property_descriptor" 34 | [[test]] 35 | name = "rooting" 36 | [[test]] 37 | name = "runtime" 38 | [[test]] 39 | name = "runtime_no_outlive" 40 | [[test]] 41 | name = "typedarray" 42 | [[test]] 43 | name = "typedarray_panic" 44 | [[test]] 45 | name = "stack_limit" 46 | [[test]] 47 | name = "vec_conversion" 48 | 49 | [lib] 50 | doctest = false 51 | 52 | [features] 53 | debugmozjs = ['mozjs_sys/debugmozjs'] 54 | jitspew = ['mozjs_sys/jitspew'] 55 | profilemozjs = ['mozjs_sys/profilemozjs'] 56 | uwp = ['mozjs_sys/uwp'] 57 | 58 | [dependencies] 59 | lazy_static = "1" 60 | libc = "0.2" 61 | log = "0.4" 62 | num-traits = "0.2" 63 | mozjs_sys = { git = "https://github.com/servo/mozjs", rev="72ce2c95d24b225e3c87364608822b498b2312fb" } 64 | -------------------------------------------------------------------------------- /tests/custom_auto_rooter.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | extern crate mozjs; 6 | 7 | use std::cell::Cell; 8 | 9 | use mozjs::jsapi::{GCReason, JSTracer, JS_GC}; 10 | use mozjs::rust::{CustomAutoRooter, CustomTrace, JSEngine, Runtime}; 11 | 12 | struct TraceCheck { 13 | trace_was_called: Cell, 14 | } 15 | 16 | impl TraceCheck { 17 | fn new() -> TraceCheck { 18 | TraceCheck { 19 | trace_was_called: Cell::new(false), 20 | } 21 | } 22 | } 23 | 24 | unsafe impl CustomTrace for TraceCheck { 25 | fn trace(&self, _: *mut JSTracer) { 26 | self.trace_was_called.set(true); 27 | } 28 | } 29 | 30 | /// Check if Rust reimplementation of CustomAutoRooter properly appends itself 31 | /// to autoGCRooters stack list and if C++ inheritance was properly simulated 32 | /// by checking if appropriate virtual trace function was called. 33 | #[test] 34 | fn virtual_trace_called() { 35 | let engine = JSEngine::init().unwrap(); 36 | let runtime = Runtime::new(engine.handle()); 37 | let context = runtime.cx(); 38 | 39 | let mut rooter = CustomAutoRooter::new(TraceCheck::new()); 40 | let guard = rooter.root(context); 41 | 42 | unsafe { 43 | JS_GC(context, GCReason::API); 44 | } 45 | 46 | assert!(guard.trace_was_called.get()); 47 | } 48 | -------------------------------------------------------------------------------- /tests/typedarray_panic.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate mozjs; 7 | 8 | use std::ptr; 9 | 10 | use mozjs::jsapi::{JSAutoRealm, JSObject, JS_NewGlobalObject, OnNewGlobalHookOption}; 11 | use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 12 | use mozjs::typedarray::{CreateWith, Uint32Array}; 13 | 14 | #[test] 15 | #[should_panic] 16 | fn typedarray_update_panic() { 17 | let engine = JSEngine::init().unwrap(); 18 | let runtime = Runtime::new(engine.handle()); 19 | let context = runtime.cx(); 20 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 21 | let c_option = RealmOptions::default(); 22 | 23 | unsafe { 24 | rooted!(in(context) let global = JS_NewGlobalObject( 25 | context, 26 | &SIMPLE_GLOBAL_CLASS, 27 | ptr::null_mut(), 28 | h_option, 29 | &*c_option, 30 | )); 31 | let _ac = JSAutoRealm::new(context, global.get()); 32 | 33 | rooted!(in(context) let mut rval = ptr::null_mut::()); 34 | let _ = Uint32Array::create(context, CreateWith::Slice(&[1, 2, 3, 4, 5]), rval.handle_mut()); 35 | typedarray!(in(context) let mut array: Uint32Array = rval.get()); 36 | array.as_mut().unwrap().update(&[0, 2, 4, 6, 8, 10]); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/panic.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate mozjs; 7 | 8 | use std::ptr; 9 | 10 | use mozjs::jsapi::{JSAutoRealm, JSContext, OnNewGlobalHookOption, Value}; 11 | use mozjs::jsapi::{JS_DefineFunction, JS_NewGlobalObject}; 12 | use mozjs::jsval::UndefinedValue; 13 | use mozjs::panic::wrap_panic; 14 | use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 15 | 16 | #[test] 17 | #[should_panic] 18 | fn test_panic() { 19 | let engine = JSEngine::init().unwrap(); 20 | let runtime = Runtime::new(engine.handle()); 21 | let context = runtime.cx(); 22 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 23 | let c_option = RealmOptions::default(); 24 | 25 | unsafe { 26 | rooted!(in(context) let global = JS_NewGlobalObject( 27 | context, 28 | &SIMPLE_GLOBAL_CLASS, 29 | ptr::null_mut(), 30 | h_option, 31 | &*c_option, 32 | )); 33 | let _ac = JSAutoRealm::new(context, global.get()); 34 | 35 | let function = JS_DefineFunction( 36 | context, 37 | global.handle().into(), 38 | b"test\0".as_ptr() as *const _, 39 | Some(test), 40 | 0, 41 | 0, 42 | ); 43 | assert!(!function.is_null()); 44 | 45 | rooted!(in(context) let mut rval = UndefinedValue()); 46 | let _ = 47 | runtime.evaluate_script(global.handle(), "test();", "test.js", 0, rval.handle_mut()); 48 | } 49 | } 50 | 51 | unsafe extern "C" fn test(_cx: *mut JSContext, _argc: u32, _vp: *mut Value) -> bool { 52 | let mut result = false; 53 | wrap_panic(&mut || { 54 | panic!(); 55 | #[allow(unreachable_code)] 56 | { 57 | result = true 58 | } 59 | }); 60 | result 61 | } 62 | -------------------------------------------------------------------------------- /examples/minimal.rs: -------------------------------------------------------------------------------- 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 | } 53 | -------------------------------------------------------------------------------- /examples/eval.rs: -------------------------------------------------------------------------------- 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 | } 63 | -------------------------------------------------------------------------------- /tests/enumerate.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate mozjs; 7 | 8 | use std::ptr; 9 | 10 | use mozjs::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING}; 11 | use mozjs::jsapi::{GetPropertyKeys, JS_NewGlobalObject, JS_StringEqualsAscii, OnNewGlobalHookOption}; 12 | use mozjs::jsapi::JSITER_OWNONLY; 13 | use mozjs::jsval::UndefinedValue; 14 | use mozjs::rust::{IdVector, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 15 | 16 | #[test] 17 | fn enumerate() { 18 | let engine = JSEngine::init().unwrap(); 19 | let runtime = Runtime::new(engine.handle()); 20 | let context = runtime.cx(); 21 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 22 | let c_option = RealmOptions::default(); 23 | 24 | unsafe { 25 | rooted!(in(context) let global = JS_NewGlobalObject( 26 | context, 27 | &SIMPLE_GLOBAL_CLASS, 28 | ptr::null_mut(), 29 | h_option, 30 | &*c_option, 31 | )); 32 | 33 | rooted!(in(context) let mut rval = UndefinedValue()); 34 | assert!(runtime 35 | .evaluate_script( 36 | global.handle(), 37 | "({ 'a': 7 })", 38 | "test", 39 | 1, 40 | rval.handle_mut() 41 | ) 42 | .is_ok()); 43 | assert!(rval.is_object()); 44 | 45 | rooted!(in(context) let object = rval.to_object()); 46 | let mut ids = IdVector::new(context); 47 | assert!(GetPropertyKeys( 48 | context, 49 | object.handle().into(), 50 | JSITER_OWNONLY, 51 | ids.handle_mut(), 52 | )); 53 | 54 | assert_eq!(ids.len(), 1); 55 | rooted!(in(context) let id = ids[0]); 56 | 57 | assert!(RUST_JSID_IS_STRING(id.handle().into())); 58 | rooted!(in(context) let id = RUST_JSID_TO_STRING(id.handle().into())); 59 | 60 | let mut matches = false; 61 | assert!(JS_StringEqualsAscii( 62 | context, 63 | id.get(), 64 | b"a\0" as *const _ as *const _, 65 | &mut matches 66 | )); 67 | assert!(matches); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 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 | #![crate_name = "mozjs"] 6 | #![crate_type = "rlib"] 7 | #![allow( 8 | non_upper_case_globals, 9 | non_camel_case_types, 10 | non_snake_case, 11 | improper_ctypes 12 | )] 13 | 14 | //! 15 | //! This crate contains Rust bindings to the [SpiderMonkey Javascript engine][1] 16 | //! developed by Mozilla. 17 | //! 18 | //! These bindings are designed to be a fairly straightforward translation to the C++ API, while 19 | //! taking advantage of Rust's memory safety. For more about the Spidermonkey API, see the 20 | //! [API Reference][2] and the [User Guide][3] on MDN, and the [embedding examples][4] on GitHub. 21 | //! 22 | //! The code from User Guide sections [A minimal example](https://github.com/servo/rust-mozjs/tree/master/examples/minimal.rs) and 23 | //! [Running scripts](https://github.com/servo/rust-mozjs/tree/master/examples/eval.rs) are also included. 24 | //! 25 | //! [1]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey 26 | //! [2]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference 27 | //! [3]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide 28 | //! [4]: https://github.com/mozilla-spidermonkey/spidermonkey-embedding-examples/ 29 | //! 30 | 31 | #[macro_use] 32 | extern crate lazy_static; 33 | extern crate libc; 34 | #[macro_use] 35 | extern crate log; 36 | extern crate mozjs_sys; 37 | extern crate num_traits; 38 | 39 | pub mod jsapi { 40 | pub use mozjs_sys::jsapi::glue::*; 41 | pub use mozjs_sys::jsapi::js::detail::*; 42 | pub use mozjs_sys::jsapi::js::Scalar::Type; 43 | pub use mozjs_sys::jsapi::js::*; 44 | pub use mozjs_sys::jsapi::mozilla::MallocSizeOf; 45 | pub use mozjs_sys::jsapi::JS::detail::*; 46 | pub use mozjs_sys::jsapi::JS::shadow::Object; 47 | pub use mozjs_sys::jsapi::JS::*; 48 | pub use mozjs_sys::jsapi::*; 49 | } 50 | 51 | #[macro_use] 52 | pub mod rust; 53 | 54 | mod consts; 55 | pub mod conversions; 56 | pub mod error; 57 | pub mod glue; 58 | pub mod panic; 59 | pub mod typedarray; 60 | 61 | pub use consts::*; 62 | pub use mozjs_sys::jsval; 63 | 64 | pub use jsval::JS_ARGV; 65 | pub use jsval::JS_CALLEE; 66 | -------------------------------------------------------------------------------- /src/glue_wrappers.in: -------------------------------------------------------------------------------- 1 | wrap!(glue: pub fn InvokeGetOwnPropertyDescriptor(handler: *const ::libc::c_void, cx: *mut JSContext, proxy: HandleObject, id: HandleId, desc: MutableHandle) -> bool); 2 | wrap!(glue: pub fn InvokeHasOwn(handler: *const ::libc::c_void, cx: *mut JSContext, proxy: HandleObject, id: HandleId, bp: *mut bool) -> bool); 3 | wrap!(glue: pub fn CallJitGetterOp(info: *const JSJitInfo, cx: *mut JSContext, thisObj: HandleObject, specializedThis: *mut ::libc::c_void, argc: u32, vp: *mut Value) -> bool); 4 | wrap!(glue: pub fn CallJitSetterOp(info: *const JSJitInfo, cx: *mut JSContext, thisObj: HandleObject, specializedThis: *mut ::libc::c_void, argc: u32, vp: *mut Value) -> bool); 5 | wrap!(glue: pub fn CallJitMethodOp(info: *const JSJitInfo, cx: *mut JSContext, thisObj: HandleObject, specializedThis: *mut ::libc::c_void, argc: u32, vp: *mut Value) -> bool); 6 | wrap!(glue: pub fn NewProxyObject(aCx: *mut JSContext, aHandler: *const ::libc::c_void, aPriv: HandleValue, proto: *mut JSObject, classp: *const JSClass, aLazyProto: bool) -> *mut JSObject); 7 | wrap!(glue: pub fn WrapperNew(aCx: *mut JSContext, aObj: HandleObject, aHandler: *const ::libc::c_void, aClass: *const JSClass, aSingleton: bool) -> *mut JSObject); 8 | wrap!(glue: pub fn NewWindowProxy(aCx: *mut JSContext, aObj: HandleObject, aHandler: *const ::libc::c_void) -> *mut JSObject); 9 | wrap!(glue: pub fn RUST_JSID_IS_INT(id: HandleId) -> bool); 10 | wrap!(glue: pub fn RUST_JSID_TO_INT(id: HandleId) -> i32); 11 | wrap!(glue: pub fn int_to_jsid(i: i32, id: MutableHandleId)); 12 | wrap!(glue: pub fn RUST_JSID_IS_STRING(id: HandleId) -> bool); 13 | wrap!(glue: pub fn RUST_JSID_TO_STRING(id: HandleId) -> *mut JSString); 14 | wrap!(glue: pub fn RUST_SYMBOL_TO_JSID(sym: *mut Symbol, id: MutableHandleId)); 15 | wrap!(glue: pub fn RUST_JSID_IS_VOID(id: HandleId) -> bool); 16 | wrap!(glue: pub fn RUST_INTERNED_STRING_TO_JSID(cx: *mut JSContext, str: *mut JSString, id: MutableHandleId)); 17 | wrap!(glue: pub fn AppendToIdVector(v: MutableHandleIdVector, id: HandleId) -> bool); 18 | wrap!(glue: pub fn JS_GetPromiseResult(promise: HandleObject, dest: MutableHandleValue)); 19 | wrap!(glue: pub fn JS_GetScriptPrivate(script: *mut JSScript, dest: MutableHandleValue)); 20 | wrap!(glue: pub fn JS_GetModulePrivate(module: *mut JSObject, dest: MutableHandleValue)); 21 | wrap!(glue: pub fn EncodeStringToUTF8(cx: *mut JSContext, str: HandleString, cb: fn(*const c_char))); 22 | -------------------------------------------------------------------------------- /tests/runtime.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | extern crate libc; 6 | #[macro_use] 7 | extern crate mozjs; 8 | 9 | use std::ptr; 10 | use std::sync::mpsc::channel; 11 | use std::thread; 12 | 13 | use mozjs::jsapi::JSCLASS_FOREGROUND_FINALIZE; 14 | use mozjs::jsapi::{JSAutoRealm, JSClass, JSClassOps, JSFreeOp, JSObject, OnNewGlobalHookOption}; 15 | use mozjs::jsapi::{JS_NewGlobalObject, JS_NewObject}; 16 | use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 17 | 18 | #[test] 19 | fn runtime() { 20 | let engine = JSEngine::init().unwrap(); 21 | let runtime = Runtime::new(engine.handle()); 22 | let context = runtime.cx(); 23 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 24 | let c_option = RealmOptions::default(); 25 | 26 | unsafe { 27 | rooted!(in(context) let global = JS_NewGlobalObject( 28 | context, 29 | &SIMPLE_GLOBAL_CLASS, 30 | ptr::null_mut(), 31 | h_option, 32 | &*c_option, 33 | )); 34 | let _ac = JSAutoRealm::new(context, global.get()); 35 | rooted!(in(context) let _object = JS_NewObject(context, &CLASS as *const _)); 36 | } 37 | 38 | let parent = runtime.prepare_for_new_child(); 39 | let (sender, receiver) = channel(); 40 | thread::spawn(move || { 41 | let runtime = unsafe { Runtime::create_with_parent(parent) }; 42 | assert!(!Runtime::get().is_null()); 43 | drop(runtime); 44 | let _ = sender.send(()); 45 | }); 46 | let _ = receiver.recv(); 47 | } 48 | 49 | unsafe extern "C" fn finalize(_fop: *mut JSFreeOp, _object: *mut JSObject) { 50 | assert!(!Runtime::get().is_null()); 51 | } 52 | 53 | static CLASS_OPS: JSClassOps = JSClassOps { 54 | addProperty: None, 55 | delProperty: None, 56 | enumerate: None, 57 | newEnumerate: None, 58 | resolve: None, 59 | mayResolve: None, 60 | finalize: Some(finalize), 61 | call: None, 62 | hasInstance: None, 63 | construct: None, 64 | trace: None, 65 | }; 66 | 67 | static CLASS: JSClass = JSClass { 68 | name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char, 69 | flags: JSCLASS_FOREGROUND_FINALIZE, 70 | cOps: &CLASS_OPS as *const JSClassOps, 71 | spec: ptr::null(), 72 | ext: ptr::null(), 73 | oOps: ptr::null(), 74 | }; 75 | -------------------------------------------------------------------------------- /tests/capture_stack.rs: -------------------------------------------------------------------------------- 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 | extern crate libc; 6 | #[macro_use] 7 | extern crate mozjs; 8 | 9 | use std::ptr; 10 | 11 | use mozjs::jsapi::{CallArgs, JSAutoRealm, JSContext, OnNewGlobalHookOption, StackFormat, Value}; 12 | use mozjs::jsapi::{JS_DefineFunction, JS_NewGlobalObject}; 13 | use mozjs::jsval::UndefinedValue; 14 | use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 15 | 16 | #[test] 17 | fn capture_stack() { 18 | let engine = JSEngine::init().unwrap(); 19 | let runtime = Runtime::new(engine.handle()); 20 | let context = runtime.cx(); 21 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 22 | let c_option = RealmOptions::default(); 23 | 24 | unsafe { 25 | rooted!(in(context) let global = JS_NewGlobalObject( 26 | context, 27 | &SIMPLE_GLOBAL_CLASS, 28 | ptr::null_mut(), 29 | h_option, 30 | &*c_option, 31 | )); 32 | let _ac = JSAutoRealm::new(context, global.get()); 33 | 34 | let function = JS_DefineFunction( 35 | context, 36 | global.handle().into(), 37 | b"print_stack\0".as_ptr() as *const libc::c_char, 38 | Some(print_stack), 39 | 0, 40 | 0, 41 | ); 42 | assert!(!function.is_null()); 43 | 44 | let javascript = " 45 | function foo(arg1) { 46 | var bar = function() { 47 | print_stack(); 48 | }; 49 | bar(); 50 | } 51 | 52 | foo(\"arg1-value\"); 53 | "; 54 | rooted!(in(context) let mut rval = UndefinedValue()); 55 | assert!(runtime 56 | .evaluate_script(global.handle(), javascript, "test.js", 0, rval.handle_mut()) 57 | .is_ok()); 58 | } 59 | } 60 | 61 | unsafe extern "C" fn print_stack(context: *mut JSContext, argc: u32, vp: *mut Value) -> bool { 62 | let args = CallArgs::from_vp(vp, argc); 63 | 64 | capture_stack!(in(context) let stack); 65 | let str_stack = stack 66 | .unwrap() 67 | .as_string(None, StackFormat::SpiderMonkey) 68 | .unwrap(); 69 | println!("{}", str_stack); 70 | assert_eq!( 71 | "bar@test.js:3:21\nfoo@test.js:5:17\n@test.js:8:16\n".to_string(), 72 | str_stack 73 | ); 74 | 75 | args.rval().set(UndefinedValue()); 76 | true 77 | } 78 | -------------------------------------------------------------------------------- /tests/callback.rs: -------------------------------------------------------------------------------- 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 | extern crate libc; 6 | #[macro_use] 7 | extern crate mozjs; 8 | 9 | use std::ffi::CStr; 10 | use std::ptr; 11 | use std::str; 12 | 13 | use mozjs::glue::EncodeStringToUTF8; 14 | use mozjs::jsapi::{CallArgs, JSAutoRealm, JSContext, OnNewGlobalHookOption, Value}; 15 | use mozjs::jsapi::{JS_DefineFunction, JS_NewGlobalObject, JS_ReportErrorASCII}; 16 | use mozjs::jsval::UndefinedValue; 17 | use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 18 | 19 | #[test] 20 | fn callback() { 21 | let engine = JSEngine::init().unwrap(); 22 | let runtime = Runtime::new(engine.handle()); 23 | let context = runtime.cx(); 24 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 25 | let c_option = RealmOptions::default(); 26 | 27 | unsafe { 28 | rooted!(in(context) let global = JS_NewGlobalObject( 29 | context, 30 | &SIMPLE_GLOBAL_CLASS, 31 | ptr::null_mut(), 32 | h_option, 33 | &*c_option, 34 | )); 35 | let _ac = JSAutoRealm::new(context, global.get()); 36 | 37 | let function = JS_DefineFunction( 38 | context, 39 | global.handle().into(), 40 | b"puts\0".as_ptr() as *const libc::c_char, 41 | Some(puts), 42 | 1, 43 | 0, 44 | ); 45 | assert!(!function.is_null()); 46 | 47 | let javascript = "puts('Test Iñtërnâtiônàlizætiøn ┬─┬ノ( º _ ºノ) ');"; 48 | rooted!(in(context) let mut rval = UndefinedValue()); 49 | assert!(runtime 50 | .evaluate_script(global.handle(), javascript, "test.js", 0, rval.handle_mut()) 51 | .is_ok()); 52 | } 53 | } 54 | 55 | unsafe extern "C" fn puts(context: *mut JSContext, argc: u32, vp: *mut Value) -> bool { 56 | let args = CallArgs::from_vp(vp, argc); 57 | 58 | if args.argc_ != 1 { 59 | JS_ReportErrorASCII( 60 | context, 61 | b"puts() requires exactly 1 argument\0".as_ptr() as *const libc::c_char, 62 | ); 63 | return false; 64 | } 65 | 66 | let arg = mozjs::rust::Handle::from_raw(args.get(0)); 67 | let js = mozjs::rust::ToString(context, arg); 68 | rooted!(in(context) let message_root = js); 69 | EncodeStringToUTF8(context, message_root.handle().into(), |message| { 70 | let message = CStr::from_ptr(message); 71 | let message = str::from_utf8(message.to_bytes()).unwrap(); 72 | assert_eq!(message, "Test Iñtërnâtiônàlizætiøn ┬─┬ノ( º _ ºノ) "); 73 | println!("{}", message); 74 | }); 75 | 76 | args.rval().set(UndefinedValue()); 77 | true 78 | } 79 | -------------------------------------------------------------------------------- /tests/vec_conversion.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate mozjs; 7 | 8 | use std::ptr; 9 | 10 | use mozjs::conversions::{ 11 | ConversionBehavior, ConversionResult, FromJSValConvertible, ToJSValConvertible, 12 | }; 13 | use mozjs::jsapi::{ 14 | InitRealmStandardClasses, JSAutoRealm, JS_NewGlobalObject, OnNewGlobalHookOption, 15 | }; 16 | use mozjs::jsval::UndefinedValue; 17 | use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 18 | 19 | #[test] 20 | fn vec_conversion() { 21 | let engine = JSEngine::init().unwrap(); 22 | let runtime = Runtime::new(engine.handle()); 23 | let context = runtime.cx(); 24 | 25 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 26 | let c_option = RealmOptions::default(); 27 | 28 | unsafe { 29 | rooted!(in(context) let global = JS_NewGlobalObject( 30 | context, 31 | &SIMPLE_GLOBAL_CLASS, 32 | ptr::null_mut(), 33 | h_option, 34 | &*c_option, 35 | )); 36 | let _ac = JSAutoRealm::new(context, global.get()); 37 | assert!(InitRealmStandardClasses(context)); 38 | 39 | rooted!(in(context) let mut rval = UndefinedValue()); 40 | 41 | let orig_vec: Vec = vec![1.0, 2.9, 3.0]; 42 | orig_vec.to_jsval(context, rval.handle_mut()); 43 | let converted = Vec::::from_jsval(context, rval.handle(), ()).unwrap(); 44 | 45 | assert_eq!(&orig_vec, converted.get_success_value().unwrap()); 46 | 47 | let orig_vec: Vec = vec![1, 2, 3]; 48 | orig_vec.to_jsval(context, rval.handle_mut()); 49 | let converted = 50 | Vec::::from_jsval(context, rval.handle(), ConversionBehavior::Default).unwrap(); 51 | 52 | assert_eq!(&orig_vec, converted.get_success_value().unwrap()); 53 | 54 | assert!(runtime 55 | .evaluate_script( 56 | global.handle(), 57 | "new Set([1, 2, 3])", 58 | "test", 59 | 1, 60 | rval.handle_mut() 61 | ) 62 | .is_ok()); 63 | let converted = 64 | Vec::::from_jsval(context, rval.handle(), ConversionBehavior::Default).unwrap(); 65 | 66 | assert_eq!(&orig_vec, converted.get_success_value().unwrap()); 67 | 68 | assert!(runtime 69 | .evaluate_script(global.handle(), "({})", "test", 1, rval.handle_mut()) 70 | .is_ok()); 71 | let converted = Vec::::from_jsval(context, rval.handle(), ConversionBehavior::Default); 72 | assert!(match converted { 73 | Ok(ConversionResult::Failure(_)) => true, 74 | _ => false, 75 | }); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/property_descriptor.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate mozjs; 7 | extern crate mozjs_sys; 8 | 9 | use std::ptr; 10 | 11 | use mozjs::jsapi::{JS_NewGlobalObject, JS_NewPlainObject, FromPropertyDescriptor, JS_DefineProperty, JS_GetPropertyDescriptor}; 12 | use mozjs::jsapi::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT}; 13 | use mozjs::jsapi::{JSAutoRealm, OnNewGlobalHookOption, PropertyDescriptor}; 14 | use mozjs::jsval::{Int32Value, NullValue}; 15 | use mozjs::rust::{JSEngine, Runtime, RealmOptions, SIMPLE_GLOBAL_CLASS}; 16 | use mozjs_sys::jsapi::JS_GetProperty; 17 | 18 | #[test] 19 | fn property_descriptor() { 20 | let engine = JSEngine::init().unwrap(); 21 | let runtime = Runtime::new(engine.handle()); 22 | let context = runtime.cx(); 23 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 24 | let c_option = RealmOptions::default(); 25 | 26 | unsafe { 27 | rooted!(in(context) let global = JS_NewGlobalObject( 28 | context, 29 | &SIMPLE_GLOBAL_CLASS, 30 | ptr::null_mut(), 31 | h_option, 32 | &*c_option, 33 | )); 34 | let _ac = JSAutoRealm::new(context, global.get()); 35 | 36 | rooted!(in(context) let object = JS_NewPlainObject(context)); 37 | rooted!(in(context) let property = Int32Value(32)); 38 | 39 | let attrs = (JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY) as u32; 40 | assert!(JS_DefineProperty(context, object.handle().into(), b"property\0" as *const u8 as *const libc::c_char, property.handle().into(), attrs)); 41 | 42 | rooted!(in(context) let mut descriptor: PropertyDescriptor); 43 | 44 | assert!(JS_GetPropertyDescriptor(context, object.handle().into(), b"property\0" as *const u8 as *const libc::c_char, descriptor.handle_mut().into())); 45 | assert_eq!(descriptor.get().attrs, attrs); 46 | assert_eq!(descriptor.get().value.to_int32(), 32); 47 | 48 | rooted!(in(context) let mut desc = NullValue()); 49 | assert!(FromPropertyDescriptor(context, descriptor.handle().into(), desc.handle_mut().into())); 50 | rooted!(in(context) let desc_object = desc.to_object()); 51 | 52 | rooted!(in(context) let mut rval = NullValue()); 53 | assert!(JS_GetProperty(context, desc_object.handle().into(), b"value\0" as *const u8 as *const libc::c_char, rval.handle_mut().into())); 54 | assert_eq!(rval.get().to_int32(), 32); 55 | assert!(JS_GetProperty(context, desc_object.handle().into(), b"configurable\0" as *const u8 as *const libc::c_char, rval.handle_mut().into())); 56 | assert!(!rval.get().to_boolean()); 57 | assert!(JS_GetProperty(context, desc_object.handle().into(), b"enumerable\0" as *const u8 as *const libc::c_char, rval.handle_mut().into())); 58 | assert!(rval.get().to_boolean()); 59 | assert!(JS_GetProperty(context, desc_object.handle().into(), b"writable\0" as *const u8 as *const libc::c_char, rval.handle_mut().into())); 60 | assert!(!rval.get().to_boolean()); 61 | } 62 | } -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Functions to throw JavaScript exceptions from Rust. 6 | 7 | #![deny(missing_docs)] 8 | 9 | use jsapi::{JSContext, JSErrorFormatString, JSExnType, JS_ReportErrorNumberUTF8}; 10 | use libc; 11 | use std::ffi::CString; 12 | use std::{mem, os, ptr}; 13 | 14 | /// Format string used to throw javascript errors. 15 | static ERROR_FORMAT_STRING_STRING: [libc::c_char; 4] = [ 16 | '{' as libc::c_char, 17 | '0' as libc::c_char, 18 | '}' as libc::c_char, 19 | 0 as libc::c_char, 20 | ]; 21 | 22 | /// Format string struct used to throw `TypeError`s. 23 | static mut TYPE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString { 24 | name: b"RUSTMSG_TYPE_ERROR\0" as *const _ as *const libc::c_char, 25 | format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char, 26 | argCount: 1, 27 | exnType: JSExnType::JSEXN_TYPEERR as i16, 28 | }; 29 | 30 | /// Format string struct used to throw `RangeError`s. 31 | static mut RANGE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString { 32 | name: b"RUSTMSG_RANGE_ERROR\0" as *const _ as *const libc::c_char, 33 | format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char, 34 | argCount: 1, 35 | exnType: JSExnType::JSEXN_RANGEERR as i16, 36 | }; 37 | 38 | /// Callback used to throw javascript errors. 39 | /// See throw_js_error for info about error_number. 40 | unsafe extern "C" fn get_error_message( 41 | _user_ref: *mut os::raw::c_void, 42 | error_number: libc::c_uint, 43 | ) -> *const JSErrorFormatString { 44 | let num: JSExnType = mem::transmute(error_number); 45 | match num { 46 | JSExnType::JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString, 47 | JSExnType::JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString, 48 | _ => panic!( 49 | "Bad js error number given to get_error_message: {}", 50 | error_number 51 | ), 52 | } 53 | } 54 | 55 | /// Helper fn to throw a javascript error with the given message and number. 56 | /// Reuse the jsapi error codes to distinguish the error_number 57 | /// passed back to the get_error_message callback. 58 | /// c_uint is u32, so this cast is safe, as is casting to/from i32 from there. 59 | unsafe fn throw_js_error(cx: *mut JSContext, error: &str, error_number: u32) { 60 | let error = CString::new(error).unwrap(); 61 | JS_ReportErrorNumberUTF8( 62 | cx, 63 | Some(get_error_message), 64 | ptr::null_mut(), 65 | error_number, 66 | error.as_ptr(), 67 | ); 68 | } 69 | 70 | /// Throw a `TypeError` with the given message. 71 | pub unsafe fn throw_type_error(cx: *mut JSContext, error: &str) { 72 | throw_js_error(cx, error, JSExnType::JSEXN_TYPEERR as u32); 73 | } 74 | 75 | /// Throw a `RangeError` with the given message. 76 | pub unsafe fn throw_range_error(cx: *mut JSContext, error: &str) { 77 | throw_js_error(cx, error, JSExnType::JSEXN_RANGEERR as u32); 78 | } 79 | 80 | /// Throw an `InternalError` with the given message. 81 | pub unsafe fn throw_internal_error(cx: *mut JSContext, error: &str) { 82 | throw_js_error(cx, error, JSExnType::JSEXN_INTERNALERR as u32); 83 | } 84 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: [push, pull_request] 4 | 5 | env: 6 | CARGO_TERM_COLOR: always 7 | SHELL: /bin/bash 8 | 9 | jobs: 10 | Build: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | os: [macos-latest, ubuntu-latest, windows-latest] 16 | rust: [beta, stable] 17 | features: ["--features debugmozjs", ""] 18 | exclude: 19 | - os: windows-latest 20 | rust: beta 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Install deps on osx 24 | if: startsWith(matrix.os, 'macOS') 25 | run: | 26 | brew install python autoconf@2.13 ccache llvm yasm 27 | - name: Install deps on linux 28 | if: startsWith(matrix.os, 'ubuntu') 29 | run: | 30 | sudo apt install autoconf2.13 gcc-7 g++-7 ccache llvm -y 31 | - name: Install deps on windows 32 | if: startsWith(matrix.os, 'windows') 33 | run: | 34 | Start-BitsTransfer -Source https://ftp.mozilla.org/pub/mozilla/libraries/win32/MozillaBuildSetup-3.4.exe -Destination ./MozillaBuildSetup.exe 35 | .\MozillaBuildSetup.exe /S | Out-Null 36 | iwr -useb get.scoop.sh -outfile 'install.ps1' 37 | .\install.ps1 -RunAsAdmin 38 | scoop install llvm@14.0.6 --global 39 | echo "C:\ProgramData\scoop\shims;C:\Users\runneradmin\scoop\shims" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append 40 | # TODO: Remove this step when the compatibility issue between mozjs and 41 | # Homebrew's Python 3.10 formula (servo/rust-mozjs#559) is truly fixed 42 | - name: Select Python 3.9 43 | if: startsWith(matrix.os, 'macOS') 44 | run: | 45 | brew install python@3.9 46 | cd $(dirname $(which python3.9)) 47 | rm -f python3 pip3 48 | ln -s python3.9 python3 49 | ln -s pip3.9 pip3 50 | - uses: actions-rs/toolchain@v1 51 | with: 52 | profile: minimal 53 | toolchain: ${{ matrix.rust }} 54 | override: true 55 | default: true 56 | - name: ccache cache files 57 | if: startsWith(matrix.os, 'windows') != true 58 | uses: actions/cache@v1.1.0 59 | with: 60 | path: .ccache 61 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }} 62 | - name: Build POSIX 63 | if: startsWith(matrix.os, 'windows') != true 64 | run: | 65 | ccache -z 66 | ccache cargo build --verbose ${{ matrix.features }} 67 | ccache cargo test --verbose ${{ matrix.features }} 68 | ccache -s 69 | - name: Build Windows 70 | if: startsWith(matrix.os, 'windows') 71 | shell: cmd 72 | env: 73 | MOZTOOLS_PATH: 'C:\mozilla-build\msys\bin;C:\mozilla-build\bin' 74 | AUTOCONF: "C:/mozilla-build/msys/local/bin/autoconf-2.13" 75 | LINKER: "lld-link.exe" 76 | CC: "clang-cl.exe" 77 | CXX: "clang-cl.exe" 78 | NATIVE_WIN32_PYTHON: "C:\\mozilla-build\\python\\python.exe" 79 | PYTHON3: "C:\\mozilla-build\\python3\\python3.exe" 80 | LIBCLANG_PATH: "C:\\ProgramData\\scoop\\apps\\llvm\\current\\lib" 81 | CARGO_HOME: ${{ github.workspace }}\..\.cargo 82 | run: | 83 | cargo test --verbose --verbose ${{ matrix.features }} --lib 84 | 85 | build_result: 86 | name: homu build finished 87 | runs-on: ubuntu-latest 88 | needs: ["Build"] 89 | steps: 90 | - name: Mark the job as successful 91 | run: exit 0 92 | if: success() 93 | - name: Mark the job as unsuccessful 94 | run: exit 1 95 | if: "!success()" 96 | -------------------------------------------------------------------------------- /tests/typedarray.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #[macro_use] 6 | extern crate mozjs; 7 | 8 | use std::ptr; 9 | 10 | use mozjs::jsapi::{JSAutoRealm, JSObject, JS_NewGlobalObject, OnNewGlobalHookOption, Type}; 11 | use mozjs::jsval::UndefinedValue; 12 | use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 13 | use mozjs::typedarray::{CreateWith, Uint32Array}; 14 | 15 | #[test] 16 | fn typedarray() { 17 | let engine = JSEngine::init().unwrap(); 18 | let runtime = Runtime::new(engine.handle()); 19 | let context = runtime.cx(); 20 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 21 | let c_option = RealmOptions::default(); 22 | 23 | unsafe { 24 | rooted!(in(context) let global = JS_NewGlobalObject( 25 | context, 26 | &SIMPLE_GLOBAL_CLASS, 27 | ptr::null_mut(), 28 | h_option, 29 | &*c_option, 30 | )); 31 | let _ac = JSAutoRealm::new(context, global.get()); 32 | 33 | rooted!(in(context) let mut rval = UndefinedValue()); 34 | assert!(runtime 35 | .evaluate_script( 36 | global.handle(), 37 | "new Uint8Array([0, 2, 4])", 38 | "test", 39 | 1, 40 | rval.handle_mut() 41 | ) 42 | .is_ok()); 43 | assert!(rval.is_object()); 44 | 45 | typedarray!(in(context) let array: Uint8Array = rval.to_object()); 46 | assert_eq!(array.unwrap().as_slice(), &[0, 2, 4][..]); 47 | 48 | typedarray!(in(context) let array: Uint8Array = rval.to_object()); 49 | assert_eq!(array.unwrap().len(), 3); 50 | 51 | typedarray!(in(context) let array: Uint8Array = rval.to_object()); 52 | assert_eq!(array.unwrap().to_vec(), vec![0, 2, 4]); 53 | 54 | typedarray!(in(context) let array: Uint16Array = rval.to_object()); 55 | assert!(array.is_err()); 56 | 57 | typedarray!(in(context) let view: ArrayBufferView = rval.to_object()); 58 | assert_eq!(view.unwrap().get_array_type(), Type::Uint8); 59 | 60 | rooted!(in(context) let mut rval = ptr::null_mut::()); 61 | assert!( 62 | Uint32Array::create(context, CreateWith::Slice(&[1, 3, 5]), rval.handle_mut()).is_ok() 63 | ); 64 | 65 | typedarray!(in(context) let array: Uint32Array = rval.get()); 66 | assert_eq!(array.unwrap().as_slice(), &[1, 3, 5][..]); 67 | 68 | typedarray!(in(context) let mut array: Uint32Array = rval.get()); 69 | array.as_mut().unwrap().update(&[2, 4, 6]); 70 | assert_eq!(array.unwrap().as_slice(), &[2, 4, 6][..]); 71 | 72 | rooted!(in(context) let rval = ptr::null_mut::()); 73 | typedarray!(in(context) let array: Uint8Array = rval.get()); 74 | assert!(array.is_err()); 75 | 76 | rooted!(in(context) let mut rval = ptr::null_mut::()); 77 | assert!(Uint32Array::create(context, CreateWith::Length(5), rval.handle_mut()).is_ok()); 78 | 79 | typedarray!(in(context) let array: Uint32Array = rval.get()); 80 | assert_eq!(array.unwrap().as_slice(), &[0, 0, 0, 0, 0]); 81 | 82 | typedarray!(in(context) let mut array: Uint32Array = rval.get()); 83 | array.as_mut().unwrap().update(&[0, 1, 2, 3]); 84 | assert_eq!(array.unwrap().as_slice(), &[0, 1, 2, 3, 0]); 85 | 86 | typedarray!(in(context) let view: ArrayBufferView = rval.get()); 87 | assert_eq!(view.unwrap().get_array_type(), Type::Uint32); 88 | 89 | typedarray!(in(context) let view: ArrayBufferView = rval.get()); 90 | assert_eq!(view.unwrap().is_shared(), false); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /tests/rooting.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | #![cfg(feature = "debugmozjs")] 6 | 7 | extern crate libc; 8 | #[macro_use] 9 | extern crate mozjs; 10 | 11 | use std::ptr; 12 | 13 | use mozjs::jsapi::JSPROP_ENUMERATE; 14 | use mozjs::jsapi::{ 15 | GetRealmObjectPrototype, JS_NewGlobalObject, JS_NewObjectWithGivenProto, JS_SetGCZeal, 16 | }; 17 | use mozjs::jsapi::{ 18 | JSAutoRealm, JSClass, JSContext, JSFunction, JSFunctionSpec, JSNativeWrapper, JSObject, 19 | JSPropertySpec_Name, JSString, OnNewGlobalHookOption, Value, 20 | }; 21 | use mozjs::jsval::JSVal; 22 | use mozjs::rust::{define_methods, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; 23 | 24 | #[test] 25 | fn rooting() { 26 | let engine = JSEngine::init().unwrap(); 27 | let runtime = Runtime::new(engine.handle()); 28 | let context = runtime.cx(); 29 | let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; 30 | let c_option = RealmOptions::default(); 31 | 32 | unsafe { 33 | JS_SetGCZeal(context, 2, 1); 34 | rooted!(in(context) let global = JS_NewGlobalObject( 35 | context, 36 | &SIMPLE_GLOBAL_CLASS, 37 | ptr::null_mut(), 38 | h_option, 39 | &*c_option, 40 | )); 41 | let _ac = JSAutoRealm::new(context, global.get()); 42 | 43 | rooted!(in(context) let prototype_proto = GetRealmObjectPrototype(context)); 44 | rooted!(in(context) let proto = JS_NewObjectWithGivenProto(context, &CLASS as *const _, prototype_proto.handle().into())); 45 | define_methods(context, proto.handle(), METHODS).unwrap(); 46 | 47 | rooted!(in(context) let root: JSVal); 48 | assert_eq!(root.get().is_undefined(), true); 49 | 50 | rooted!(in(context) let root: *mut JSObject); 51 | assert_eq!(root.get().is_null(), true); 52 | 53 | rooted!(in(context) let root: *mut JSString); 54 | assert_eq!(root.get().is_null(), true); 55 | 56 | rooted!(in(context) let root: *mut JSFunction); 57 | assert_eq!(root.get().is_null(), true); 58 | } 59 | } 60 | 61 | unsafe extern "C" fn generic_method(_: *mut JSContext, _: u32, _: *mut Value) -> bool { 62 | true 63 | } 64 | 65 | const METHODS: &'static [JSFunctionSpec] = &[ 66 | JSFunctionSpec { 67 | name: JSPropertySpec_Name { 68 | string_: b"addEventListener\0" as *const u8 as *const libc::c_char, 69 | }, 70 | call: JSNativeWrapper { 71 | op: Some(generic_method), 72 | info: 0 as *const _, 73 | }, 74 | nargs: 2, 75 | flags: JSPROP_ENUMERATE as u16, 76 | selfHostedName: 0 as *const libc::c_char, 77 | }, 78 | JSFunctionSpec { 79 | name: JSPropertySpec_Name { 80 | string_: b"removeEventListener\0" as *const u8 as *const libc::c_char, 81 | }, 82 | call: JSNativeWrapper { 83 | op: Some(generic_method), 84 | info: 0 as *const _, 85 | }, 86 | nargs: 2, 87 | flags: JSPROP_ENUMERATE as u16, 88 | selfHostedName: 0 as *const libc::c_char, 89 | }, 90 | JSFunctionSpec { 91 | name: JSPropertySpec_Name { 92 | string_: b"dispatchEvent\0" as *const u8 as *const libc::c_char, 93 | }, 94 | call: JSNativeWrapper { 95 | op: Some(generic_method), 96 | info: 0 as *const _, 97 | }, 98 | nargs: 1, 99 | flags: JSPROP_ENUMERATE as u16, 100 | selfHostedName: 0 as *const libc::c_char, 101 | }, 102 | JSFunctionSpec::ZERO, 103 | ]; 104 | 105 | static CLASS: JSClass = JSClass { 106 | name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char, 107 | flags: 0, 108 | cOps: 0 as *const _, 109 | spec: ptr::null(), 110 | ext: ptr::null(), 111 | oOps: ptr::null(), 112 | }; 113 | -------------------------------------------------------------------------------- /src/typedarray.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | //! High-level, safe bindings for JS typed array APIs. Allows creating new 6 | //! typed arrays or wrapping existing JS reflectors, and prevents reinterpreting 7 | //! existing buffers as different types except in well-defined cases. 8 | 9 | use conversions::ConversionResult; 10 | use conversions::FromJSValConvertible; 11 | use conversions::ToJSValConvertible; 12 | use glue::GetFloat32ArrayLengthAndData; 13 | use glue::GetFloat64ArrayLengthAndData; 14 | use glue::GetInt16ArrayLengthAndData; 15 | use glue::GetInt32ArrayLengthAndData; 16 | use glue::GetInt8ArrayLengthAndData; 17 | use glue::GetUint16ArrayLengthAndData; 18 | use glue::GetUint32ArrayLengthAndData; 19 | use glue::GetUint8ArrayLengthAndData; 20 | use glue::GetUint8ClampedArrayLengthAndData; 21 | use jsapi::GetArrayBufferData; 22 | use jsapi::GetArrayBufferLengthAndData; 23 | use jsapi::GetArrayBufferViewLengthAndData; 24 | use jsapi::Heap; 25 | use jsapi::JSContext; 26 | use jsapi::JSObject; 27 | use jsapi::JSTracer; 28 | use jsapi::JS_GetArrayBufferViewType; 29 | use jsapi::JS_GetFloat32ArrayData; 30 | use jsapi::JS_GetFloat64ArrayData; 31 | use jsapi::JS_GetInt16ArrayData; 32 | use jsapi::JS_GetInt32ArrayData; 33 | use jsapi::JS_GetInt8ArrayData; 34 | use jsapi::JS_GetTypedArraySharedness; 35 | use jsapi::JS_GetUint16ArrayData; 36 | use jsapi::JS_GetUint32ArrayData; 37 | use jsapi::JS_GetUint8ArrayData; 38 | use jsapi::JS_GetUint8ClampedArrayData; 39 | use jsapi::JS_NewFloat32Array; 40 | use jsapi::JS_NewFloat64Array; 41 | use jsapi::JS_NewInt16Array; 42 | use jsapi::JS_NewInt32Array; 43 | use jsapi::JS_NewInt8Array; 44 | use jsapi::JS_NewUint16Array; 45 | use jsapi::JS_NewUint32Array; 46 | use jsapi::JS_NewUint8Array; 47 | use jsapi::JS_NewUint8ClampedArray; 48 | use jsapi::NewArrayBuffer; 49 | use jsapi::Type; 50 | use jsapi::UnwrapArrayBuffer; 51 | use jsapi::UnwrapArrayBufferView; 52 | use jsapi::UnwrapFloat32Array; 53 | use jsapi::UnwrapFloat64Array; 54 | use jsapi::UnwrapInt16Array; 55 | use jsapi::UnwrapInt32Array; 56 | use jsapi::UnwrapInt8Array; 57 | use jsapi::UnwrapUint16Array; 58 | use jsapi::UnwrapUint32Array; 59 | use jsapi::UnwrapUint8Array; 60 | use jsapi::UnwrapUint8ClampedArray; 61 | use rust::CustomTrace; 62 | use rust::{HandleValue, MutableHandleObject, MutableHandleValue}; 63 | 64 | use std::cell::Cell; 65 | use std::ptr; 66 | use std::slice; 67 | 68 | /// Trait that specifies how pointers to wrapped objects are stored. It supports 69 | /// two variants, one with bare pointer (to be rooted on stack using 70 | /// CustomAutoRooter) and wrapped in a Box>, which can be stored in a 71 | /// heap-allocated structure, to be rooted with JSTraceable-implementing tracers 72 | /// (currently implemented in Servo). 73 | pub trait JSObjectStorage { 74 | fn as_raw(&self) -> *mut JSObject; 75 | fn from_raw(raw: *mut JSObject) -> Self; 76 | } 77 | 78 | impl JSObjectStorage for *mut JSObject { 79 | fn as_raw(&self) -> *mut JSObject { 80 | *self 81 | } 82 | fn from_raw(raw: *mut JSObject) -> Self { 83 | raw 84 | } 85 | } 86 | 87 | impl JSObjectStorage for Box> { 88 | fn as_raw(&self) -> *mut JSObject { 89 | self.get() 90 | } 91 | fn from_raw(raw: *mut JSObject) -> Self { 92 | let boxed = Box::new(Heap::default()); 93 | boxed.set(raw); 94 | boxed 95 | } 96 | } 97 | 98 | impl FromJSValConvertible for TypedArray { 99 | type Config = (); 100 | unsafe fn from_jsval( 101 | _cx: *mut JSContext, 102 | value: HandleValue, 103 | _option: (), 104 | ) -> Result, ()> { 105 | if value.get().is_object() { 106 | Self::from(value.get().to_object()).map(ConversionResult::Success) 107 | } else { 108 | Err(()) 109 | } 110 | } 111 | } 112 | 113 | impl ToJSValConvertible for TypedArray { 114 | #[inline] 115 | unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { 116 | ToJSValConvertible::to_jsval(&self.object.as_raw(), cx, rval); 117 | } 118 | } 119 | 120 | pub enum CreateWith<'a, T: 'a> { 121 | Length(usize), 122 | Slice(&'a [T]), 123 | } 124 | 125 | /// A typed array wrapper. 126 | pub struct TypedArray { 127 | object: S, 128 | computed: Cell>, 129 | } 130 | 131 | unsafe impl CustomTrace for TypedArray 132 | where 133 | T: TypedArrayElement, 134 | { 135 | fn trace(&self, trc: *mut JSTracer) { 136 | self.object.trace(trc); 137 | } 138 | } 139 | 140 | impl TypedArray { 141 | /// Create a typed array representation that wraps an existing JS reflector. 142 | /// This operation will fail if attempted on a JS object that does not match 143 | /// the expected typed array details. 144 | pub fn from(object: *mut JSObject) -> Result { 145 | if object.is_null() { 146 | return Err(()); 147 | } 148 | unsafe { 149 | let unwrapped = T::unwrap_array(object); 150 | if unwrapped.is_null() { 151 | return Err(()); 152 | } 153 | 154 | Ok(TypedArray { 155 | object: S::from_raw(unwrapped), 156 | computed: Cell::new(None), 157 | }) 158 | } 159 | } 160 | 161 | fn data(&self) -> (*mut T::Element, usize) { 162 | if let Some(data) = self.computed.get() { 163 | return data; 164 | } 165 | 166 | let data = unsafe { T::length_and_data(self.object.as_raw()) }; 167 | self.computed.set(Some(data)); 168 | data 169 | } 170 | 171 | /// Returns the number of elements in the underlying typed array. 172 | pub fn len(&self) -> usize { 173 | self.data().1 as usize 174 | } 175 | 176 | /// # Unsafety 177 | /// 178 | /// Returned wrapped pointer to the underlying `JSObject` is meant to be 179 | /// read-only, modifying it can lead to Undefined Behaviour and violation 180 | /// of TypedArray API guarantees. 181 | /// 182 | /// Practically, this exists only to implement `JSTraceable` trait in Servo 183 | /// for Box> variant. 184 | pub unsafe fn underlying_object(&self) -> &S { 185 | &self.object 186 | } 187 | 188 | /// Retrieves an owned data that's represented by the typed array. 189 | pub fn to_vec(&self) -> Vec 190 | where 191 | T::Element: Clone, 192 | { 193 | // This is safe, because we immediately copy from the underlying buffer 194 | // to an owned collection. Otherwise, one needs to be careful, since 195 | // the underlying buffer can easily invalidated when transferred with 196 | // postMessage to another thread (To remedy that, we shouldn't 197 | // execute any JS code between getting the data pointer and using it). 198 | unsafe { self.as_slice().to_vec() } 199 | } 200 | 201 | /// # Unsafety 202 | /// 203 | /// The returned slice can be invalidated if the underlying typed array 204 | /// is neutered. 205 | pub unsafe fn as_slice(&self) -> &[T::Element] { 206 | let (pointer, length) = self.data(); 207 | slice::from_raw_parts(pointer as *const T::Element, length as usize) 208 | } 209 | 210 | /// # Unsafety 211 | /// 212 | /// The returned slice can be invalidated if the underlying typed array 213 | /// is neutered. 214 | /// 215 | /// The underlying `JSObject` can be aliased, which can lead to 216 | /// Undefined Behavior due to mutable aliasing. 217 | pub unsafe fn as_mut_slice(&mut self) -> &mut [T::Element] { 218 | let (pointer, length) = self.data(); 219 | slice::from_raw_parts_mut(pointer, length as usize) 220 | } 221 | 222 | /// Return a boolean flag which denotes whether the underlying buffer 223 | /// is a SharedArrayBuffer. 224 | pub fn is_shared(&self) -> bool { 225 | unsafe { JS_GetTypedArraySharedness(self.object.as_raw()) } 226 | } 227 | } 228 | 229 | impl TypedArray { 230 | /// Create a new JS typed array, optionally providing initial data that will 231 | /// be copied into the newly-allocated buffer. Returns the new JS reflector. 232 | pub unsafe fn create( 233 | cx: *mut JSContext, 234 | with: CreateWith, 235 | mut result: MutableHandleObject, 236 | ) -> Result<(), ()> { 237 | let length = match with { 238 | CreateWith::Length(len) => len, 239 | CreateWith::Slice(slice) => slice.len(), 240 | }; 241 | 242 | result.set(T::create_new(cx, length)); 243 | if result.get().is_null() { 244 | return Err(()); 245 | } 246 | 247 | if let CreateWith::Slice(data) = with { 248 | Self::update_raw(data, result.get()); 249 | } 250 | 251 | Ok(()) 252 | } 253 | 254 | /// Update an existed JS typed array 255 | pub unsafe fn update(&mut self, data: &[T::Element]) { 256 | Self::update_raw(data, self.object.as_raw()); 257 | } 258 | 259 | unsafe fn update_raw(data: &[T::Element], result: *mut JSObject) { 260 | let (buf, length) = T::length_and_data(result); 261 | assert!(data.len() <= length as usize); 262 | ptr::copy_nonoverlapping(data.as_ptr(), buf, data.len()); 263 | } 264 | } 265 | 266 | /// Internal trait used to associate an element type with an underlying representation 267 | /// and various functions required to manipulate typed arrays of that element type. 268 | pub trait TypedArrayElement { 269 | /// Underlying primitive representation of this element type. 270 | type Element; 271 | /// Unwrap a typed array JS reflector for this element type. 272 | unsafe fn unwrap_array(obj: *mut JSObject) -> *mut JSObject; 273 | /// Retrieve the length and data of a typed array's buffer for this element type. 274 | unsafe fn length_and_data(obj: *mut JSObject) -> (*mut Self::Element, usize); 275 | } 276 | 277 | /// Internal trait for creating new typed arrays. 278 | pub trait TypedArrayElementCreator: TypedArrayElement { 279 | /// Create a new typed array. 280 | unsafe fn create_new(cx: *mut JSContext, length: usize) -> *mut JSObject; 281 | /// Get the data. 282 | unsafe fn get_data(obj: *mut JSObject) -> *mut Self::Element; 283 | } 284 | 285 | macro_rules! typed_array_element { 286 | ($t: ident, 287 | $element: ty, 288 | $unwrap: ident, 289 | $length_and_data: ident) => { 290 | /// A kind of typed array. 291 | pub struct $t; 292 | 293 | impl TypedArrayElement for $t { 294 | type Element = $element; 295 | unsafe fn unwrap_array(obj: *mut JSObject) -> *mut JSObject { 296 | $unwrap(obj) 297 | } 298 | 299 | unsafe fn length_and_data(obj: *mut JSObject) -> (*mut Self::Element, usize) { 300 | let mut len = 0; 301 | let mut shared = false; 302 | let mut data = ptr::null_mut(); 303 | $length_and_data(obj, &mut len, &mut shared, &mut data); 304 | assert!(!shared); 305 | (data, len) 306 | } 307 | } 308 | }; 309 | 310 | ($t: ident, 311 | $element: ty, 312 | $unwrap: ident, 313 | $length_and_data: ident, 314 | $create_new: ident, 315 | $get_data: ident) => { 316 | typed_array_element!($t, $element, $unwrap, $length_and_data); 317 | 318 | impl TypedArrayElementCreator for $t { 319 | unsafe fn create_new(cx: *mut JSContext, length: usize) -> *mut JSObject { 320 | $create_new(cx, length) 321 | } 322 | 323 | unsafe fn get_data(obj: *mut JSObject) -> *mut Self::Element { 324 | let mut shared = false; 325 | let data = $get_data(obj, &mut shared, ptr::null_mut()); 326 | assert!(!shared); 327 | data 328 | } 329 | } 330 | }; 331 | } 332 | 333 | typed_array_element!( 334 | Uint8, 335 | u8, 336 | UnwrapUint8Array, 337 | GetUint8ArrayLengthAndData, 338 | JS_NewUint8Array, 339 | JS_GetUint8ArrayData 340 | ); 341 | typed_array_element!( 342 | Uint16, 343 | u16, 344 | UnwrapUint16Array, 345 | GetUint16ArrayLengthAndData, 346 | JS_NewUint16Array, 347 | JS_GetUint16ArrayData 348 | ); 349 | typed_array_element!( 350 | Uint32, 351 | u32, 352 | UnwrapUint32Array, 353 | GetUint32ArrayLengthAndData, 354 | JS_NewUint32Array, 355 | JS_GetUint32ArrayData 356 | ); 357 | typed_array_element!( 358 | Int8, 359 | i8, 360 | UnwrapInt8Array, 361 | GetInt8ArrayLengthAndData, 362 | JS_NewInt8Array, 363 | JS_GetInt8ArrayData 364 | ); 365 | typed_array_element!( 366 | Int16, 367 | i16, 368 | UnwrapInt16Array, 369 | GetInt16ArrayLengthAndData, 370 | JS_NewInt16Array, 371 | JS_GetInt16ArrayData 372 | ); 373 | typed_array_element!( 374 | Int32, 375 | i32, 376 | UnwrapInt32Array, 377 | GetInt32ArrayLengthAndData, 378 | JS_NewInt32Array, 379 | JS_GetInt32ArrayData 380 | ); 381 | typed_array_element!( 382 | Float32, 383 | f32, 384 | UnwrapFloat32Array, 385 | GetFloat32ArrayLengthAndData, 386 | JS_NewFloat32Array, 387 | JS_GetFloat32ArrayData 388 | ); 389 | typed_array_element!( 390 | Float64, 391 | f64, 392 | UnwrapFloat64Array, 393 | GetFloat64ArrayLengthAndData, 394 | JS_NewFloat64Array, 395 | JS_GetFloat64ArrayData 396 | ); 397 | typed_array_element!( 398 | ClampedU8, 399 | u8, 400 | UnwrapUint8ClampedArray, 401 | GetUint8ClampedArrayLengthAndData, 402 | JS_NewUint8ClampedArray, 403 | JS_GetUint8ClampedArrayData 404 | ); 405 | typed_array_element!( 406 | ArrayBufferU8, 407 | u8, 408 | UnwrapArrayBuffer, 409 | GetArrayBufferLengthAndData, 410 | NewArrayBuffer, 411 | GetArrayBufferData 412 | ); 413 | typed_array_element!( 414 | ArrayBufferViewU8, 415 | u8, 416 | UnwrapArrayBufferView, 417 | GetArrayBufferViewLengthAndData 418 | ); 419 | 420 | // Default type aliases, uses bare pointer by default, since stack lifetime 421 | // should be the most common scenario 422 | macro_rules! array_alias { 423 | ($arr: ident, $heap_arr: ident, $elem: ty) => { 424 | pub type $arr = TypedArray<$elem, *mut JSObject>; 425 | pub type $heap_arr = TypedArray<$elem, Box>>; 426 | }; 427 | } 428 | 429 | array_alias!(Uint8ClampedArray, HeapUint8ClampedArray, ClampedU8); 430 | array_alias!(Uint8Array, HeapUint8Array, Uint8); 431 | array_alias!(Int8Array, HeapInt8Array, Int8); 432 | array_alias!(Uint16Array, HeapUint16Array, Uint16); 433 | array_alias!(Int16Array, HeapInt16Array, Int16); 434 | array_alias!(Uint32Array, HeapUint32Array, Uint32); 435 | array_alias!(Int32Array, HeapInt32Array, Int32); 436 | array_alias!(Float32Array, HeapFloat32Array, Float32); 437 | array_alias!(Float64Array, HeapFloat64Array, Float64); 438 | array_alias!(ArrayBuffer, HeapArrayBuffer, ArrayBufferU8); 439 | array_alias!(ArrayBufferView, HeapArrayBufferView, ArrayBufferViewU8); 440 | 441 | impl TypedArray { 442 | pub fn get_array_type(&self) -> Type { 443 | unsafe { JS_GetArrayBufferViewType(self.object.as_raw()) } 444 | } 445 | } 446 | 447 | #[macro_export] 448 | macro_rules! typedarray { 449 | (in($cx:expr) let $name:ident : $ty:ident = $init:expr) => { 450 | let mut __array = 451 | $crate::typedarray::$ty::from($init).map($crate::rust::CustomAutoRooter::new); 452 | 453 | let $name = __array.as_mut().map(|ok| ok.root($cx)); 454 | }; 455 | (in($cx:expr) let mut $name:ident : $ty:ident = $init:expr) => { 456 | let mut __array = 457 | $crate::typedarray::$ty::from($init).map($crate::rust::CustomAutoRooter::new); 458 | 459 | let mut $name = __array.as_mut().map(|ok| ok.root($cx)); 460 | }; 461 | } 462 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | 375 | -------------------------------------------------------------------------------- /src/glue.rs: -------------------------------------------------------------------------------- 1 | use jsapi::*; 2 | use std::os::raw::{c_char, c_void}; 3 | 4 | pub enum Action {} 5 | unsafe impl Sync for ProxyTraps {} 6 | /* automatically generated by rust-bindgen */ 7 | 8 | #[repr(C)] 9 | #[derive(Copy, Clone)] 10 | pub struct JobQueueTraps { 11 | pub getIncumbentGlobal: ::std::option::Option< 12 | unsafe extern "C" fn(queue: *const c_void, cx: *mut JSContext) -> *mut JSObject, 13 | >, 14 | pub enqueuePromiseJob: ::std::option::Option< 15 | unsafe extern "C" fn( 16 | queue: *const c_void, 17 | cx: *mut JSContext, 18 | promise: HandleObject, 19 | job: HandleObject, 20 | allocationSite: HandleObject, 21 | incumbentGlobal: HandleObject, 22 | ) -> bool, 23 | >, 24 | pub empty: ::std::option::Option bool>, 25 | } 26 | impl ::std::default::Default for JobQueueTraps { 27 | fn default() -> JobQueueTraps { 28 | unsafe { ::std::mem::zeroed() } 29 | } 30 | } 31 | 32 | #[repr(C)] 33 | #[derive(Copy, Clone, Default)] 34 | pub struct ReadableStreamUnderlyingSourceTraps { 35 | pub requestData: ::std::option::Option< 36 | unsafe extern "C" fn( 37 | source: *const c_void, 38 | cx: *mut JSContext, 39 | stream: HandleObject, 40 | desiredSize: usize, 41 | ), 42 | >, 43 | pub writeIntoReadRequestBuffer: ::std::option::Option< 44 | unsafe extern "C" fn( 45 | source: *const c_void, 46 | cx: *mut JSContext, 47 | stream: HandleObject, 48 | buffer: *mut c_void, 49 | length: usize, 50 | bytesWritten: *mut usize, 51 | ), 52 | >, 53 | pub cancel: ::std::option::Option< 54 | unsafe extern "C" fn( 55 | source: *const c_void, 56 | cx: *mut JSContext, 57 | stream: HandleObject, 58 | reason: HandleValue, 59 | resolve_to: *mut JS::Value, 60 | ), 61 | >, 62 | pub onClosed: ::std::option::Option< 63 | unsafe extern "C" fn(source: *const c_void, cx: *mut JSContext, stream: HandleObject), 64 | >, 65 | pub onErrored: ::std::option::Option< 66 | unsafe extern "C" fn( 67 | source: *const c_void, 68 | cx: *mut JSContext, 69 | stream: HandleObject, 70 | reason: HandleValue, 71 | ), 72 | >, 73 | pub finalize: ::std::option::Option< 74 | unsafe extern "C" fn(source: *mut JS::ReadableStreamUnderlyingSource), 75 | >, 76 | } 77 | 78 | #[repr(C)] 79 | #[derive(Copy, Clone, Default)] 80 | pub struct JSExternalStringCallbacksTraps { 81 | pub finalize: ::std::option::Option< 82 | unsafe extern "C" fn(*const c_void, *mut u16) 83 | >, 84 | pub sizeOfBuffer: ::std::option::Option< 85 | unsafe extern "C" fn(*const c_void, *const u16, MallocSizeOf) -> ::libc::size_t 86 | >, 87 | } 88 | 89 | #[repr(C)] 90 | #[derive(Copy, Clone)] 91 | pub struct ProxyTraps { 92 | pub enter: ::std::option::Option< 93 | unsafe extern "C" fn( 94 | cx: *mut JSContext, 95 | proxy: HandleObject, 96 | id: HandleId, 97 | action: Action, 98 | bp: *mut bool, 99 | ) -> bool, 100 | >, 101 | pub getOwnPropertyDescriptor: ::std::option::Option< 102 | unsafe extern "C" fn( 103 | cx: *mut JSContext, 104 | proxy: HandleObject, 105 | id: HandleId, 106 | desc: MutableHandle, 107 | ) -> bool, 108 | >, 109 | pub defineProperty: ::std::option::Option< 110 | unsafe extern "C" fn( 111 | cx: *mut JSContext, 112 | proxy: HandleObject, 113 | id: HandleId, 114 | desc: Handle, 115 | result: *mut ObjectOpResult, 116 | ) -> bool, 117 | >, 118 | pub ownPropertyKeys: ::std::option::Option< 119 | unsafe extern "C" fn( 120 | cx: *mut JSContext, 121 | proxy: HandleObject, 122 | props: MutableHandleIdVector, 123 | ) -> bool, 124 | >, 125 | pub delete_: ::std::option::Option< 126 | unsafe extern "C" fn( 127 | cx: *mut JSContext, 128 | proxy: HandleObject, 129 | id: HandleId, 130 | result: *mut ObjectOpResult, 131 | ) -> bool, 132 | >, 133 | pub enumerate: ::std::option::Option< 134 | unsafe extern "C" fn( 135 | cx: *mut JSContext, 136 | proxy: HandleObject, 137 | props: MutableHandleIdVector, 138 | ) -> bool, 139 | >, 140 | pub getPrototypeIfOrdinary: ::std::option::Option< 141 | unsafe extern "C" fn( 142 | cx: *mut JSContext, 143 | proxy: HandleObject, 144 | isOrdinary: *mut bool, 145 | protop: MutableHandleObject, 146 | ) -> bool, 147 | >, 148 | pub getPrototype: ::std::option::Option< 149 | unsafe extern "C" fn( 150 | cx: *mut JSContext, 151 | proxy: HandleObject, 152 | protop: MutableHandleObject, 153 | ) -> bool, 154 | >, 155 | pub setPrototype: ::std::option::Option< 156 | unsafe extern "C" fn( 157 | cx: *mut JSContext, 158 | proxy: HandleObject, 159 | proto: HandleObject, 160 | result: *mut ObjectOpResult, 161 | ) -> bool, 162 | >, 163 | pub setImmutablePrototype: ::std::option::Option< 164 | unsafe extern "C" fn(cx: *mut JSContext, proxy: HandleObject, succeeded: *mut bool) -> bool, 165 | >, 166 | pub preventExtensions: ::std::option::Option< 167 | unsafe extern "C" fn( 168 | cx: *mut JSContext, 169 | proxy: HandleObject, 170 | result: *mut ObjectOpResult, 171 | ) -> bool, 172 | >, 173 | pub isExtensible: ::std::option::Option< 174 | unsafe extern "C" fn(cx: *mut JSContext, proxy: HandleObject, succeeded: *mut bool) -> bool, 175 | >, 176 | pub has: ::std::option::Option< 177 | unsafe extern "C" fn( 178 | cx: *mut JSContext, 179 | proxy: HandleObject, 180 | id: HandleId, 181 | bp: *mut bool, 182 | ) -> bool, 183 | >, 184 | pub get: ::std::option::Option< 185 | unsafe extern "C" fn( 186 | cx: *mut JSContext, 187 | proxy: HandleObject, 188 | receiver: HandleValue, 189 | id: HandleId, 190 | vp: MutableHandleValue, 191 | ) -> bool, 192 | >, 193 | pub set: ::std::option::Option< 194 | unsafe extern "C" fn( 195 | cx: *mut JSContext, 196 | proxy: HandleObject, 197 | id: HandleId, 198 | v: HandleValue, 199 | receiver: HandleValue, 200 | result: *mut ObjectOpResult, 201 | ) -> bool, 202 | >, 203 | pub call: ::std::option::Option< 204 | unsafe extern "C" fn( 205 | cx: *mut JSContext, 206 | proxy: HandleObject, 207 | args: *const CallArgs, 208 | ) -> bool, 209 | >, 210 | pub construct: ::std::option::Option< 211 | unsafe extern "C" fn( 212 | cx: *mut JSContext, 213 | proxy: HandleObject, 214 | args: *const CallArgs, 215 | ) -> bool, 216 | >, 217 | pub hasOwn: ::std::option::Option< 218 | unsafe extern "C" fn( 219 | cx: *mut JSContext, 220 | proxy: HandleObject, 221 | id: HandleId, 222 | bp: *mut bool, 223 | ) -> bool, 224 | >, 225 | pub getOwnEnumerablePropertyKeys: ::std::option::Option< 226 | unsafe extern "C" fn( 227 | cx: *mut JSContext, 228 | proxy: HandleObject, 229 | props: MutableHandleIdVector, 230 | ) -> bool, 231 | >, 232 | pub nativeCall: ::std::option::Option< 233 | unsafe extern "C" fn( 234 | cx: *mut JSContext, 235 | test: IsAcceptableThis, 236 | _impl: NativeImpl, 237 | args: CallArgs, 238 | ) -> bool, 239 | >, 240 | pub hasInstance: ::std::option::Option< 241 | unsafe extern "C" fn( 242 | cx: *mut JSContext, 243 | proxy: HandleObject, 244 | v: MutableHandleValue, 245 | bp: *mut bool, 246 | ) -> bool, 247 | >, 248 | pub objectClassIs: ::std::option::Option< 249 | unsafe extern "C" fn(obj: HandleObject, classValue: ESClass, cx: *mut JSContext) -> bool, 250 | >, 251 | pub className: ::std::option::Option< 252 | unsafe extern "C" fn(cx: *mut JSContext, proxy: HandleObject) -> *const i8, 253 | >, 254 | pub fun_toString: ::std::option::Option< 255 | unsafe extern "C" fn( 256 | cx: *mut JSContext, 257 | proxy: HandleObject, 258 | isToString: bool, 259 | ) -> *mut JSString, 260 | >, 261 | pub boxedValue_unbox: ::std::option::Option< 262 | unsafe extern "C" fn( 263 | cx: *mut JSContext, 264 | proxy: HandleObject, 265 | vp: MutableHandleValue, 266 | ) -> bool, 267 | >, 268 | pub defaultValue: ::std::option::Option< 269 | unsafe extern "C" fn( 270 | cx: *mut JSContext, 271 | obj: HandleObject, 272 | hint: JSType, 273 | vp: MutableHandleValue, 274 | ) -> bool, 275 | >, 276 | pub trace: 277 | ::std::option::Option, 278 | pub finalize: 279 | ::std::option::Option, 280 | pub objectMoved: ::std::option::Option< 281 | unsafe extern "C" fn(proxy: *mut JSObject, old: *mut JSObject) -> usize, 282 | >, 283 | pub isCallable: ::std::option::Option bool>, 284 | pub isConstructor: ::std::option::Option bool>, 285 | } 286 | impl ::std::default::Default for ProxyTraps { 287 | fn default() -> ProxyTraps { 288 | unsafe { ::std::mem::zeroed() } 289 | } 290 | } 291 | #[repr(C)] 292 | #[derive(Copy, Clone)] 293 | pub struct WrapperProxyHandler { 294 | pub mTraps: ProxyTraps, 295 | } 296 | impl ::std::default::Default for WrapperProxyHandler { 297 | fn default() -> WrapperProxyHandler { 298 | unsafe { ::std::mem::zeroed() } 299 | } 300 | } 301 | #[repr(C)] 302 | #[derive(Copy, Clone)] 303 | pub struct ForwardingProxyHandler { 304 | pub mTraps: ProxyTraps, 305 | pub mExtra: *const ::libc::c_void, 306 | } 307 | impl ::std::default::Default for ForwardingProxyHandler { 308 | fn default() -> ForwardingProxyHandler { 309 | unsafe { ::std::mem::zeroed() } 310 | } 311 | } 312 | 313 | #[repr(C)] 314 | #[derive(Copy, Clone)] 315 | pub struct JSPrincipalsCallbacks { 316 | pub write: ::std::option::Option< 317 | unsafe extern "C" fn( 318 | *mut JSPrincipals, 319 | *mut JSContext, 320 | *mut JSStructuredCloneWriter, 321 | ) -> bool, 322 | >, 323 | pub isSystemOrAddonPrincipal: 324 | ::std::option::Option bool>, 325 | } 326 | 327 | extern "C" { 328 | pub fn CreateRustJSPrincipals( 329 | callbacks: *const JSPrincipalsCallbacks, 330 | private: *mut ::libc::c_void, 331 | ) -> *mut JSPrincipals; 332 | pub fn DestroyRustJSPrincipals(principals: *const JSPrincipals); 333 | pub fn GetRustJSPrincipalsPrivate(principals: *const JSPrincipals) -> *mut ::libc::c_void; 334 | pub fn InvokeGetOwnPropertyDescriptor( 335 | handler: *const ::libc::c_void, 336 | cx: *mut JSContext, 337 | proxy: HandleObject, 338 | id: HandleId, 339 | desc: MutableHandle, 340 | ) -> bool; 341 | pub fn InvokeHasOwn( 342 | handler: *const ::libc::c_void, 343 | cx: *mut JSContext, 344 | proxy: HandleObject, 345 | id: HandleId, 346 | bp: *mut bool, 347 | ) -> bool; 348 | pub fn RUST_JS_NumberValue(d: f64, dest: *mut JS::Value); 349 | pub fn RUST_FUNCTION_VALUE_TO_JITINFO(v: Value) -> *const JSJitInfo; 350 | pub fn CreateCallArgsFromVp(argc: u32, v: *mut Value) -> CallArgs; 351 | pub fn CallJitGetterOp( 352 | info: *const JSJitInfo, 353 | cx: *mut JSContext, 354 | thisObj: HandleObject, 355 | specializedThis: *mut ::libc::c_void, 356 | argc: u32, 357 | vp: *mut Value, 358 | ) -> bool; 359 | pub fn CallJitSetterOp( 360 | info: *const JSJitInfo, 361 | cx: *mut JSContext, 362 | thisObj: HandleObject, 363 | specializedThis: *mut ::libc::c_void, 364 | argc: u32, 365 | vp: *mut Value, 366 | ) -> bool; 367 | pub fn CallJitMethodOp( 368 | info: *const JSJitInfo, 369 | cx: *mut JSContext, 370 | thisObj: HandleObject, 371 | specializedThis: *mut ::libc::c_void, 372 | argc: u32, 373 | vp: *mut Value, 374 | ) -> bool; 375 | pub fn CreateProxyHandler( 376 | aTraps: *const ProxyTraps, 377 | aExtra: *const ::libc::c_void, 378 | ) -> *const ::libc::c_void; 379 | pub fn CreateWrapperProxyHandler(aTraps: *const ProxyTraps) -> *const ::libc::c_void; 380 | pub fn GetCrossCompartmentWrapper() -> *const ::libc::c_void; 381 | pub fn GetSecurityWrapper() -> *const ::libc::c_void; 382 | pub fn NewCompileOptions( 383 | aCx: *mut JSContext, 384 | aFile: *const ::libc::c_char, 385 | aLine: u32, 386 | ) -> *mut ReadOnlyCompileOptions; 387 | pub fn DeleteCompileOptions(aOpts: *mut ReadOnlyCompileOptions); 388 | pub fn NewProxyObject( 389 | aCx: *mut JSContext, 390 | aHandler: *const ::libc::c_void, 391 | aPriv: HandleValue, 392 | proto: *mut JSObject, 393 | classp: *const JSClass, 394 | aLazyProto: bool, 395 | ) -> *mut JSObject; 396 | pub fn WrapperNew( 397 | aCx: *mut JSContext, 398 | aObj: HandleObject, 399 | aHandler: *const ::libc::c_void, 400 | aClass: *const JSClass, 401 | aSingleton: bool, 402 | ) -> *mut JSObject; 403 | 404 | pub fn NewWindowProxy( 405 | aCx: *mut JSContext, 406 | aObj: HandleObject, 407 | aHandler: *const ::libc::c_void, 408 | ) -> *mut JSObject; 409 | pub fn GetWindowProxyClass() -> *const JSClass; 410 | pub fn GetProxyReservedSlot(obj: *mut JSObject, slot: u32, dest: *mut JS::Value); 411 | pub fn GetProxyPrivate(obj: *mut JSObject, dest: *mut JS::Value); 412 | pub fn SetProxyReservedSlot(obj: *mut JSObject, slot: u32, val: *const JS::Value); 413 | pub fn SetProxyPrivate(obj: *mut JSObject, expando: *const JS::Value); 414 | 415 | pub fn RUST_JSID_IS_INT(id: HandleId) -> bool; 416 | pub fn RUST_JSID_TO_INT(id: HandleId) -> i32; 417 | pub fn int_to_jsid(i: i32, id: MutableHandleId); 418 | pub fn RUST_JSID_IS_STRING(id: HandleId) -> bool; 419 | pub fn RUST_JSID_TO_STRING(id: HandleId) -> *mut JSString; 420 | pub fn RUST_SYMBOL_TO_JSID(sym: *mut Symbol, id: MutableHandleId); 421 | pub fn RUST_JSID_IS_VOID(id: HandleId) -> bool; 422 | pub fn SetBuildId(buildId: *mut JS::BuildIdCharVector, chars: *const u8, len: usize) -> bool; 423 | pub fn RUST_SET_JITINFO(func: *mut JSFunction, info: *const JSJitInfo); 424 | pub fn RUST_INTERNED_STRING_TO_JSID( 425 | cx: *mut JSContext, 426 | str: *mut JSString, 427 | id: MutableHandleId, 428 | ); 429 | pub fn RUST_js_GetErrorMessage( 430 | userRef: *mut ::libc::c_void, 431 | errorNumber: u32, 432 | ) -> *const JSErrorFormatString; 433 | pub fn IsProxyHandlerFamily(obj: *mut JSObject) -> u8; 434 | pub fn GetProxyHandlerExtra(obj: *mut JSObject) -> *const ::libc::c_void; 435 | pub fn GetProxyHandler(obj: *mut JSObject) -> *const ::libc::c_void; 436 | pub fn ReportError(aCx: *mut JSContext, aError: *const i8); 437 | pub fn IsWrapper(obj: *mut JSObject) -> bool; 438 | pub fn UnwrapObjectStatic(obj: *mut JSObject) -> *mut JSObject; 439 | pub fn UnwrapObjectDynamic( 440 | obj: *mut JSObject, 441 | cx: *mut JSContext, 442 | stopAtOuter: u8, 443 | ) -> *mut JSObject; 444 | pub fn UncheckedUnwrapObject(obj: *mut JSObject, stopAtOuter: u8) -> *mut JSObject; 445 | pub fn CreateRootedIdVector(cx: *mut JSContext) -> *mut PersistentRootedIdVector; 446 | pub fn GetIdVectorAddress(v: *mut PersistentRootedIdVector) -> *mut ::libc::c_void; 447 | pub fn SliceRootedIdVector( 448 | v: *const PersistentRootedIdVector, 449 | length: *mut usize, 450 | ) -> *const jsid; 451 | pub fn AppendToIdVector(v: MutableHandleIdVector, id: HandleId) -> bool; 452 | pub fn DestroyRootedIdVector(v: *mut PersistentRootedIdVector); 453 | pub fn CreateRootedObjectVector(aCx: *mut JSContext) -> *mut PersistentRootedObjectVector; 454 | pub fn AppendToRootedObjectVector( 455 | v: *mut PersistentRootedObjectVector, 456 | obj: *mut JSObject, 457 | ) -> bool; 458 | pub fn GetObjectVectorAddress(v: *mut PersistentRootedObjectVector) -> *mut ::libc::c_void; 459 | pub fn DeleteRootedObjectVector(v: *mut PersistentRootedObjectVector); 460 | pub fn CollectServoSizes( 461 | cx: *mut JSContext, 462 | sizes: *mut ServoSizes, 463 | get_size: Option usize>, 464 | ) -> bool; 465 | pub fn InitializeMemoryReporter( 466 | want_to_measure: Option bool>, 467 | ); 468 | pub fn CallIdTracer(trc: *mut JSTracer, idp: *mut Heap, name: *const ::libc::c_char); 469 | pub fn CallValueTracer( 470 | trc: *mut JSTracer, 471 | valuep: *mut Heap, 472 | name: *const ::libc::c_char, 473 | ); 474 | pub fn CallObjectTracer( 475 | trc: *mut JSTracer, 476 | objp: *mut Heap<*mut JSObject>, 477 | name: *const ::libc::c_char, 478 | ); 479 | pub fn CallStringTracer( 480 | trc: *mut JSTracer, 481 | strp: *mut Heap<*mut JSString>, 482 | name: *const ::libc::c_char, 483 | ); 484 | pub fn CallScriptTracer( 485 | trc: *mut JSTracer, 486 | scriptp: *mut Heap<*mut JSScript>, 487 | name: *const ::libc::c_char, 488 | ); 489 | pub fn CallFunctionTracer( 490 | trc: *mut JSTracer, 491 | funp: *mut Heap<*mut JSFunction>, 492 | name: *const ::libc::c_char, 493 | ); 494 | pub fn CallUnbarrieredObjectTracer( 495 | trc: *mut JSTracer, 496 | objp: *mut *mut JSObject, 497 | name: *const ::libc::c_char, 498 | ); 499 | pub fn CallObjectRootTracer( 500 | trc: *mut JSTracer, 501 | objp: *mut *mut JSObject, 502 | name: *const ::libc::c_char, 503 | ); 504 | pub fn CallValueRootTracer(trc: *mut JSTracer, valp: *mut Value, name: *const ::libc::c_char); 505 | pub fn GetProxyHandlerFamily() -> *const c_void; 506 | 507 | pub fn GetInt8ArrayLengthAndData( 508 | obj: *mut JSObject, 509 | length: *mut usize, 510 | isSharedMemory: *mut bool, 511 | data: *mut *mut i8, 512 | ); 513 | pub fn GetUint8ArrayLengthAndData( 514 | obj: *mut JSObject, 515 | length: *mut usize, 516 | isSharedMemory: *mut bool, 517 | data: *mut *mut u8, 518 | ); 519 | pub fn GetUint8ClampedArrayLengthAndData( 520 | obj: *mut JSObject, 521 | length: *mut usize, 522 | isSharedMemory: *mut bool, 523 | data: *mut *mut u8, 524 | ); 525 | pub fn GetInt16ArrayLengthAndData( 526 | obj: *mut JSObject, 527 | length: *mut usize, 528 | isSharedMemory: *mut bool, 529 | data: *mut *mut i16, 530 | ); 531 | pub fn GetUint16ArrayLengthAndData( 532 | obj: *mut JSObject, 533 | length: *mut usize, 534 | isSharedMemory: *mut bool, 535 | data: *mut *mut u16, 536 | ); 537 | pub fn GetInt32ArrayLengthAndData( 538 | obj: *mut JSObject, 539 | length: *mut usize, 540 | isSharedMemory: *mut bool, 541 | data: *mut *mut i32, 542 | ); 543 | pub fn GetUint32ArrayLengthAndData( 544 | obj: *mut JSObject, 545 | length: *mut usize, 546 | isSharedMemory: *mut bool, 547 | data: *mut *mut u32, 548 | ); 549 | pub fn GetFloat32ArrayLengthAndData( 550 | obj: *mut JSObject, 551 | length: *mut usize, 552 | isSharedMemory: *mut bool, 553 | data: *mut *mut f32, 554 | ); 555 | pub fn GetFloat64ArrayLengthAndData( 556 | obj: *mut JSObject, 557 | length: *mut usize, 558 | isSharedMemory: *mut bool, 559 | data: *mut *mut f64, 560 | ); 561 | 562 | pub fn NewJSAutoStructuredCloneBuffer( 563 | scope: JS::StructuredCloneScope, 564 | callbacks: *const JSStructuredCloneCallbacks, 565 | ) -> *mut JSAutoStructuredCloneBuffer; 566 | pub fn DeleteJSAutoStructuredCloneBuffer(buf: *mut JSAutoStructuredCloneBuffer); 567 | pub fn GetLengthOfJSStructuredCloneData(data: *mut JSStructuredCloneData) -> usize; 568 | pub fn CopyJSStructuredCloneData(src: *const JSStructuredCloneData, dest: *mut u8); 569 | pub fn WriteBytesToJSStructuredCloneData( 570 | src: *const u8, 571 | len: usize, 572 | dest: *mut JSStructuredCloneData, 573 | ); 574 | pub fn JS_ComputeThis(cx: *mut JSContext, vp: *mut JS::Value, dest: *mut JS::Value); 575 | pub fn JS_GetModuleHostDefinedField(module: *mut JSObject, dest: *mut JS::Value); 576 | pub fn JS_GetPromiseResult(promise: JS::HandleObject, dest: JS::MutableHandleValue); 577 | pub fn JS_GetScriptPrivate(script: *mut JSScript, dest: JS::MutableHandleValue); 578 | pub fn JS_GetModulePrivate(module: *mut JSObject, dest: JS::MutableHandleValue); 579 | pub fn JS_THIS(cx: *mut JSContext, vp: *mut JS::Value, dest: *mut JS::Value); 580 | pub fn JS_GetNaNValue(cx: *mut JSContext, dest: *mut JS::Value); 581 | pub fn JS_GetPositiveInfinityValue(cx: *mut JSContext, dest: *mut JS::Value); 582 | pub fn JS_GetEmptyStringValue(cx: *mut JSContext, dest: *mut JS::Value); 583 | pub fn JS_GetReservedSlot(obj: *mut JSObject, index: u32, dest: *mut JS::Value); 584 | pub fn EncodeStringToUTF8(cx: *mut JSContext, str: JS::HandleString, cb: fn(*const c_char)); 585 | pub fn CreateJobQueue(traps: *const JobQueueTraps, queue: *const c_void) -> *mut JS::JobQueue; 586 | pub fn DeleteJobQueue(queue: *mut JS::JobQueue); 587 | pub fn CreateReadableStreamUnderlyingSource( 588 | traps: *const ReadableStreamUnderlyingSourceTraps, 589 | source: *const c_void, 590 | ) -> *mut JS::ReadableStreamUnderlyingSource; 591 | pub fn DeleteReadableStreamUnderlyingSource(source: *mut JS::ReadableStreamUnderlyingSource); 592 | pub fn CreateJSExternalStringCallbacks( 593 | traps: *const JSExternalStringCallbacksTraps, 594 | privateData: *const c_void, 595 | ) -> *mut JSExternalStringCallbacks; 596 | pub fn DeleteJSExternalStringCallbacks(callbacks: *mut JSExternalStringCallbacks); 597 | pub fn DispatchableRun( 598 | cx: *mut JSContext, 599 | ptr: *mut JS::Dispatchable, 600 | mb: JS::Dispatchable_MaybeShuttingDown, 601 | ); 602 | pub fn StreamConsumerConsumeChunk( 603 | sc: *mut JS::StreamConsumer, 604 | begin: *const u8, 605 | length: usize, 606 | ) -> bool; 607 | pub fn StreamConsumerStreamEnd(cx: *mut JS::StreamConsumer); 608 | pub fn StreamConsumerStreamError(cx: *mut JS::StreamConsumer, errorCode: usize); 609 | pub fn StreamConsumerNoteResponseURLs( 610 | sc: *mut JS::StreamConsumer, 611 | maybeUrl: *const c_char, 612 | maybeSourceMapUrl: *const c_char, 613 | ); 614 | pub fn DescribeScriptedCaller( 615 | cx: *mut JSContext, 616 | buffer: *mut u8, 617 | buflen: usize, 618 | line: *mut u32, 619 | col: *mut u32, 620 | ) -> bool; 621 | } 622 | -------------------------------------------------------------------------------- /src/conversions.rs: -------------------------------------------------------------------------------- 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 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | //! Conversions of Rust values to and from `JSVal`. 6 | //! 7 | //! | IDL type | Type | 8 | //! |-------------------------|----------------------------------| 9 | //! | any | `JSVal` | 10 | //! | boolean | `bool` | 11 | //! | byte | `i8` | 12 | //! | octet | `u8` | 13 | //! | short | `i16` | 14 | //! | unsigned short | `u16` | 15 | //! | long | `i32` | 16 | //! | unsigned long | `u32` | 17 | //! | long long | `i64` | 18 | //! | unsigned long long | `u64` | 19 | //! | unrestricted float | `f32` | 20 | //! | float | `Finite` | 21 | //! | unrestricted double | `f64` | 22 | //! | double | `Finite` | 23 | //! | USVString | `String` | 24 | //! | object | `*mut JSObject` | 25 | //! | symbol | `*mut Symbol` | 26 | //! | nullable types | `Option` | 27 | //! | sequences | `Vec` | 28 | 29 | #![deny(missing_docs)] 30 | 31 | use error::throw_type_error; 32 | use glue::RUST_JS_NumberValue; 33 | use jsapi::AssertSameCompartment; 34 | use jsapi::JS; 35 | use jsapi::{ForOfIterator, ForOfIterator_NonIterableBehavior}; 36 | use jsapi::{Heap, JS_DefineElement, JS_GetLatin1StringCharsAndLength}; 37 | use jsapi::{JSContext, JSObject, JSString, RootedObject, RootedValue}; 38 | use jsapi::{JS_DeprecatedStringHasLatin1Chars, JS_NewUCStringCopyN, JSPROP_ENUMERATE}; 39 | use jsapi::{JS_GetTwoByteStringCharsAndLength, NewArrayObject1}; 40 | use jsval::{BooleanValue, Int32Value, NullValue, UInt32Value, UndefinedValue}; 41 | use jsval::{JSVal, ObjectOrNullValue, ObjectValue, StringValue, SymbolValue}; 42 | use libc; 43 | use num_traits::{Bounded, Zero}; 44 | use rust::maybe_wrap_value; 45 | use rust::{maybe_wrap_object_or_null_value, maybe_wrap_object_value, ToString}; 46 | use rust::{HandleValue, MutableHandleValue}; 47 | use rust::{ToBoolean, ToInt32, ToInt64, ToNumber, ToUint16, ToUint32, ToUint64}; 48 | use std::borrow::Cow; 49 | use std::mem; 50 | use std::rc::Rc; 51 | use std::{ptr, slice}; 52 | 53 | trait As: Copy { 54 | fn cast(self) -> O; 55 | } 56 | 57 | macro_rules! impl_as { 58 | ($I:ty, $O:ty) => { 59 | impl As<$O> for $I { 60 | fn cast(self) -> $O { 61 | self as $O 62 | } 63 | } 64 | }; 65 | } 66 | 67 | impl_as!(f64, u8); 68 | impl_as!(f64, u16); 69 | impl_as!(f64, u32); 70 | impl_as!(f64, u64); 71 | impl_as!(f64, i8); 72 | impl_as!(f64, i16); 73 | impl_as!(f64, i32); 74 | impl_as!(f64, i64); 75 | 76 | impl_as!(u8, f64); 77 | impl_as!(u16, f64); 78 | impl_as!(u32, f64); 79 | impl_as!(u64, f64); 80 | impl_as!(i8, f64); 81 | impl_as!(i16, f64); 82 | impl_as!(i32, f64); 83 | impl_as!(i64, f64); 84 | 85 | impl_as!(i32, i8); 86 | impl_as!(i32, u8); 87 | impl_as!(i32, i16); 88 | impl_as!(u16, u16); 89 | impl_as!(i32, i32); 90 | impl_as!(u32, u32); 91 | impl_as!(i64, i64); 92 | impl_as!(u64, u64); 93 | 94 | /// A trait to convert Rust types to `JSVal`s. 95 | pub trait ToJSValConvertible { 96 | /// Convert `self` to a `JSVal`. JSAPI failure causes a panic. 97 | unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue); 98 | } 99 | 100 | /// An enum to better support enums through FromJSValConvertible::from_jsval. 101 | #[derive(PartialEq, Eq, Clone, Debug)] 102 | pub enum ConversionResult { 103 | /// Everything went fine. 104 | Success(T), 105 | /// Conversion failed, without a pending exception. 106 | Failure(Cow<'static, str>), 107 | } 108 | 109 | impl ConversionResult { 110 | /// Returns Some(value) if it is `ConversionResult::Success`. 111 | pub fn get_success_value(&self) -> Option<&T> { 112 | match *self { 113 | ConversionResult::Success(ref v) => Some(v), 114 | _ => None, 115 | } 116 | } 117 | } 118 | 119 | /// A trait to convert `JSVal`s to Rust types. 120 | pub trait FromJSValConvertible: Sized { 121 | /// Optional configurable behaviour switch; use () for no configuration. 122 | type Config; 123 | /// Convert `val` to type `Self`. 124 | /// Optional configuration of type `T` can be passed as the `option` 125 | /// argument. 126 | /// If it returns `Err(())`, a JSAPI exception is pending. 127 | /// If it returns `Ok(Failure(reason))`, there is no pending JSAPI exception. 128 | unsafe fn from_jsval( 129 | cx: *mut JSContext, 130 | val: HandleValue, 131 | option: Self::Config, 132 | ) -> Result, ()>; 133 | } 134 | 135 | /// Behavior for converting out-of-range integers. 136 | #[derive(PartialEq, Eq, Clone)] 137 | pub enum ConversionBehavior { 138 | /// Wrap into the integer's range. 139 | Default, 140 | /// Throw an exception. 141 | EnforceRange, 142 | /// Clamp into the integer's range. 143 | Clamp, 144 | } 145 | 146 | /// Try to cast the number to a smaller type, but 147 | /// if it doesn't fit, it will return an error. 148 | unsafe fn enforce_range(cx: *mut JSContext, d: f64) -> Result, ()> 149 | where 150 | D: Bounded + As, 151 | f64: As, 152 | { 153 | if d.is_infinite() { 154 | throw_type_error(cx, "value out of range in an EnforceRange argument"); 155 | return Err(()); 156 | } 157 | 158 | let rounded = d.round(); 159 | if D::min_value().cast() <= rounded && rounded <= D::max_value().cast() { 160 | Ok(ConversionResult::Success(rounded.cast())) 161 | } else { 162 | throw_type_error(cx, "value out of range in an EnforceRange argument"); 163 | Err(()) 164 | } 165 | } 166 | 167 | /// Try to cast the number to a smaller type, but if it doesn't fit, 168 | /// round it to the MAX or MIN of the source type before casting it to 169 | /// the destination type. 170 | fn clamp_to(d: f64) -> D 171 | where 172 | D: Bounded + As + Zero, 173 | f64: As, 174 | { 175 | if d.is_nan() { 176 | D::zero() 177 | } else if d > D::max_value().cast() { 178 | D::max_value() 179 | } else if d < D::min_value().cast() { 180 | D::min_value() 181 | } else { 182 | d.cast() 183 | } 184 | } 185 | 186 | // https://heycam.github.io/webidl/#es-void 187 | impl ToJSValConvertible for () { 188 | #[inline] 189 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 190 | rval.set(UndefinedValue()); 191 | } 192 | } 193 | 194 | impl FromJSValConvertible for JSVal { 195 | type Config = (); 196 | unsafe fn from_jsval( 197 | _cx: *mut JSContext, 198 | value: HandleValue, 199 | _option: (), 200 | ) -> Result, ()> { 201 | Ok(ConversionResult::Success(value.get())) 202 | } 203 | } 204 | 205 | impl ToJSValConvertible for JSVal { 206 | #[inline] 207 | unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) { 208 | rval.set(*self); 209 | maybe_wrap_value(cx, rval); 210 | } 211 | } 212 | 213 | impl<'a> ToJSValConvertible for HandleValue<'a> { 214 | #[inline] 215 | unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) { 216 | rval.set(self.get()); 217 | maybe_wrap_value(cx, rval); 218 | } 219 | } 220 | 221 | impl ToJSValConvertible for Heap { 222 | #[inline] 223 | unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) { 224 | rval.set(self.get()); 225 | maybe_wrap_value(cx, rval); 226 | } 227 | } 228 | 229 | #[inline] 230 | unsafe fn convert_int_from_jsval( 231 | cx: *mut JSContext, 232 | value: HandleValue, 233 | option: ConversionBehavior, 234 | convert_fn: unsafe fn(*mut JSContext, HandleValue) -> Result, 235 | ) -> Result, ()> 236 | where 237 | T: Bounded + Zero + As, 238 | M: Zero + As, 239 | f64: As, 240 | { 241 | match option { 242 | ConversionBehavior::Default => Ok(ConversionResult::Success(convert_fn(cx, value)?.cast())), 243 | ConversionBehavior::EnforceRange => enforce_range(cx, ToNumber(cx, value)?), 244 | ConversionBehavior::Clamp => Ok(ConversionResult::Success(clamp_to(ToNumber(cx, value)?))), 245 | } 246 | } 247 | 248 | // https://heycam.github.io/webidl/#es-boolean 249 | impl ToJSValConvertible for bool { 250 | #[inline] 251 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 252 | rval.set(BooleanValue(*self)); 253 | } 254 | } 255 | 256 | // https://heycam.github.io/webidl/#es-boolean 257 | impl FromJSValConvertible for bool { 258 | type Config = (); 259 | unsafe fn from_jsval( 260 | _cx: *mut JSContext, 261 | val: HandleValue, 262 | _option: (), 263 | ) -> Result, ()> { 264 | Ok(ToBoolean(val)).map(ConversionResult::Success) 265 | } 266 | } 267 | 268 | // https://heycam.github.io/webidl/#es-byte 269 | impl ToJSValConvertible for i8 { 270 | #[inline] 271 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 272 | rval.set(Int32Value(*self as i32)); 273 | } 274 | } 275 | 276 | // https://heycam.github.io/webidl/#es-byte 277 | impl FromJSValConvertible for i8 { 278 | type Config = ConversionBehavior; 279 | unsafe fn from_jsval( 280 | cx: *mut JSContext, 281 | val: HandleValue, 282 | option: ConversionBehavior, 283 | ) -> Result, ()> { 284 | convert_int_from_jsval(cx, val, option, ToInt32) 285 | } 286 | } 287 | 288 | // https://heycam.github.io/webidl/#es-octet 289 | impl ToJSValConvertible for u8 { 290 | #[inline] 291 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 292 | rval.set(Int32Value(*self as i32)); 293 | } 294 | } 295 | 296 | // https://heycam.github.io/webidl/#es-octet 297 | impl FromJSValConvertible for u8 { 298 | type Config = ConversionBehavior; 299 | unsafe fn from_jsval( 300 | cx: *mut JSContext, 301 | val: HandleValue, 302 | option: ConversionBehavior, 303 | ) -> Result, ()> { 304 | convert_int_from_jsval(cx, val, option, ToInt32) 305 | } 306 | } 307 | 308 | // https://heycam.github.io/webidl/#es-short 309 | impl ToJSValConvertible for i16 { 310 | #[inline] 311 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 312 | rval.set(Int32Value(*self as i32)); 313 | } 314 | } 315 | 316 | // https://heycam.github.io/webidl/#es-short 317 | impl FromJSValConvertible for i16 { 318 | type Config = ConversionBehavior; 319 | unsafe fn from_jsval( 320 | cx: *mut JSContext, 321 | val: HandleValue, 322 | option: ConversionBehavior, 323 | ) -> Result, ()> { 324 | convert_int_from_jsval(cx, val, option, ToInt32) 325 | } 326 | } 327 | 328 | // https://heycam.github.io/webidl/#es-unsigned-short 329 | impl ToJSValConvertible for u16 { 330 | #[inline] 331 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 332 | rval.set(Int32Value(*self as i32)); 333 | } 334 | } 335 | 336 | // https://heycam.github.io/webidl/#es-unsigned-short 337 | impl FromJSValConvertible for u16 { 338 | type Config = ConversionBehavior; 339 | unsafe fn from_jsval( 340 | cx: *mut JSContext, 341 | val: HandleValue, 342 | option: ConversionBehavior, 343 | ) -> Result, ()> { 344 | convert_int_from_jsval(cx, val, option, ToUint16) 345 | } 346 | } 347 | 348 | // https://heycam.github.io/webidl/#es-long 349 | impl ToJSValConvertible for i32 { 350 | #[inline] 351 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 352 | rval.set(Int32Value(*self)); 353 | } 354 | } 355 | 356 | // https://heycam.github.io/webidl/#es-long 357 | impl FromJSValConvertible for i32 { 358 | type Config = ConversionBehavior; 359 | unsafe fn from_jsval( 360 | cx: *mut JSContext, 361 | val: HandleValue, 362 | option: ConversionBehavior, 363 | ) -> Result, ()> { 364 | convert_int_from_jsval(cx, val, option, ToInt32) 365 | } 366 | } 367 | 368 | // https://heycam.github.io/webidl/#es-unsigned-long 369 | impl ToJSValConvertible for u32 { 370 | #[inline] 371 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 372 | rval.set(UInt32Value(*self)); 373 | } 374 | } 375 | 376 | // https://heycam.github.io/webidl/#es-unsigned-long 377 | impl FromJSValConvertible for u32 { 378 | type Config = ConversionBehavior; 379 | unsafe fn from_jsval( 380 | cx: *mut JSContext, 381 | val: HandleValue, 382 | option: ConversionBehavior, 383 | ) -> Result, ()> { 384 | convert_int_from_jsval(cx, val, option, ToUint32) 385 | } 386 | } 387 | 388 | // https://heycam.github.io/webidl/#es-long-long 389 | impl ToJSValConvertible for i64 { 390 | #[inline] 391 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 392 | RUST_JS_NumberValue(*self as f64, &mut *rval); 393 | } 394 | } 395 | 396 | // https://heycam.github.io/webidl/#es-long-long 397 | impl FromJSValConvertible for i64 { 398 | type Config = ConversionBehavior; 399 | unsafe fn from_jsval( 400 | cx: *mut JSContext, 401 | val: HandleValue, 402 | option: ConversionBehavior, 403 | ) -> Result, ()> { 404 | convert_int_from_jsval(cx, val, option, ToInt64) 405 | } 406 | } 407 | 408 | // https://heycam.github.io/webidl/#es-unsigned-long-long 409 | impl ToJSValConvertible for u64 { 410 | #[inline] 411 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 412 | RUST_JS_NumberValue(*self as f64, &mut *rval); 413 | } 414 | } 415 | 416 | // https://heycam.github.io/webidl/#es-unsigned-long-long 417 | impl FromJSValConvertible for u64 { 418 | type Config = ConversionBehavior; 419 | unsafe fn from_jsval( 420 | cx: *mut JSContext, 421 | val: HandleValue, 422 | option: ConversionBehavior, 423 | ) -> Result, ()> { 424 | convert_int_from_jsval(cx, val, option, ToUint64) 425 | } 426 | } 427 | 428 | // https://heycam.github.io/webidl/#es-float 429 | impl ToJSValConvertible for f32 { 430 | #[inline] 431 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 432 | RUST_JS_NumberValue(*self as f64, &mut *rval); 433 | } 434 | } 435 | 436 | // https://heycam.github.io/webidl/#es-float 437 | impl FromJSValConvertible for f32 { 438 | type Config = (); 439 | unsafe fn from_jsval( 440 | cx: *mut JSContext, 441 | val: HandleValue, 442 | _option: (), 443 | ) -> Result, ()> { 444 | let result = ToNumber(cx, val); 445 | result.map(|f| f as f32).map(ConversionResult::Success) 446 | } 447 | } 448 | 449 | // https://heycam.github.io/webidl/#es-double 450 | impl ToJSValConvertible for f64 { 451 | #[inline] 452 | unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) { 453 | RUST_JS_NumberValue(*self, &mut *rval); 454 | } 455 | } 456 | 457 | // https://heycam.github.io/webidl/#es-double 458 | impl FromJSValConvertible for f64 { 459 | type Config = (); 460 | unsafe fn from_jsval( 461 | cx: *mut JSContext, 462 | val: HandleValue, 463 | _option: (), 464 | ) -> Result, ()> { 465 | ToNumber(cx, val).map(ConversionResult::Success) 466 | } 467 | } 468 | 469 | /// Converts a `JSString`, encoded in "Latin1" (i.e. U+0000-U+00FF encoded as 0x00-0xFF) into a 470 | /// `String`. 471 | pub unsafe fn latin1_to_string(cx: *mut JSContext, s: *mut JSString) -> String { 472 | assert!(JS_DeprecatedStringHasLatin1Chars(s)); 473 | 474 | let mut length = 0; 475 | let chars = JS_GetLatin1StringCharsAndLength(cx, ptr::null(), s, &mut length); 476 | assert!(!chars.is_null()); 477 | 478 | let chars = slice::from_raw_parts(chars, length as usize); 479 | let mut s = String::with_capacity(length as usize); 480 | s.extend(chars.iter().map(|&c| c as char)); 481 | s 482 | } 483 | 484 | /// Converts a `JSString` into a `String`, regardless of used encoding. 485 | pub unsafe fn jsstr_to_string(cx: *mut JSContext, jsstr: *mut JSString) -> String { 486 | if JS_DeprecatedStringHasLatin1Chars(jsstr) { 487 | return latin1_to_string(cx, jsstr); 488 | } 489 | 490 | let mut length = 0; 491 | let chars = JS_GetTwoByteStringCharsAndLength(cx, ptr::null(), jsstr, &mut length); 492 | assert!(!chars.is_null()); 493 | let char_vec = slice::from_raw_parts(chars, length as usize); 494 | String::from_utf16_lossy(char_vec) 495 | } 496 | 497 | // https://heycam.github.io/webidl/#es-USVString 498 | impl ToJSValConvertible for str { 499 | #[inline] 500 | unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) { 501 | let mut string_utf16: Vec = Vec::with_capacity(self.len()); 502 | string_utf16.extend(self.encode_utf16()); 503 | let jsstr = JS_NewUCStringCopyN( 504 | cx, 505 | string_utf16.as_ptr(), 506 | string_utf16.len() as libc::size_t, 507 | ); 508 | if jsstr.is_null() { 509 | panic!("JS_NewUCStringCopyN failed"); 510 | } 511 | rval.set(StringValue(&*jsstr)); 512 | } 513 | } 514 | 515 | // https://heycam.github.io/webidl/#es-USVString 516 | impl ToJSValConvertible for String { 517 | #[inline] 518 | unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { 519 | (**self).to_jsval(cx, rval); 520 | } 521 | } 522 | 523 | // https://heycam.github.io/webidl/#es-USVString 524 | impl FromJSValConvertible for String { 525 | type Config = (); 526 | unsafe fn from_jsval( 527 | cx: *mut JSContext, 528 | value: HandleValue, 529 | _: (), 530 | ) -> Result, ()> { 531 | let jsstr = ToString(cx, value); 532 | if jsstr.is_null() { 533 | debug!("ToString failed"); 534 | return Err(()); 535 | } 536 | Ok(jsstr_to_string(cx, jsstr)).map(ConversionResult::Success) 537 | } 538 | } 539 | 540 | impl ToJSValConvertible for Option { 541 | #[inline] 542 | unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) { 543 | match self { 544 | &Some(ref value) => value.to_jsval(cx, rval), 545 | &None => rval.set(NullValue()), 546 | } 547 | } 548 | } 549 | 550 | impl FromJSValConvertible for Option { 551 | type Config = T::Config; 552 | unsafe fn from_jsval( 553 | cx: *mut JSContext, 554 | value: HandleValue, 555 | option: T::Config, 556 | ) -> Result>, ()> { 557 | if value.get().is_null_or_undefined() { 558 | Ok(ConversionResult::Success(None)) 559 | } else { 560 | Ok(match FromJSValConvertible::from_jsval(cx, value, option)? { 561 | ConversionResult::Success(v) => ConversionResult::Success(Some(v)), 562 | ConversionResult::Failure(v) => ConversionResult::Failure(v), 563 | }) 564 | } 565 | } 566 | } 567 | 568 | impl ToJSValConvertible for &'_ T { 569 | #[inline] 570 | unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { 571 | (**self).to_jsval(cx, rval) 572 | } 573 | } 574 | 575 | impl ToJSValConvertible for Box { 576 | #[inline] 577 | unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { 578 | (**self).to_jsval(cx, rval) 579 | } 580 | } 581 | 582 | impl ToJSValConvertible for Rc { 583 | #[inline] 584 | unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { 585 | (**self).to_jsval(cx, rval) 586 | } 587 | } 588 | 589 | // https://heycam.github.io/webidl/#es-sequence 590 | impl ToJSValConvertible for [T] { 591 | #[inline] 592 | unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) { 593 | rooted!(in(cx) let js_array = NewArrayObject1(cx, self.len() as libc::size_t)); 594 | assert!(!js_array.handle().is_null()); 595 | 596 | rooted!(in(cx) let mut val = UndefinedValue()); 597 | for (index, obj) in self.iter().enumerate() { 598 | obj.to_jsval(cx, val.handle_mut()); 599 | 600 | assert!(JS_DefineElement( 601 | cx, 602 | js_array.handle().into(), 603 | index as u32, 604 | val.handle().into(), 605 | JSPROP_ENUMERATE as u32 606 | )); 607 | } 608 | 609 | rval.set(ObjectValue(js_array.handle().get())); 610 | } 611 | } 612 | 613 | // https://heycam.github.io/webidl/#es-sequence 614 | impl ToJSValConvertible for Vec { 615 | #[inline] 616 | unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { 617 | <[_]>::to_jsval(self, cx, rval) 618 | } 619 | } 620 | 621 | /// Rooting guard for the iterator field of ForOfIterator. 622 | /// Behaves like RootedGuard (roots on creation, unroots on drop), 623 | /// but borrows and allows access to the whole ForOfIterator, so 624 | /// that methods on ForOfIterator can still be used through it. 625 | struct ForOfIteratorGuard<'a> { 626 | root: &'a mut ForOfIterator, 627 | } 628 | 629 | impl<'a> ForOfIteratorGuard<'a> { 630 | fn new(cx: *mut JSContext, root: &'a mut ForOfIterator) -> Self { 631 | unsafe { 632 | root.iterator.add_to_root_stack(cx); 633 | } 634 | ForOfIteratorGuard { root: root } 635 | } 636 | } 637 | 638 | impl<'a> Drop for ForOfIteratorGuard<'a> { 639 | fn drop(&mut self) { 640 | unsafe { 641 | self.root.iterator.remove_from_root_stack(); 642 | } 643 | } 644 | } 645 | 646 | impl> FromJSValConvertible for Vec { 647 | type Config = C; 648 | 649 | unsafe fn from_jsval( 650 | cx: *mut JSContext, 651 | value: HandleValue, 652 | option: C, 653 | ) -> Result>, ()> { 654 | if !value.is_object() { 655 | return Ok(ConversionResult::Failure("Value is not an object".into())); 656 | } 657 | 658 | // Depending on the version of LLVM in use, bindgen can end up including 659 | // a padding field in the ForOfIterator. To support multiple versions of 660 | // LLVM that may not have the same fields as a result, we create an empty 661 | // iterator instance and initialize a non-empty instance using the empty 662 | // instance as a base value. 663 | let zero = mem::zeroed(); 664 | let mut iterator = ForOfIterator { 665 | cx_: cx, 666 | iterator: RootedObject::new_unrooted(), 667 | nextMethod: RootedValue::new_unrooted(), 668 | index: ::std::u32::MAX, // NOT_ARRAY 669 | ..zero 670 | }; 671 | let iterator = ForOfIteratorGuard::new(cx, &mut iterator); 672 | let iterator = &mut *iterator.root; 673 | 674 | if !iterator.init( 675 | value.into(), 676 | ForOfIterator_NonIterableBehavior::AllowNonIterable, 677 | ) { 678 | return Err(()); 679 | } 680 | 681 | if iterator.iterator.ptr.is_null() { 682 | return Ok(ConversionResult::Failure("Value is not iterable".into())); 683 | } 684 | 685 | let mut ret = vec![]; 686 | 687 | loop { 688 | let mut done = false; 689 | rooted!(in(cx) let mut val = UndefinedValue()); 690 | if !iterator.next(val.handle_mut().into(), &mut done) { 691 | return Err(()); 692 | } 693 | 694 | if done { 695 | break; 696 | } 697 | 698 | ret.push(match T::from_jsval(cx, val.handle(), option.clone())? { 699 | ConversionResult::Success(v) => v, 700 | ConversionResult::Failure(e) => { 701 | throw_type_error(cx, &e); 702 | return Err(()); 703 | } 704 | }); 705 | } 706 | 707 | Ok(ret).map(ConversionResult::Success) 708 | } 709 | } 710 | 711 | // https://heycam.github.io/webidl/#es-object 712 | impl ToJSValConvertible for *mut JSObject { 713 | #[inline] 714 | unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) { 715 | rval.set(ObjectOrNullValue(*self)); 716 | maybe_wrap_object_or_null_value(cx, rval); 717 | } 718 | } 719 | 720 | // https://heycam.github.io/webidl/#es-object 721 | impl ToJSValConvertible for ptr::NonNull { 722 | #[inline] 723 | unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) { 724 | rval.set(ObjectValue(self.as_ptr())); 725 | maybe_wrap_object_value(cx, rval); 726 | } 727 | } 728 | 729 | // https://heycam.github.io/webidl/#es-object 730 | impl ToJSValConvertible for Heap<*mut JSObject> { 731 | #[inline] 732 | unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) { 733 | rval.set(ObjectOrNullValue(self.get())); 734 | maybe_wrap_object_or_null_value(cx, rval); 735 | } 736 | } 737 | 738 | // https://heycam.github.io/webidl/#es-object 739 | impl FromJSValConvertible for *mut JSObject { 740 | type Config = (); 741 | #[inline] 742 | unsafe fn from_jsval( 743 | cx: *mut JSContext, 744 | value: HandleValue, 745 | _option: (), 746 | ) -> Result, ()> { 747 | if !value.is_object() { 748 | throw_type_error(cx, "value is not an object"); 749 | return Err(()); 750 | } 751 | 752 | AssertSameCompartment(cx, value.to_object()); 753 | 754 | Ok(ConversionResult::Success(value.to_object())) 755 | } 756 | } 757 | 758 | impl ToJSValConvertible for *mut JS::Symbol { 759 | #[inline] 760 | unsafe fn to_jsval(&self, _: *mut JSContext, mut rval: MutableHandleValue) { 761 | rval.set(SymbolValue(&**self)); 762 | } 763 | } 764 | 765 | impl FromJSValConvertible for *mut JS::Symbol { 766 | type Config = (); 767 | #[inline] 768 | unsafe fn from_jsval( 769 | cx: *mut JSContext, 770 | value: HandleValue, 771 | _option: (), 772 | ) -> Result, ()> { 773 | if !value.is_symbol() { 774 | throw_type_error(cx, "value is not a symbol"); 775 | return Err(()); 776 | } 777 | 778 | Ok(ConversionResult::Success(value.to_symbol())) 779 | } 780 | } 781 | -------------------------------------------------------------------------------- /src/jsapi_wrappers.in: -------------------------------------------------------------------------------- 1 | wrap!(jsapi: pub fn IsArgumentsObject(obj: HandleObject) -> bool); 2 | wrap!(jsapi: pub fn EnqueueJob(cx: *mut JSContext, job: HandleObject) -> bool); 3 | wrap!(jsapi: pub fn AssertSameCompartment1(cx: *mut JSContext, v: HandleValue)); 4 | wrap!(jsapi: pub fn GetObjectProto(cx: *mut JSContext, obj: HandleObject, proto: MutableHandleObject) -> bool); 5 | wrap!(jsapi: pub fn GetRealmOriginalEval(cx: *mut JSContext, eval: MutableHandleObject) -> bool); 6 | wrap!(jsapi: pub fn GetPropertyKeys(cx: *mut JSContext, obj: HandleObject, flags: ::std::os::raw::c_uint, props: MutableHandleIdVector) -> bool); 7 | wrap!(jsapi: pub fn AppendUnique(cx: *mut JSContext, base: MutableHandleIdVector, others: HandleIdVector) -> bool); 8 | wrap!(jsapi: pub fn DateIsValid(cx: *mut JSContext, obj: HandleObject, isValid: *mut bool) -> bool); 9 | wrap!(jsapi: pub fn DateGetMsecSinceEpoch(cx: *mut JSContext, obj: HandleObject, msecSinceEpoch: *mut f64) -> bool); 10 | wrap!(jsapi: pub fn PrepareScriptEnvironmentAndInvoke(cx: *mut JSContext, global: HandleObject, closure: *mut ScriptEnvironmentPreparer_Closure)); 11 | wrap!(jsapi: pub fn GetElementsWithAdder(cx: *mut JSContext, obj: HandleObject, receiver: HandleObject, begin: u32, end: u32, adder: *mut ElementAdder) -> bool); 12 | wrap!(jsapi: pub fn SetPropertyIgnoringNamedGetter(cx: *mut JSContext, obj: HandleObject, id: HandleId, v: HandleValue, receiver: HandleValue, ownDesc: Handle, result: *mut ObjectOpResult) -> bool); 13 | wrap!(jsapi: pub fn ExecuteInFrameScriptEnvironment(cx: *mut JSContext, obj: HandleObject, script: HandleScript, scope: MutableHandleObject) -> bool); 14 | wrap!(jsapi: pub fn ReportIsNotFunction(cx: *mut JSContext, v: HandleValue) -> bool); 15 | wrap!(jsapi: pub fn RemapRemoteWindowProxies(cx: *mut JSContext, callback: *mut CompartmentTransplantCallback, newTarget: MutableHandleObject)); 16 | wrap!(jsapi: pub fn ToBooleanSlow(v: HandleValue) -> bool); 17 | wrap!(jsapi: pub fn ToNumberSlow(cx: *mut JSContext, v: HandleValue, dp: *mut f64) -> bool); 18 | wrap!(jsapi: pub fn ToInt8Slow(cx: *mut JSContext, v: HandleValue, out: *mut i8) -> bool); 19 | wrap!(jsapi: pub fn ToUint8Slow(cx: *mut JSContext, v: HandleValue, out: *mut u8) -> bool); 20 | wrap!(jsapi: pub fn ToInt16Slow(cx: *mut JSContext, v: HandleValue, out: *mut i16) -> bool); 21 | wrap!(jsapi: pub fn ToInt32Slow(cx: *mut JSContext, v: HandleValue, out: *mut i32) -> bool); 22 | wrap!(jsapi: pub fn ToUint32Slow(cx: *mut JSContext, v: HandleValue, out: *mut u32) -> bool); 23 | wrap!(jsapi: pub fn ToUint16Slow(cx: *mut JSContext, v: HandleValue, out: *mut u16) -> bool); 24 | wrap!(jsapi: pub fn ToInt64Slow(cx: *mut JSContext, v: HandleValue, out: *mut i64) -> bool); 25 | wrap!(jsapi: pub fn ToUint64Slow(cx: *mut JSContext, v: HandleValue, out: *mut u64) -> bool); 26 | wrap!(jsapi: pub fn ToStringSlow(cx: *mut JSContext, v: HandleValue) -> *mut JSString); 27 | wrap!(jsapi: pub fn ToObjectSlow(cx: *mut JSContext, v: HandleValue, reportScanStack: bool) -> *mut JSObject); 28 | wrap!(jsapi: pub fn NukeNonCCWProxy(cx: *mut JSContext, proxy: HandleObject)); 29 | wrap!(jsapi: pub fn GetFirstSubsumedSavedFrame(cx: *mut JSContext, principals: *mut JSPrincipals, savedFrame: HandleObject, selfHosted: SavedFrameSelfHosted) -> *mut JSObject); 30 | wrap!(jsapi: pub fn SetWindowProxy(cx: *mut JSContext, global: HandleObject, windowProxy: HandleObject)); 31 | wrap!(jsapi: pub fn ComputeThis(cx: *mut JSContext, vp: *mut Value, thisObject: MutableHandleObject) -> bool); 32 | wrap!(jsapi: pub fn GetFunctionRealm(cx: *mut JSContext, objArg: HandleObject) -> *mut Realm); 33 | wrap!(jsapi: pub fn ObjectToCompletePropertyDescriptor(cx: *mut JSContext, obj: HandleObject, descriptor: Handle, desc: MutableHandle) -> bool); 34 | wrap!(jsapi: pub fn FromPropertyDescriptor(cx: *mut JSContext, desc: Handle, vp: MutableHandle) -> bool); 35 | wrap!(jsapi: pub fn NewSymbol(cx: *mut JSContext, description: Handle<*mut JSString>) -> *mut Symbol); 36 | wrap!(jsapi: pub fn GetSymbolFor(cx: *mut JSContext, key: Handle<*mut JSString>) -> *mut Symbol); 37 | wrap!(jsapi: pub fn GetSymbolDescription(symbol: Handle<*mut Symbol>) -> *mut JSString); 38 | wrap!(jsapi: pub fn GetSymbolCode(symbol: Handle<*mut Symbol>) -> SymbolCode); 39 | wrap!(jsapi: pub fn EncodeScript(cx: *mut JSContext, buffer: *mut TranscodeBuffer, script: Handle<*mut JSScript>) -> TranscodeResult); 40 | wrap!(jsapi: pub fn DecodeScript(cx: *mut JSContext, options: *const ReadOnlyCompileOptions, buffer: *mut TranscodeBuffer, scriptp: MutableHandle<*mut JSScript>, cursorIndex: usize) -> TranscodeResult); 41 | wrap!(jsapi: pub fn DecodeScript1(cx: *mut JSContext, options: *const ReadOnlyCompileOptions, range: *const TranscodeRange, scriptp: MutableHandle<*mut JSScript>) -> TranscodeResult); 42 | wrap!(jsapi: pub fn DecodeScriptMaybeStencil(cx: *mut JSContext, options: *const ReadOnlyCompileOptions, buffer: *mut TranscodeBuffer, scriptp: MutableHandle<*mut JSScript>, cursorIndex: usize) -> TranscodeResult); 43 | wrap!(jsapi: pub fn DecodeScriptAndStartIncrementalEncoding(cx: *mut JSContext, options: *const ReadOnlyCompileOptions, buffer: *mut TranscodeBuffer, scriptp: MutableHandle<*mut JSScript>, cursorIndex: usize) -> TranscodeResult); 44 | wrap!(jsapi: pub fn FinishIncrementalEncoding(cx: *mut JSContext, script: Handle<*mut JSScript>, buffer: *mut TranscodeBuffer) -> bool); 45 | wrap!(jsapi: pub fn ProtoKeyToId(cx: *mut JSContext, key: JSProtoKey, idp: MutableHandleId)); 46 | wrap!(jsapi: pub fn ToPrimitive(cx: *mut JSContext, obj: HandleObject, hint: JSType, vp: MutableHandleValue) -> bool); 47 | wrap!(jsapi: pub fn OrdinaryHasInstance(cx: *mut JSContext, objArg: HandleObject, v: HandleValue, bp: *mut bool) -> bool); 48 | wrap!(jsapi: pub fn InstanceofOperator(cx: *mut JSContext, obj: HandleObject, v: HandleValue, bp: *mut bool) -> bool); 49 | wrap!(jsapi: pub fn Call(cx: *mut JSContext, thisv: HandleValue, fun: HandleValue, args: *const HandleValueArray, rval: MutableHandleValue) -> bool); 50 | wrap!(jsapi: pub fn Construct(cx: *mut JSContext, fun: HandleValue, newTarget: HandleObject, args: *const HandleValueArray, objp: MutableHandleObject) -> bool); 51 | wrap!(jsapi: pub fn Construct1(cx: *mut JSContext, fun: HandleValue, args: *const HandleValueArray, objp: MutableHandleObject) -> bool); 52 | wrap!(jsapi: pub fn IsMapObject(cx: *mut JSContext, obj: HandleObject, isMap: *mut bool) -> bool); 53 | wrap!(jsapi: pub fn IsSetObject(cx: *mut JSContext, obj: HandleObject, isSet: *mut bool) -> bool); 54 | wrap!(jsapi: pub fn GetSelfHostedFunction(cx: *mut JSContext, selfHostedName: *const ::std::os::raw::c_char, id: HandleId, nargs: ::std::os::raw::c_uint) -> *mut JSFunction); 55 | wrap!(jsapi: pub fn NewFunctionFromSpec(cx: *mut JSContext, fs: *const JSFunctionSpec, id: HandleId) -> *mut JSFunction); 56 | wrap!(jsapi: pub fn PropertySpecNameEqualsId(name: JSPropertySpec_Name, id: HandleId) -> bool); 57 | wrap!(jsapi: pub fn CreateError(cx: *mut JSContext, type_: JSExnType, stack: HandleObject, fileName: HandleString, lineNumber: u32, columnNumber: u32, report: *mut JSErrorReport, message: HandleString, rval: MutableHandleValue) -> bool); 58 | wrap!(jsapi: pub fn GetWeakMapEntry(cx: *mut JSContext, mapObj: HandleObject, key: HandleObject, val: MutableHandleValue) -> bool); 59 | wrap!(jsapi: pub fn SetWeakMapEntry(cx: *mut JSContext, mapObj: HandleObject, key: HandleObject, val: HandleValue) -> bool); 60 | wrap!(jsapi: pub fn MapSize(cx: *mut JSContext, obj: HandleObject) -> u32); 61 | wrap!(jsapi: pub fn MapGet(cx: *mut JSContext, obj: HandleObject, key: HandleValue, rval: MutableHandleValue) -> bool); 62 | wrap!(jsapi: pub fn MapHas(cx: *mut JSContext, obj: HandleObject, key: HandleValue, rval: *mut bool) -> bool); 63 | wrap!(jsapi: pub fn MapSet(cx: *mut JSContext, obj: HandleObject, key: HandleValue, val: HandleValue) -> bool); 64 | wrap!(jsapi: pub fn MapDelete(cx: *mut JSContext, obj: HandleObject, key: HandleValue, rval: *mut bool) -> bool); 65 | wrap!(jsapi: pub fn MapClear(cx: *mut JSContext, obj: HandleObject) -> bool); 66 | wrap!(jsapi: pub fn MapKeys(cx: *mut JSContext, obj: HandleObject, rval: MutableHandleValue) -> bool); 67 | wrap!(jsapi: pub fn MapValues(cx: *mut JSContext, obj: HandleObject, rval: MutableHandleValue) -> bool); 68 | wrap!(jsapi: pub fn MapEntries(cx: *mut JSContext, obj: HandleObject, rval: MutableHandleValue) -> bool); 69 | wrap!(jsapi: pub fn MapForEach(cx: *mut JSContext, obj: HandleObject, callbackFn: HandleValue, thisVal: HandleValue) -> bool); 70 | wrap!(jsapi: pub fn SetSize(cx: *mut JSContext, obj: HandleObject) -> u32); 71 | wrap!(jsapi: pub fn SetHas(cx: *mut JSContext, obj: HandleObject, key: HandleValue, rval: *mut bool) -> bool); 72 | wrap!(jsapi: pub fn SetDelete(cx: *mut JSContext, obj: HandleObject, key: HandleValue, rval: *mut bool) -> bool); 73 | wrap!(jsapi: pub fn SetAdd(cx: *mut JSContext, obj: HandleObject, key: HandleValue) -> bool); 74 | wrap!(jsapi: pub fn SetClear(cx: *mut JSContext, obj: HandleObject) -> bool); 75 | wrap!(jsapi: pub fn SetKeys(cx: *mut JSContext, obj: HandleObject, rval: MutableHandleValue) -> bool); 76 | wrap!(jsapi: pub fn SetValues(cx: *mut JSContext, obj: HandleObject, rval: MutableHandleValue) -> bool); 77 | wrap!(jsapi: pub fn SetEntries(cx: *mut JSContext, obj: HandleObject, rval: MutableHandleValue) -> bool); 78 | wrap!(jsapi: pub fn SetForEach(cx: *mut JSContext, obj: HandleObject, callbackFn: HandleValue, thisVal: HandleValue) -> bool); 79 | wrap!(jsapi: pub fn ExceptionStackOrNull(obj: HandleObject) -> *mut JSObject); 80 | wrap!(jsapi: pub fn CaptureCurrentStack(cx: *mut JSContext, stackp: MutableHandleObject, capture: *mut StackCapture) -> bool); 81 | wrap!(jsapi: pub fn BuildStackString(cx: *mut JSContext, principals: *mut JSPrincipals, stack: HandleObject, stringp: MutableHandleString, indent: usize, stackFormat: StackFormat) -> bool); 82 | wrap!(jsapi: pub fn GetBuiltinClass(cx: *mut JSContext, obj: HandleObject, cls: *mut ESClass) -> bool); 83 | wrap!(jsapi: pub fn ForceLexicalInitialization(cx: *mut JSContext, obj: HandleObject) -> bool); 84 | wrap!(jsapi: pub fn CopyArrayBuffer(cx: *mut JSContext, maybeArrayBuffer: HandleObject) -> *mut JSObject); 85 | wrap!(jsapi: pub fn DetachArrayBuffer(cx: *mut JSContext, obj: HandleObject) -> bool); 86 | wrap!(jsapi: pub fn StealArrayBufferContents(cx: *mut JSContext, obj: HandleObject) -> *mut ::std::os::raw::c_void); 87 | wrap!(jsapi: pub fn CloneAndExecuteScript(cx: *mut JSContext, script: Handle<*mut JSScript>, rval: MutableHandle) -> bool); 88 | wrap!(jsapi: pub fn CloneAndExecuteScript1(cx: *mut JSContext, envChain: HandleObjectVector, script: Handle<*mut JSScript>, rval: MutableHandle) -> bool); 89 | wrap!(jsapi: pub fn Evaluate(cx: *mut JSContext, options: *const ReadOnlyCompileOptions, srcBuf: *mut SourceText, rval: MutableHandle) -> bool); 90 | wrap!(jsapi: pub fn Evaluate1(cx: *mut JSContext, envChain: HandleObjectVector, options: *const ReadOnlyCompileOptions, srcBuf: *mut SourceText, rval: MutableHandle) -> bool); 91 | wrap!(jsapi: pub fn Evaluate2(cx: *mut JSContext, options: *const ReadOnlyCompileOptions, srcBuf: *mut SourceText, rval: MutableHandle) -> bool); 92 | wrap!(jsapi: pub fn EvaluateUtf8Path(cx: *mut JSContext, options: *const ReadOnlyCompileOptions, filename: *const ::std::os::raw::c_char, rval: MutableHandle) -> bool); 93 | wrap!(jsapi: pub fn CompileFunction(cx: *mut JSContext, envChain: HandleObjectVector, options: *const ReadOnlyCompileOptions, name: *const ::std::os::raw::c_char, nargs: ::std::os::raw::c_uint, argnames: *const *const ::std::os::raw::c_char, srcBuf: *mut SourceText) -> *mut JSFunction); 94 | wrap!(jsapi: pub fn CompileFunction1(cx: *mut JSContext, envChain: HandleObjectVector, options: *const ReadOnlyCompileOptions, name: *const ::std::os::raw::c_char, nargs: ::std::os::raw::c_uint, argnames: *const *const ::std::os::raw::c_char, srcBuf: *mut SourceText) -> *mut JSFunction); 95 | wrap!(jsapi: pub fn CompileFunctionUtf8(cx: *mut JSContext, envChain: HandleObjectVector, options: *const ReadOnlyCompileOptions, name: *const ::std::os::raw::c_char, nargs: ::std::os::raw::c_uint, argnames: *const *const ::std::os::raw::c_char, utf8: *const ::std::os::raw::c_char, length: usize) -> *mut JSFunction); 96 | wrap!(jsapi: pub fn ExposeScriptToDebugger(cx: *mut JSContext, script: Handle<*mut JSScript>)); 97 | wrap!(jsapi: pub fn OrdinaryToPrimitive(cx: *mut JSContext, obj: HandleObject, type_: JSType, vp: MutableHandleValue) -> bool); 98 | wrap!(jsapi: pub fn ObjectIsDate(cx: *mut JSContext, obj: HandleObject, isDate: *mut bool) -> bool); 99 | wrap!(jsapi: pub fn StrictlyEqual(cx: *mut JSContext, v1: Handle, v2: Handle, equal: *mut bool) -> bool); 100 | wrap!(jsapi: pub fn LooselyEqual(cx: *mut JSContext, v1: Handle, v2: Handle, equal: *mut bool) -> bool); 101 | wrap!(jsapi: pub fn SameValue(cx: *mut JSContext, v1: Handle, v2: Handle, same: *mut bool) -> bool); 102 | wrap!(jsapi: pub fn ToJSONMaybeSafely(cx: *mut JSContext, input: HandleObject, callback: JSONWriteCallback, data: *mut ::std::os::raw::c_void) -> bool); 103 | wrap!(jsapi: pub fn AddSizeOfTab(cx: *mut JSContext, obj: HandleObject, mallocSizeOf: MallocSizeOf, opv: *mut ObjectPrivateVisitor, sizes: *mut TabSizes) -> bool); 104 | wrap!(jsapi: pub fn FinishDynamicModuleImport(cx: *mut JSContext, evaluationPromise: HandleObject, referencingPrivate: Handle, specifier: Handle<*mut JSString>, promise: HandleObject) -> bool); 105 | wrap!(jsapi: pub fn FinishDynamicModuleImport_NoTLA(cx: *mut JSContext, status: DynamicImportStatus, referencingPrivate: Handle, specifier: Handle<*mut JSString>, promise: HandleObject) -> bool); 106 | wrap!(jsapi: pub fn ModuleInstantiate(cx: *mut JSContext, moduleRecord: HandleObject) -> bool); 107 | wrap!(jsapi: pub fn ModuleEvaluate(cx: *mut JSContext, moduleRecord: HandleObject, rval: MutableHandleValue) -> bool); 108 | wrap!(jsapi: pub fn ThrowOnModuleEvaluationFailure(cx: *mut JSContext, evaluationPromise: HandleObject) -> bool); 109 | wrap!(jsapi: pub fn GetRequestedModules(cx: *mut JSContext, moduleRecord: HandleObject) -> *mut JSObject); 110 | wrap!(jsapi: pub fn GetRequestedModuleSpecifier(cx: *mut JSContext, requestedModuleObject: Handle) -> *mut JSString); 111 | wrap!(jsapi: pub fn GetRequestedModuleSourcePos(cx: *mut JSContext, requestedModuleObject: Handle, lineNumber: *mut u32, columnNumber: *mut u32)); 112 | wrap!(jsapi: pub fn GetModuleScript(moduleRecord: HandleObject) -> *mut JSScript); 113 | wrap!(jsapi: pub fn NewPromiseObject(cx: *mut JSContext, executor: HandleObject) -> *mut JSObject); 114 | wrap!(jsapi: pub fn IsPromiseObject(obj: HandleObject) -> bool); 115 | wrap!(jsapi: pub fn GetPromiseState(promise: HandleObject) -> PromiseState); 116 | wrap!(jsapi: pub fn GetPromiseID(promise: HandleObject) -> u64); 117 | wrap!(jsapi: pub fn GetPromiseResult(promise: HandleObject) -> Value); 118 | wrap!(jsapi: pub fn GetPromiseIsHandled(promise: HandleObject) -> bool); 119 | wrap!(jsapi: pub fn SetSettledPromiseIsHandled(cx: *mut JSContext, promise: HandleObject)); 120 | wrap!(jsapi: pub fn GetPromiseAllocationSite(promise: HandleObject) -> *mut JSObject); 121 | wrap!(jsapi: pub fn GetPromiseResolutionSite(promise: HandleObject) -> *mut JSObject); 122 | wrap!(jsapi: pub fn CallOriginalPromiseResolve(cx: *mut JSContext, resolutionValue: HandleValue) -> *mut JSObject); 123 | wrap!(jsapi: pub fn CallOriginalPromiseReject(cx: *mut JSContext, rejectionValue: HandleValue) -> *mut JSObject); 124 | wrap!(jsapi: pub fn ResolvePromise(cx: *mut JSContext, promiseObj: HandleObject, resolutionValue: HandleValue) -> bool); 125 | wrap!(jsapi: pub fn RejectPromise(cx: *mut JSContext, promiseObj: HandleObject, rejectionValue: HandleValue) -> bool); 126 | wrap!(jsapi: pub fn CallOriginalPromiseThen(cx: *mut JSContext, promise: HandleObject, onFulfilled: HandleObject, onRejected: HandleObject) -> *mut JSObject); 127 | wrap!(jsapi: pub fn AddPromiseReactions(cx: *mut JSContext, promise: HandleObject, onFulfilled: HandleObject, onRejected: HandleObject) -> bool); 128 | wrap!(jsapi: pub fn AddPromiseReactionsIgnoringUnhandledRejection(cx: *mut JSContext, promise: HandleObject, onFulfilled: HandleObject, onRejected: HandleObject) -> bool); 129 | wrap!(jsapi: pub fn GetPromiseUserInputEventHandlingState(promise: HandleObject) -> PromiseUserInputEventHandlingState); 130 | wrap!(jsapi: pub fn SetPromiseUserInputEventHandlingState(promise: HandleObject, state: PromiseUserInputEventHandlingState) -> bool); 131 | wrap!(jsapi: pub fn GetWaitForAllPromise(cx: *mut JSContext, promises: HandleObjectVector) -> *mut JSObject); 132 | wrap!(jsapi: pub fn NewArrayObject(cx: *mut JSContext, contents: *const HandleValueArray) -> *mut JSObject); 133 | wrap!(jsapi: pub fn IsArrayObject(cx: *mut JSContext, value: Handle, isArray: *mut bool) -> bool); 134 | wrap!(jsapi: pub fn IsArrayObject1(cx: *mut JSContext, obj: HandleObject, isArray: *mut bool) -> bool); 135 | wrap!(jsapi: pub fn GetArrayLength(cx: *mut JSContext, obj: HandleObject, lengthp: *mut u32) -> bool); 136 | wrap!(jsapi: pub fn SetArrayLength(cx: *mut JSContext, obj: HandleObject, length: u32) -> bool); 137 | wrap!(jsapi: pub fn IsArray(cx: *mut JSContext, obj: HandleObject, isArray: *mut bool) -> bool); 138 | wrap!(jsapi: pub fn IsArray1(cx: *mut JSContext, obj: HandleObject, answer: *mut IsArrayAnswer) -> bool); 139 | wrap!(jsapi: pub fn SetRegExpInput(cx: *mut JSContext, obj: HandleObject, input: Handle<*mut JSString>) -> bool); 140 | wrap!(jsapi: pub fn ClearRegExpStatics(cx: *mut JSContext, obj: HandleObject) -> bool); 141 | wrap!(jsapi: pub fn ExecuteRegExp(cx: *mut JSContext, obj: HandleObject, reobj: HandleObject, chars: *mut u16, length: usize, indexp: *mut usize, test: bool, rval: MutableHandle) -> bool); 142 | wrap!(jsapi: pub fn ExecuteRegExpNoStatics(cx: *mut JSContext, reobj: HandleObject, chars: *const u16, length: usize, indexp: *mut usize, test: bool, rval: MutableHandle) -> bool); 143 | wrap!(jsapi: pub fn ObjectIsRegExp(cx: *mut JSContext, obj: HandleObject, isRegExp: *mut bool) -> bool); 144 | wrap!(jsapi: pub fn GetRegExpFlags(cx: *mut JSContext, obj: HandleObject) -> RegExpFlags); 145 | wrap!(jsapi: pub fn GetRegExpSource(cx: *mut JSContext, obj: HandleObject) -> *mut JSString); 146 | wrap!(jsapi: pub fn CheckRegExpSyntax(cx: *mut JSContext, chars: *const u16, length: usize, flags: RegExpFlags, error: MutableHandle) -> bool); 147 | wrap!(jsapi: pub fn GetSavedFrameSource(cx: *mut JSContext, principals: *mut JSPrincipals, savedFrame: HandleObject, sourcep: MutableHandle<*mut JSString>, selfHosted: SavedFrameSelfHosted) -> SavedFrameResult); 148 | wrap!(jsapi: pub fn GetSavedFrameSourceId(cx: *mut JSContext, principals: *mut JSPrincipals, savedFrame: HandleObject, sourceIdp: *mut u32, selfHosted: SavedFrameSelfHosted) -> SavedFrameResult); 149 | wrap!(jsapi: pub fn GetSavedFrameLine(cx: *mut JSContext, principals: *mut JSPrincipals, savedFrame: HandleObject, linep: *mut u32, selfHosted: SavedFrameSelfHosted) -> SavedFrameResult); 150 | wrap!(jsapi: pub fn GetSavedFrameColumn(cx: *mut JSContext, principals: *mut JSPrincipals, savedFrame: HandleObject, columnp: *mut u32, selfHosted: SavedFrameSelfHosted) -> SavedFrameResult); 151 | wrap!(jsapi: pub fn GetSavedFrameFunctionDisplayName(cx: *mut JSContext, principals: *mut JSPrincipals, savedFrame: HandleObject, namep: MutableHandle<*mut JSString>, selfHosted: SavedFrameSelfHosted) -> SavedFrameResult); 152 | wrap!(jsapi: pub fn GetSavedFrameAsyncCause(cx: *mut JSContext, principals: *mut JSPrincipals, savedFrame: HandleObject, asyncCausep: MutableHandle<*mut JSString>, selfHosted: SavedFrameSelfHosted) -> SavedFrameResult); 153 | wrap!(jsapi: pub fn GetSavedFrameAsyncParent(cx: *mut JSContext, principals: *mut JSPrincipals, savedFrame: HandleObject, asyncParentp: MutableHandleObject, selfHosted: SavedFrameSelfHosted) -> SavedFrameResult); 154 | wrap!(jsapi: pub fn GetSavedFrameParent(cx: *mut JSContext, principals: *mut JSPrincipals, savedFrame: HandleObject, parentp: MutableHandleObject, selfHosted: SavedFrameSelfHosted) -> SavedFrameResult); 155 | wrap!(jsapi: pub fn ConvertSavedFrameToPlainObject(cx: *mut JSContext, savedFrame: HandleObject, selfHosted: SavedFrameSelfHosted) -> *mut JSObject); 156 | wrap!(jsapi: pub fn NewReadableDefaultStreamObject(cx: *mut JSContext, underlyingSource: HandleObject, size: HandleFunction, highWaterMark: f64, proto: HandleObject) -> *mut JSObject); 157 | wrap!(jsapi: pub fn NewReadableExternalSourceStreamObject(cx: *mut JSContext, underlyingSource: *mut ReadableStreamUnderlyingSource, nsISupportsObject_alreadyAddreffed: *mut ::std::os::raw::c_void, proto: HandleObject) -> *mut JSObject); 158 | wrap!(jsapi: pub fn ReadableStreamGetExternalUnderlyingSource(cx: *mut JSContext, stream: HandleObject, source: *mut *mut ReadableStreamUnderlyingSource) -> bool); 159 | wrap!(jsapi: pub fn ReadableStreamReleaseExternalUnderlyingSource(cx: *mut JSContext, stream: HandleObject) -> bool); 160 | wrap!(jsapi: pub fn ReadableStreamUpdateDataAvailableFromSource(cx: *mut JSContext, stream: HandleObject, availableData: u32) -> bool); 161 | wrap!(jsapi: pub fn ReadableStreamGetMode(cx: *mut JSContext, stream: HandleObject, mode: *mut ReadableStreamMode) -> bool); 162 | wrap!(jsapi: pub fn ReadableStreamIsReadable(cx: *mut JSContext, stream: HandleObject, result: *mut bool) -> bool); 163 | wrap!(jsapi: pub fn ReadableStreamIsLocked(cx: *mut JSContext, stream: HandleObject, result: *mut bool) -> bool); 164 | wrap!(jsapi: pub fn ReadableStreamIsDisturbed(cx: *mut JSContext, stream: HandleObject, result: *mut bool) -> bool); 165 | wrap!(jsapi: pub fn ReadableStreamCancel(cx: *mut JSContext, stream: HandleObject, reason: HandleValue) -> *mut JSObject); 166 | wrap!(jsapi: pub fn ReadableStreamGetReader(cx: *mut JSContext, stream: HandleObject, mode: ReadableStreamReaderMode) -> *mut JSObject); 167 | wrap!(jsapi: pub fn ReadableStreamTee(cx: *mut JSContext, stream: HandleObject, branch1Stream: MutableHandleObject, branch2Stream: MutableHandleObject) -> bool); 168 | wrap!(jsapi: pub fn ReadableStreamClose(cx: *mut JSContext, stream: HandleObject) -> bool); 169 | wrap!(jsapi: pub fn ReadableStreamReaderIsClosed(cx: *mut JSContext, reader: HandleObject, result: *mut bool) -> bool); 170 | wrap!(jsapi: pub fn ReadableStreamEnqueue(cx: *mut JSContext, stream: HandleObject, chunk: HandleValue) -> bool); 171 | wrap!(jsapi: pub fn ReadableStreamError(cx: *mut JSContext, stream: HandleObject, error: HandleValue) -> bool); 172 | wrap!(jsapi: pub fn ReadableStreamReaderCancel(cx: *mut JSContext, reader: HandleObject, reason: HandleValue) -> bool); 173 | wrap!(jsapi: pub fn ReadableStreamReaderReleaseLock(cx: *mut JSContext, reader: HandleObject) -> bool); 174 | wrap!(jsapi: pub fn ReadableStreamDefaultReaderRead(cx: *mut JSContext, reader: HandleObject) -> *mut JSObject); 175 | wrap!(jsapi: pub fn IsWasmModuleObject(obj: HandleObject) -> bool); 176 | wrap!(jsapi: pub fn GetWasmModule(obj: HandleObject) -> RefPtr); 177 | wrap!(jsapi: pub fn JS_EncodeStringToUTF8(cx: *mut JSContext, str_: Handle<*mut JSString>) -> UniqueChars); 178 | wrap!(jsapi: pub fn JS_ValueToObject(cx: *mut JSContext, v: HandleValue, objp: MutableHandleObject) -> bool); 179 | wrap!(jsapi: pub fn JS_ValueToFunction(cx: *mut JSContext, v: HandleValue) -> *mut JSFunction); 180 | wrap!(jsapi: pub fn JS_ValueToConstructor(cx: *mut JSContext, v: HandleValue) -> *mut JSFunction); 181 | wrap!(jsapi: pub fn JS_ValueToSource(cx: *mut JSContext, v: Handle) -> *mut JSString); 182 | wrap!(jsapi: pub fn JS_TypeOfValue(cx: *mut JSContext, v: Handle) -> JSType); 183 | wrap!(jsapi: pub fn JS_WrapObject(cx: *mut JSContext, objp: MutableHandleObject) -> bool); 184 | wrap!(jsapi: pub fn JS_WrapValue(cx: *mut JSContext, vp: MutableHandleValue) -> bool); 185 | wrap!(jsapi: pub fn JS_TransplantObject(cx: *mut JSContext, origobj: HandleObject, target: HandleObject) -> *mut JSObject); 186 | wrap!(jsapi: pub fn JS_RefreshCrossCompartmentWrappers(cx: *mut JSContext, obj: HandleObject) -> bool); 187 | wrap!(jsapi: pub fn JS_ResolveStandardClass(cx: *mut JSContext, obj: HandleObject, id: HandleId, resolved: *mut bool) -> bool); 188 | wrap!(jsapi: pub fn JS_EnumerateStandardClasses(cx: *mut JSContext, obj: HandleObject) -> bool); 189 | wrap!(jsapi: pub fn JS_NewEnumerateStandardClasses(cx: *mut JSContext, obj: HandleObject, properties: MutableHandleIdVector, enumerableOnly: bool) -> bool); 190 | wrap!(jsapi: pub fn JS_NewEnumerateStandardClassesIncludingResolved(cx: *mut JSContext, obj: HandleObject, properties: MutableHandleIdVector, enumerableOnly: bool) -> bool); 191 | wrap!(jsapi: pub fn JS_GetClassObject(cx: *mut JSContext, key: JSProtoKey, objp: MutableHandleObject) -> bool); 192 | wrap!(jsapi: pub fn JS_GetClassPrototype(cx: *mut JSContext, key: JSProtoKey, objp: MutableHandleObject) -> bool); 193 | wrap!(jsapi: pub fn JS_IdToProtoKey(cx: *mut JSContext, id: HandleId) -> JSProtoKey); 194 | wrap!(jsapi: pub fn JS_InitReflectParse(cx: *mut JSContext, global: HandleObject) -> bool); 195 | wrap!(jsapi: pub fn JS_DefineProfilingFunctions(cx: *mut JSContext, obj: HandleObject) -> bool); 196 | wrap!(jsapi: pub fn JS_DefineDebuggerObject(cx: *mut JSContext, obj: HandleObject) -> bool); 197 | wrap!(jsapi: pub fn JS_ValueToId(cx: *mut JSContext, v: HandleValue, idp: MutableHandleId) -> bool); 198 | wrap!(jsapi: pub fn JS_StringToId(cx: *mut JSContext, s: HandleString, idp: MutableHandleId) -> bool); 199 | wrap!(jsapi: pub fn JS_IdToValue(cx: *mut JSContext, id: jsid, vp: MutableHandle) -> bool); 200 | wrap!(jsapi: pub fn JS_InitClass(cx: *mut JSContext, obj: HandleObject, parent_proto: HandleObject, clasp: *const JSClass, constructor: JSNative, nargs: ::std::os::raw::c_uint, ps: *const JSPropertySpec, fs: *const JSFunctionSpec, static_ps: *const JSPropertySpec, static_fs: *const JSFunctionSpec) -> *mut JSObject); 201 | wrap!(jsapi: pub fn JS_LinkConstructorAndPrototype(cx: *mut JSContext, ctor: HandleObject, proto: HandleObject) -> bool); 202 | wrap!(jsapi: pub fn JS_InstanceOf(cx: *mut JSContext, obj: HandleObject, clasp: *const JSClass, args: *mut CallArgs) -> bool); 203 | wrap!(jsapi: pub fn JS_HasInstance(cx: *mut JSContext, obj: HandleObject, v: Handle, bp: *mut bool) -> bool); 204 | wrap!(jsapi: pub fn JS_GetInstancePrivate(cx: *mut JSContext, obj: HandleObject, clasp: *const JSClass, args: *mut CallArgs) -> *mut ::std::os::raw::c_void); 205 | wrap!(jsapi: pub fn JS_GetConstructor(cx: *mut JSContext, proto: HandleObject) -> *mut JSObject); 206 | wrap!(jsapi: pub fn JS_FireOnNewGlobalObject(cx: *mut JSContext, global: HandleObject)); 207 | wrap!(jsapi: pub fn JS_NewObjectWithGivenProto(cx: *mut JSContext, clasp: *const JSClass, proto: HandleObject) -> *mut JSObject); 208 | wrap!(jsapi: pub fn JS_DeepFreezeObject(cx: *mut JSContext, obj: HandleObject) -> bool); 209 | wrap!(jsapi: pub fn JS_FreezeObject(cx: *mut JSContext, obj: HandleObject) -> bool); 210 | wrap!(jsapi: pub fn JS_GetPrototype(cx: *mut JSContext, obj: HandleObject, result: MutableHandleObject) -> bool); 211 | wrap!(jsapi: pub fn JS_GetPrototypeIfOrdinary(cx: *mut JSContext, obj: HandleObject, isOrdinary: *mut bool, result: MutableHandleObject) -> bool); 212 | wrap!(jsapi: pub fn JS_SetPrototype(cx: *mut JSContext, obj: HandleObject, proto: HandleObject) -> bool); 213 | wrap!(jsapi: pub fn JS_IsExtensible(cx: *mut JSContext, obj: HandleObject, extensible: *mut bool) -> bool); 214 | wrap!(jsapi: pub fn JS_PreventExtensions(cx: *mut JSContext, obj: HandleObject, result: *mut ObjectOpResult) -> bool); 215 | wrap!(jsapi: pub fn JS_SetImmutablePrototype(cx: *mut JSContext, obj: HandleObject, succeeded: *mut bool) -> bool); 216 | wrap!(jsapi: pub fn JS_GetOwnPropertyDescriptorById(cx: *mut JSContext, obj: HandleObject, id: HandleId, desc: MutableHandle) -> bool); 217 | wrap!(jsapi: pub fn JS_GetOwnPropertyDescriptor(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, desc: MutableHandle) -> bool); 218 | wrap!(jsapi: pub fn JS_GetOwnUCPropertyDescriptor(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, desc: MutableHandle) -> bool); 219 | wrap!(jsapi: pub fn JS_GetPropertyDescriptorById(cx: *mut JSContext, obj: HandleObject, id: HandleId, desc: MutableHandle) -> bool); 220 | wrap!(jsapi: pub fn JS_GetPropertyDescriptor(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, desc: MutableHandle) -> bool); 221 | wrap!(jsapi: pub fn JS_GetUCPropertyDescriptor(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, desc: MutableHandle) -> bool); 222 | wrap!(jsapi: pub fn JS_DefinePropertyById(cx: *mut JSContext, obj: HandleObject, id: HandleId, desc: Handle, result: *mut ObjectOpResult) -> bool); 223 | wrap!(jsapi: pub fn JS_DefinePropertyById1(cx: *mut JSContext, obj: HandleObject, id: HandleId, desc: Handle) -> bool); 224 | wrap!(jsapi: pub fn JS_DefinePropertyById2(cx: *mut JSContext, obj: HandleObject, id: HandleId, value: HandleValue, attrs: ::std::os::raw::c_uint) -> bool); 225 | wrap!(jsapi: pub fn JS_DefinePropertyById3(cx: *mut JSContext, obj: HandleObject, id: HandleId, getter: JSNative, setter: JSNative, attrs: ::std::os::raw::c_uint) -> bool); 226 | wrap!(jsapi: pub fn JS_DefinePropertyById4(cx: *mut JSContext, obj: HandleObject, id: HandleId, getter: HandleObject, setter: HandleObject, attrs: ::std::os::raw::c_uint) -> bool); 227 | wrap!(jsapi: pub fn JS_DefinePropertyById5(cx: *mut JSContext, obj: HandleObject, id: HandleId, value: HandleObject, attrs: ::std::os::raw::c_uint) -> bool); 228 | wrap!(jsapi: pub fn JS_DefinePropertyById6(cx: *mut JSContext, obj: HandleObject, id: HandleId, value: HandleString, attrs: ::std::os::raw::c_uint) -> bool); 229 | wrap!(jsapi: pub fn JS_DefinePropertyById7(cx: *mut JSContext, obj: HandleObject, id: HandleId, value: i32, attrs: ::std::os::raw::c_uint) -> bool); 230 | wrap!(jsapi: pub fn JS_DefinePropertyById8(cx: *mut JSContext, obj: HandleObject, id: HandleId, value: u32, attrs: ::std::os::raw::c_uint) -> bool); 231 | wrap!(jsapi: pub fn JS_DefinePropertyById9(cx: *mut JSContext, obj: HandleObject, id: HandleId, value: f64, attrs: ::std::os::raw::c_uint) -> bool); 232 | wrap!(jsapi: pub fn JS_DefineProperty(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, value: HandleValue, attrs: ::std::os::raw::c_uint) -> bool); 233 | wrap!(jsapi: pub fn JS_DefineProperty1(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, getter: JSNative, setter: JSNative, attrs: ::std::os::raw::c_uint) -> bool); 234 | wrap!(jsapi: pub fn JS_DefineProperty2(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, getter: HandleObject, setter: HandleObject, attrs: ::std::os::raw::c_uint) -> bool); 235 | wrap!(jsapi: pub fn JS_DefineProperty3(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, value: HandleObject, attrs: ::std::os::raw::c_uint) -> bool); 236 | wrap!(jsapi: pub fn JS_DefineProperty4(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, value: HandleString, attrs: ::std::os::raw::c_uint) -> bool); 237 | wrap!(jsapi: pub fn JS_DefineProperty5(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, value: i32, attrs: ::std::os::raw::c_uint) -> bool); 238 | wrap!(jsapi: pub fn JS_DefineProperty6(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, value: u32, attrs: ::std::os::raw::c_uint) -> bool); 239 | wrap!(jsapi: pub fn JS_DefineProperty7(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, value: f64, attrs: ::std::os::raw::c_uint) -> bool); 240 | wrap!(jsapi: pub fn JS_DefineUCProperty(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, desc: Handle, result: *mut ObjectOpResult) -> bool); 241 | wrap!(jsapi: pub fn JS_DefineUCProperty1(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, desc: Handle) -> bool); 242 | wrap!(jsapi: pub fn JS_DefineUCProperty2(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, value: HandleValue, attrs: ::std::os::raw::c_uint) -> bool); 243 | wrap!(jsapi: pub fn JS_DefineUCProperty3(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, getter: HandleObject, setter: HandleObject, attrs: ::std::os::raw::c_uint) -> bool); 244 | wrap!(jsapi: pub fn JS_DefineUCProperty4(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, value: HandleObject, attrs: ::std::os::raw::c_uint) -> bool); 245 | wrap!(jsapi: pub fn JS_DefineUCProperty5(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, value: HandleString, attrs: ::std::os::raw::c_uint) -> bool); 246 | wrap!(jsapi: pub fn JS_DefineUCProperty6(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, value: i32, attrs: ::std::os::raw::c_uint) -> bool); 247 | wrap!(jsapi: pub fn JS_DefineUCProperty7(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, value: u32, attrs: ::std::os::raw::c_uint) -> bool); 248 | wrap!(jsapi: pub fn JS_DefineUCProperty8(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, value: f64, attrs: ::std::os::raw::c_uint) -> bool); 249 | wrap!(jsapi: pub fn JS_DefineElement(cx: *mut JSContext, obj: HandleObject, index: u32, value: HandleValue, attrs: ::std::os::raw::c_uint) -> bool); 250 | wrap!(jsapi: pub fn JS_DefineElement1(cx: *mut JSContext, obj: HandleObject, index: u32, getter: HandleObject, setter: HandleObject, attrs: ::std::os::raw::c_uint) -> bool); 251 | wrap!(jsapi: pub fn JS_DefineElement2(cx: *mut JSContext, obj: HandleObject, index: u32, value: HandleObject, attrs: ::std::os::raw::c_uint) -> bool); 252 | wrap!(jsapi: pub fn JS_DefineElement3(cx: *mut JSContext, obj: HandleObject, index: u32, value: HandleString, attrs: ::std::os::raw::c_uint) -> bool); 253 | wrap!(jsapi: pub fn JS_DefineElement4(cx: *mut JSContext, obj: HandleObject, index: u32, value: i32, attrs: ::std::os::raw::c_uint) -> bool); 254 | wrap!(jsapi: pub fn JS_DefineElement5(cx: *mut JSContext, obj: HandleObject, index: u32, value: u32, attrs: ::std::os::raw::c_uint) -> bool); 255 | wrap!(jsapi: pub fn JS_DefineElement6(cx: *mut JSContext, obj: HandleObject, index: u32, value: f64, attrs: ::std::os::raw::c_uint) -> bool); 256 | wrap!(jsapi: pub fn JS_HasPropertyById(cx: *mut JSContext, obj: HandleObject, id: HandleId, foundp: *mut bool) -> bool); 257 | wrap!(jsapi: pub fn JS_HasProperty(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, foundp: *mut bool) -> bool); 258 | wrap!(jsapi: pub fn JS_HasUCProperty(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, vp: *mut bool) -> bool); 259 | wrap!(jsapi: pub fn JS_HasElement(cx: *mut JSContext, obj: HandleObject, index: u32, foundp: *mut bool) -> bool); 260 | wrap!(jsapi: pub fn JS_HasOwnPropertyById(cx: *mut JSContext, obj: HandleObject, id: HandleId, foundp: *mut bool) -> bool); 261 | wrap!(jsapi: pub fn JS_HasOwnProperty(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, foundp: *mut bool) -> bool); 262 | wrap!(jsapi: pub fn JS_ForwardGetPropertyTo(cx: *mut JSContext, obj: HandleObject, id: HandleId, receiver: HandleValue, vp: MutableHandleValue) -> bool); 263 | wrap!(jsapi: pub fn JS_ForwardGetElementTo(cx: *mut JSContext, obj: HandleObject, index: u32, receiver: HandleObject, vp: MutableHandleValue) -> bool); 264 | wrap!(jsapi: pub fn JS_GetPropertyById(cx: *mut JSContext, obj: HandleObject, id: HandleId, vp: MutableHandleValue) -> bool); 265 | wrap!(jsapi: pub fn JS_GetProperty(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, vp: MutableHandleValue) -> bool); 266 | wrap!(jsapi: pub fn JS_GetUCProperty(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, vp: MutableHandleValue) -> bool); 267 | wrap!(jsapi: pub fn JS_GetElement(cx: *mut JSContext, obj: HandleObject, index: u32, vp: MutableHandleValue) -> bool); 268 | wrap!(jsapi: pub fn JS_ForwardSetPropertyTo(cx: *mut JSContext, obj: HandleObject, id: HandleId, v: HandleValue, receiver: HandleValue, result: *mut ObjectOpResult) -> bool); 269 | wrap!(jsapi: pub fn JS_SetPropertyById(cx: *mut JSContext, obj: HandleObject, id: HandleId, v: HandleValue) -> bool); 270 | wrap!(jsapi: pub fn JS_SetProperty(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, v: HandleValue) -> bool); 271 | wrap!(jsapi: pub fn JS_SetUCProperty(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, v: HandleValue) -> bool); 272 | wrap!(jsapi: pub fn JS_SetElement(cx: *mut JSContext, obj: HandleObject, index: u32, v: HandleValue) -> bool); 273 | wrap!(jsapi: pub fn JS_SetElement1(cx: *mut JSContext, obj: HandleObject, index: u32, v: HandleObject) -> bool); 274 | wrap!(jsapi: pub fn JS_SetElement2(cx: *mut JSContext, obj: HandleObject, index: u32, v: HandleString) -> bool); 275 | wrap!(jsapi: pub fn JS_SetElement3(cx: *mut JSContext, obj: HandleObject, index: u32, v: i32) -> bool); 276 | wrap!(jsapi: pub fn JS_SetElement4(cx: *mut JSContext, obj: HandleObject, index: u32, v: u32) -> bool); 277 | wrap!(jsapi: pub fn JS_SetElement5(cx: *mut JSContext, obj: HandleObject, index: u32, v: f64) -> bool); 278 | wrap!(jsapi: pub fn JS_DeletePropertyById(cx: *mut JSContext, obj: HandleObject, id: HandleId, result: *mut ObjectOpResult) -> bool); 279 | wrap!(jsapi: pub fn JS_DeleteProperty(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, result: *mut ObjectOpResult) -> bool); 280 | wrap!(jsapi: pub fn JS_DeleteUCProperty(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, result: *mut ObjectOpResult) -> bool); 281 | wrap!(jsapi: pub fn JS_DeleteElement(cx: *mut JSContext, obj: HandleObject, index: u32, result: *mut ObjectOpResult) -> bool); 282 | wrap!(jsapi: pub fn JS_DeletePropertyById1(cx: *mut JSContext, obj: HandleObject, id: jsid) -> bool); 283 | wrap!(jsapi: pub fn JS_DeleteProperty1(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char) -> bool); 284 | wrap!(jsapi: pub fn JS_DeleteElement1(cx: *mut JSContext, obj: HandleObject, index: u32) -> bool); 285 | wrap!(jsapi: pub fn JS_AssignObject(cx: *mut JSContext, target: HandleObject, src: HandleObject) -> bool); 286 | wrap!(jsapi: pub fn JS_CallFunctionValue(cx: *mut JSContext, obj: HandleObject, fval: HandleValue, args: *const HandleValueArray, rval: MutableHandleValue) -> bool); 287 | wrap!(jsapi: pub fn JS_CallFunction(cx: *mut JSContext, obj: HandleObject, fun: HandleFunction, args: *const HandleValueArray, rval: MutableHandleValue) -> bool); 288 | wrap!(jsapi: pub fn JS_CallFunctionName(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, args: *const HandleValueArray, rval: MutableHandleValue) -> bool); 289 | wrap!(jsapi: pub fn JS_DefineObject(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, clasp: *const JSClass, attrs: ::std::os::raw::c_uint) -> *mut JSObject); 290 | wrap!(jsapi: pub fn JS_DefineProperties(cx: *mut JSContext, obj: HandleObject, ps: *const JSPropertySpec) -> bool); 291 | wrap!(jsapi: pub fn JS_AlreadyHasOwnPropertyById(cx: *mut JSContext, obj: HandleObject, id: HandleId, foundp: *mut bool) -> bool); 292 | wrap!(jsapi: pub fn JS_AlreadyHasOwnProperty(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, foundp: *mut bool) -> bool); 293 | wrap!(jsapi: pub fn JS_AlreadyHasOwnUCProperty(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, foundp: *mut bool) -> bool); 294 | wrap!(jsapi: pub fn JS_AlreadyHasOwnElement(cx: *mut JSContext, obj: HandleObject, index: u32, foundp: *mut bool) -> bool); 295 | wrap!(jsapi: pub fn JS_SetAllNonReservedSlotsToUndefined(obj: HandleObject)); 296 | wrap!(jsapi: pub fn JS_GetFunctionLength(cx: *mut JSContext, fun: HandleFunction, length: *mut u16) -> bool); 297 | wrap!(jsapi: pub fn JS_DefineFunctions(cx: *mut JSContext, obj: HandleObject, fs: *const JSFunctionSpec) -> bool); 298 | wrap!(jsapi: pub fn JS_DefineFunction(cx: *mut JSContext, obj: HandleObject, name: *const ::std::os::raw::c_char, call: JSNative, nargs: ::std::os::raw::c_uint, attrs: ::std::os::raw::c_uint) -> *mut JSFunction); 299 | wrap!(jsapi: pub fn JS_DefineUCFunction(cx: *mut JSContext, obj: HandleObject, name: *const u16, namelen: usize, call: JSNative, nargs: ::std::os::raw::c_uint, attrs: ::std::os::raw::c_uint) -> *mut JSFunction); 300 | wrap!(jsapi: pub fn JS_DefineFunctionById(cx: *mut JSContext, obj: HandleObject, id: Handle, call: JSNative, nargs: ::std::os::raw::c_uint, attrs: ::std::os::raw::c_uint) -> *mut JSFunction); 301 | wrap!(jsapi: pub fn JS_GetFunctionScript(cx: *mut JSContext, fun: HandleFunction) -> *mut JSScript); 302 | wrap!(jsapi: pub fn JS_DecompileScript(cx: *mut JSContext, script: Handle<*mut JSScript>) -> *mut JSString); 303 | wrap!(jsapi: pub fn JS_DecompileFunction(cx: *mut JSContext, fun: Handle<*mut JSFunction>) -> *mut JSString); 304 | wrap!(jsapi: pub fn JS_AtomizeAndPinJSString(cx: *mut JSContext, str_: HandleString) -> *mut JSString); 305 | wrap!(jsapi: pub fn JS_NewDependentString(cx: *mut JSContext, str_: HandleString, start: usize, length: usize) -> *mut JSString); 306 | wrap!(jsapi: pub fn JS_ConcatStrings(cx: *mut JSContext, left: HandleString, right: HandleString) -> *mut JSString); 307 | wrap!(jsapi: pub fn JS_GetPendingException(cx: *mut JSContext, vp: MutableHandleValue) -> bool); 308 | wrap!(jsapi: pub fn JS_SetPendingException(cx: *mut JSContext, v: HandleValue, behavior: ExceptionStackBehavior)); 309 | wrap!(jsapi: pub fn JS_ErrorFromException(cx: *mut JSContext, obj: HandleObject) -> *mut JSErrorReport); 310 | wrap!(jsapi: pub fn JS_IndexToId(cx: *mut JSContext, index: u32, arg1: MutableHandleId) -> bool); 311 | wrap!(jsapi: pub fn JS_CharsToId(cx: *mut JSContext, chars: TwoByteChars, arg1: MutableHandleId) -> bool); 312 | wrap!(jsapi: pub fn JS_IsIdentifier(cx: *mut JSContext, str_: HandleString, isIdentifier: *mut bool) -> bool); 313 | wrap!(jsapi: pub fn JS_FindCompilationScope(cx: *mut JSContext, obj: HandleObject) -> *mut JSObject); 314 | wrap!(jsapi: pub fn JS_NewObjectWithoutMetadata(cx: *mut JSContext, clasp: *const JSClass, proto: HandleObject) -> *mut JSObject); 315 | wrap!(jsapi: pub fn JS_NondeterministicGetWeakMapKeys(cx: *mut JSContext, obj: HandleObject, ret: MutableHandleObject) -> bool); 316 | wrap!(jsapi: pub fn JS_NondeterministicGetWeakSetKeys(cx: *mut JSContext, obj: HandleObject, ret: MutableHandleObject) -> bool); 317 | wrap!(jsapi: pub fn JS_CloneObject(cx: *mut JSContext, obj: HandleObject, proto: HandleObject) -> *mut JSObject); 318 | wrap!(jsapi: pub fn JS_InitializePropertiesFromCompatibleNativeObject(cx: *mut JSContext, dst: HandleObject, src: HandleObject) -> bool); 319 | wrap!(jsapi: pub fn JS_CopyOwnPropertiesAndPrivateFields(cx: *mut JSContext, target: HandleObject, obj: HandleObject) -> bool); 320 | wrap!(jsapi: pub fn JS_WrapPropertyDescriptor(cx: *mut JSContext, desc: MutableHandle) -> bool); 321 | wrap!(jsapi: pub fn JS_DefineFunctionsWithHelp(cx: *mut JSContext, obj: HandleObject, fs: *const JSFunctionSpecWithHelp) -> bool); 322 | wrap!(jsapi: pub fn JS_Utf8BufferIsCompilableUnit(cx: *mut JSContext, obj: HandleObject, utf8: *const ::std::os::raw::c_char, length: usize) -> bool); 323 | wrap!(jsapi: pub fn JS_ExecuteScript(cx: *mut JSContext, script: Handle<*mut JSScript>, rval: MutableHandle) -> bool); 324 | wrap!(jsapi: pub fn JS_ExecuteScript1(cx: *mut JSContext, script: Handle<*mut JSScript>) -> bool); 325 | wrap!(jsapi: pub fn JS_ExecuteScript2(cx: *mut JSContext, envChain: HandleObjectVector, script: Handle<*mut JSScript>, rval: MutableHandle) -> bool); 326 | wrap!(jsapi: pub fn JS_ExecuteScript3(cx: *mut JSContext, envChain: HandleObjectVector, script: Handle<*mut JSScript>) -> bool); 327 | wrap!(jsapi: pub fn JS_Stringify(cx: *mut JSContext, value: MutableHandle, replacer: HandleObject, space: Handle, callback: JSONWriteCallback, data: *mut ::std::os::raw::c_void) -> bool); 328 | wrap!(jsapi: pub fn JS_ParseJSON(cx: *mut JSContext, chars: *const u16, len: u32, vp: MutableHandle) -> bool); 329 | wrap!(jsapi: pub fn JS_ParseJSON1(cx: *mut JSContext, str_: Handle<*mut JSString>, vp: MutableHandle) -> bool); 330 | wrap!(jsapi: pub fn JS_ParseJSONWithReviver(cx: *mut JSContext, chars: *const u16, len: u32, reviver: Handle, vp: MutableHandle) -> bool); 331 | wrap!(jsapi: pub fn JS_ParseJSONWithReviver1(cx: *mut JSContext, str_: Handle<*mut JSString>, reviver: Handle, vp: MutableHandle) -> bool); 332 | wrap!(jsapi: pub fn JS_ReadStructuredClone(cx: *mut JSContext, data: *const JSStructuredCloneData, version: u32, scope: StructuredCloneScope, vp: MutableHandleValue, cloneDataPolicy: *const CloneDataPolicy, optionalCallbacks: *const JSStructuredCloneCallbacks, closure: *mut ::std::os::raw::c_void) -> bool); 333 | wrap!(jsapi: pub fn JS_WriteStructuredClone(cx: *mut JSContext, v: HandleValue, data: *mut JSStructuredCloneData, scope: StructuredCloneScope, cloneDataPolicy: *const CloneDataPolicy, optionalCallbacks: *const JSStructuredCloneCallbacks, closure: *mut ::std::os::raw::c_void, transferable: HandleValue) -> bool); 334 | wrap!(jsapi: pub fn JS_StructuredClone(cx: *mut JSContext, v: HandleValue, vp: MutableHandleValue, optionalCallbacks: *const JSStructuredCloneCallbacks, closure: *mut ::std::os::raw::c_void) -> bool); 335 | wrap!(jsapi: pub fn JS_ReadTypedArray(r: *mut JSStructuredCloneReader, vp: MutableHandleValue) -> bool); 336 | wrap!(jsapi: pub fn JS_WriteString(w: *mut JSStructuredCloneWriter, str_: HandleString) -> bool); 337 | wrap!(jsapi: pub fn JS_WriteTypedArray(w: *mut JSStructuredCloneWriter, v: HandleValue) -> bool); 338 | wrap!(jsapi: pub fn JS_ObjectNotWritten(w: *mut JSStructuredCloneWriter, obj: HandleObject) -> bool); 339 | wrap!(jsapi: pub fn JS_NewInt8ArrayFromArray(cx: *mut JSContext, array: HandleObject) -> *mut JSObject); 340 | wrap!(jsapi: pub fn JS_NewUint8ArrayFromArray(cx: *mut JSContext, array: HandleObject) -> *mut JSObject); 341 | wrap!(jsapi: pub fn JS_NewUint8ClampedArrayFromArray(cx: *mut JSContext, array: HandleObject) -> *mut JSObject); 342 | wrap!(jsapi: pub fn JS_NewInt16ArrayFromArray(cx: *mut JSContext, array: HandleObject) -> *mut JSObject); 343 | wrap!(jsapi: pub fn JS_NewUint16ArrayFromArray(cx: *mut JSContext, array: HandleObject) -> *mut JSObject); 344 | wrap!(jsapi: pub fn JS_NewInt32ArrayFromArray(cx: *mut JSContext, array: HandleObject) -> *mut JSObject); 345 | wrap!(jsapi: pub fn JS_NewUint32ArrayFromArray(cx: *mut JSContext, array: HandleObject) -> *mut JSObject); 346 | wrap!(jsapi: pub fn JS_NewFloat32ArrayFromArray(cx: *mut JSContext, array: HandleObject) -> *mut JSObject); 347 | wrap!(jsapi: pub fn JS_NewFloat64ArrayFromArray(cx: *mut JSContext, array: HandleObject) -> *mut JSObject); 348 | wrap!(jsapi: pub fn JS_NewInt8ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 349 | wrap!(jsapi: pub fn JS_NewUint8ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 350 | wrap!(jsapi: pub fn JS_NewUint8ClampedArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 351 | wrap!(jsapi: pub fn JS_NewInt16ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 352 | wrap!(jsapi: pub fn JS_NewUint16ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 353 | wrap!(jsapi: pub fn JS_NewInt32ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 354 | wrap!(jsapi: pub fn JS_NewUint32ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 355 | wrap!(jsapi: pub fn JS_NewBigInt64ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 356 | wrap!(jsapi: pub fn JS_NewBigUint64ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 357 | wrap!(jsapi: pub fn JS_NewFloat32ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 358 | wrap!(jsapi: pub fn JS_NewFloat64ArrayWithBuffer(cx: *mut JSContext, arrayBuffer: HandleObject, byteOffset: usize, length: i64) -> *mut JSObject); 359 | wrap!(jsapi: pub fn JS_GetArrayBufferViewBuffer(cx: *mut JSContext, obj: HandleObject, isSharedMemory: *mut bool) -> *mut JSObject); 360 | wrap!(jsapi: pub fn JS_NewDataView(cx: *mut JSContext, buffer: HandleObject, byteOffset: usize, byteLength: usize) -> *mut JSObject); 361 | wrap!(jsapi: pub fn JS_ForOfIteratorInit(iterator: *mut ForOfIterator, iterable: HandleValue, nonIterableBehavior: ForOfIterator_NonIterableBehavior) -> bool); 362 | wrap!(jsapi: pub fn JS_ForOfIteratorNext(iterator: *mut ForOfIterator, val: MutableHandleValue, done: *mut bool) -> bool); 363 | --------------------------------------------------------------------------------