Skip to content

Commit

Permalink
Add more APIs to work with AutoIdVector.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ms2ger authored and jdm committed Dec 18, 2017
1 parent f1eb435 commit cafdb83
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 0 deletions.
2 changes: 2 additions & 0 deletions mozjs/js/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ glob = "0.2.11"
[[test]]
name = "callback"
[[test]]
name = "enumerate"
[[test]]
name = "evaluate"
[[test]]
name = "stack_limit"
Expand Down
2 changes: 2 additions & 0 deletions mozjs/js/rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ const WHITELIST_VARS: &'static [&'static str] = &[
const WHITELIST_FUNCTIONS: &'static [&'static str] = &[
"JS::ContextOptionsRef",
"JS::Evaluate",
"js::GetPropertyKeys",
"JS::HeapObjectPostBarrier",
"JS::HeapValuePostBarrier",
"JS::InitSelfHostedCode",
Expand Down Expand Up @@ -219,6 +220,7 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[
"JS_ReportErrorNumberUTF8",
"JS_SetGCParameter",
"JS_SetNativeStackQuota",
"JS_StringEqualsAscii",
"JS_StringHasLatin1Chars",
"JS_WrapValue",
"JS::SetWarningReporter",
Expand Down
3 changes: 3 additions & 0 deletions mozjs/js/rust/src/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,10 @@ extern "C" {
pub fn IsWrapper(obj: *mut JSObject) -> bool;
pub fn UnwrapObject(obj: *mut JSObject, stopAtOuter: u8) -> *mut JSObject;
pub fn UncheckedUnwrapObject(obj: *mut JSObject, stopAtOuter: u8) -> *mut JSObject;
pub fn CreateAutoIdVector(cx: *mut JSContext) -> *mut JS::AutoIdVector;
pub fn AppendToAutoIdVector(v: *mut JS::AutoIdVector, id: jsid) -> bool;
pub fn SliceAutoIdVector(v: *const JS::AutoIdVector, length: *mut usize) -> *const jsid;
pub fn DestroyAutoIdVector(v: *mut JS::AutoIdVector);
pub fn CreateAutoObjectVector(aCx: *mut JSContext)
-> *mut JS::AutoObjectVector;
pub fn AppendToAutoObjectVector(v: *mut JS::AutoObjectVector,
Expand Down
19 changes: 19 additions & 0 deletions mozjs/js/rust/src/jsglue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,12 +660,31 @@ UncheckedUnwrapObject(JSObject* obj, bool stopAtOuter)
return js::UncheckedUnwrap(obj, stopAtOuter);
}

JS::AutoIdVector*
CreateAutoIdVector(JSContext* cx)
{
return new JS::AutoIdVector(cx);
}

bool
AppendToAutoIdVector(JS::AutoIdVector* v, jsid id)
{
return v->append(id);
}

const jsid*
SliceAutoIdVector(const JS::AutoIdVector* v, size_t* length)
{
*length = v->length();
return v->begin();
}

void
DestroyAutoIdVector(JS::AutoIdVector* v)
{
delete v;
}

JS::AutoObjectVector*
CreateAutoObjectVector(JSContext* aCx)
{
Expand Down
35 changes: 35 additions & 0 deletions mozjs/js/rust/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use std::thread;
use jsapi::root::*;
use jsval;
use glue::{CreateAutoObjectVector, CreateCallArgsFromVp, AppendToAutoObjectVector, DeleteAutoObjectVector, IsDebugBuild};
use glue::{CreateAutoIdVector, SliceAutoIdVector, DestroyAutoIdVector};
use glue::{NewCompileOptions, DeleteCompileOptions};

const DEFAULT_HEAPSIZE: u32 = 32_u32 * 1024_u32 * 1024_u32;
Expand Down Expand Up @@ -839,6 +840,40 @@ impl JSNativeWrapper {
}
}

pub struct IdVector(*mut JS::AutoIdVector);

impl IdVector {
pub unsafe fn new(cx: *mut JSContext) -> IdVector {
let vector = CreateAutoIdVector(cx);
assert!(!vector.is_null());
IdVector(vector)
}

pub fn get(&self) -> *mut JS::AutoIdVector {
self.0
}
}

impl Drop for IdVector {
fn drop(&mut self) {
unsafe {
DestroyAutoIdVector(self.0)
}
}
}

impl Deref for IdVector {
type Target = [jsid];

fn deref(&self) -> &[jsid] {
unsafe {
let mut length = 0;
let pointer = SliceAutoIdVector(self.0 as *const _, &mut length);
slice::from_raw_parts(pointer, length)
}
}
}

/// Defines methods on `obj`. The last entry of `methods` must contain zeroed
/// memory.
///
Expand Down
56 changes: 56 additions & 0 deletions tests/enumerate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#[macro_use]
extern crate js;

use js::glue::RUST_JSID_IS_STRING;
use js::glue::RUST_JSID_TO_STRING;
use js::jsapi::CompartmentOptions;
use js::jsapi::GetPropertyKeys;
use js::jsapi::JSITER_OWNONLY;
use js::jsapi::JS_NewGlobalObject;
use js::jsapi::JS_StringEqualsAscii;
use js::jsapi::OnNewGlobalHookOption;
use js::jsval::UndefinedValue;
use js::rust::IdVector;
use js::rust::Runtime;
use js::rust::SIMPLE_GLOBAL_CLASS;
use std::ptr;

#[test]
fn enumerate() {
let rt = Runtime::new();
let cx = rt.cx();

unsafe {
rooted!(in(cx) let global =
JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
OnNewGlobalHookOption::FireOnNewGlobalHook,
&CompartmentOptions::default())
);

rooted!(in(cx) let mut rval = UndefinedValue());
assert!(rt.evaluate_script(global.handle(), "({ 'a': 7 })",
"test", 1, rval.handle_mut()).is_ok());
assert!(rval.is_object());

rooted!(in(cx) let object = rval.to_object());
let ids = IdVector::new(cx);
assert!(GetPropertyKeys(cx, object.handle(), JSITER_OWNONLY, ids.get()));

assert_eq!(ids.len(), 1);
rooted!(in(cx) let id = ids[0]);

assert!(RUST_JSID_IS_STRING(id.handle()));
rooted!(in(cx) let id = RUST_JSID_TO_STRING(id.handle()));

let mut matches = false;
assert!(JS_StringEqualsAscii(cx,
id.get(),
b"a\0" as *const _ as *const _,
&mut matches));
assert!(matches);
}
}

0 comments on commit cafdb83

Please sign in to comment.