Skip to content

Commit cafdb83

Browse files
Ms2gerjdm
authored andcommitted
Add more APIs to work with AutoIdVector.
1 parent f1eb435 commit cafdb83

File tree

6 files changed

+117
-0
lines changed

6 files changed

+117
-0
lines changed

mozjs/js/rust/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ glob = "0.2.11"
1313
[[test]]
1414
name = "callback"
1515
[[test]]
16+
name = "enumerate"
17+
[[test]]
1618
name = "evaluate"
1719
[[test]]
1820
name = "stack_limit"

mozjs/js/rust/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ const WHITELIST_VARS: &'static [&'static str] = &[
191191
const WHITELIST_FUNCTIONS: &'static [&'static str] = &[
192192
"JS::ContextOptionsRef",
193193
"JS::Evaluate",
194+
"js::GetPropertyKeys",
194195
"JS::HeapObjectPostBarrier",
195196
"JS::HeapValuePostBarrier",
196197
"JS::InitSelfHostedCode",
@@ -219,6 +220,7 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[
219220
"JS_ReportErrorNumberUTF8",
220221
"JS_SetGCParameter",
221222
"JS_SetNativeStackQuota",
223+
"JS_StringEqualsAscii",
222224
"JS_StringHasLatin1Chars",
223225
"JS_WrapValue",
224226
"JS::SetWarningReporter",

mozjs/js/rust/src/glue.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,10 @@ extern "C" {
240240
pub fn IsWrapper(obj: *mut JSObject) -> bool;
241241
pub fn UnwrapObject(obj: *mut JSObject, stopAtOuter: u8) -> *mut JSObject;
242242
pub fn UncheckedUnwrapObject(obj: *mut JSObject, stopAtOuter: u8) -> *mut JSObject;
243+
pub fn CreateAutoIdVector(cx: *mut JSContext) -> *mut JS::AutoIdVector;
243244
pub fn AppendToAutoIdVector(v: *mut JS::AutoIdVector, id: jsid) -> bool;
245+
pub fn SliceAutoIdVector(v: *const JS::AutoIdVector, length: *mut usize) -> *const jsid;
246+
pub fn DestroyAutoIdVector(v: *mut JS::AutoIdVector);
244247
pub fn CreateAutoObjectVector(aCx: *mut JSContext)
245248
-> *mut JS::AutoObjectVector;
246249
pub fn AppendToAutoObjectVector(v: *mut JS::AutoObjectVector,

mozjs/js/rust/src/jsglue.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,12 +660,31 @@ UncheckedUnwrapObject(JSObject* obj, bool stopAtOuter)
660660
return js::UncheckedUnwrap(obj, stopAtOuter);
661661
}
662662

663+
JS::AutoIdVector*
664+
CreateAutoIdVector(JSContext* cx)
665+
{
666+
return new JS::AutoIdVector(cx);
667+
}
668+
663669
bool
664670
AppendToAutoIdVector(JS::AutoIdVector* v, jsid id)
665671
{
666672
return v->append(id);
667673
}
668674

675+
const jsid*
676+
SliceAutoIdVector(const JS::AutoIdVector* v, size_t* length)
677+
{
678+
*length = v->length();
679+
return v->begin();
680+
}
681+
682+
void
683+
DestroyAutoIdVector(JS::AutoIdVector* v)
684+
{
685+
delete v;
686+
}
687+
669688
JS::AutoObjectVector*
670689
CreateAutoObjectVector(JSContext* aCx)
671690
{

mozjs/js/rust/src/rust.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use std::thread;
1919
use jsapi::root::*;
2020
use jsval;
2121
use glue::{CreateAutoObjectVector, CreateCallArgsFromVp, AppendToAutoObjectVector, DeleteAutoObjectVector, IsDebugBuild};
22+
use glue::{CreateAutoIdVector, SliceAutoIdVector, DestroyAutoIdVector};
2223
use glue::{NewCompileOptions, DeleteCompileOptions};
2324

2425
const DEFAULT_HEAPSIZE: u32 = 32_u32 * 1024_u32 * 1024_u32;
@@ -839,6 +840,40 @@ impl JSNativeWrapper {
839840
}
840841
}
841842

843+
pub struct IdVector(*mut JS::AutoIdVector);
844+
845+
impl IdVector {
846+
pub unsafe fn new(cx: *mut JSContext) -> IdVector {
847+
let vector = CreateAutoIdVector(cx);
848+
assert!(!vector.is_null());
849+
IdVector(vector)
850+
}
851+
852+
pub fn get(&self) -> *mut JS::AutoIdVector {
853+
self.0
854+
}
855+
}
856+
857+
impl Drop for IdVector {
858+
fn drop(&mut self) {
859+
unsafe {
860+
DestroyAutoIdVector(self.0)
861+
}
862+
}
863+
}
864+
865+
impl Deref for IdVector {
866+
type Target = [jsid];
867+
868+
fn deref(&self) -> &[jsid] {
869+
unsafe {
870+
let mut length = 0;
871+
let pointer = SliceAutoIdVector(self.0 as *const _, &mut length);
872+
slice::from_raw_parts(pointer, length)
873+
}
874+
}
875+
}
876+
842877
/// Defines methods on `obj`. The last entry of `methods` must contain zeroed
843878
/// memory.
844879
///

tests/enumerate.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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 js;
7+
8+
use js::glue::RUST_JSID_IS_STRING;
9+
use js::glue::RUST_JSID_TO_STRING;
10+
use js::jsapi::CompartmentOptions;
11+
use js::jsapi::GetPropertyKeys;
12+
use js::jsapi::JSITER_OWNONLY;
13+
use js::jsapi::JS_NewGlobalObject;
14+
use js::jsapi::JS_StringEqualsAscii;
15+
use js::jsapi::OnNewGlobalHookOption;
16+
use js::jsval::UndefinedValue;
17+
use js::rust::IdVector;
18+
use js::rust::Runtime;
19+
use js::rust::SIMPLE_GLOBAL_CLASS;
20+
use std::ptr;
21+
22+
#[test]
23+
fn enumerate() {
24+
let rt = Runtime::new();
25+
let cx = rt.cx();
26+
27+
unsafe {
28+
rooted!(in(cx) let global =
29+
JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
30+
OnNewGlobalHookOption::FireOnNewGlobalHook,
31+
&CompartmentOptions::default())
32+
);
33+
34+
rooted!(in(cx) let mut rval = UndefinedValue());
35+
assert!(rt.evaluate_script(global.handle(), "({ 'a': 7 })",
36+
"test", 1, rval.handle_mut()).is_ok());
37+
assert!(rval.is_object());
38+
39+
rooted!(in(cx) let object = rval.to_object());
40+
let ids = IdVector::new(cx);
41+
assert!(GetPropertyKeys(cx, object.handle(), JSITER_OWNONLY, ids.get()));
42+
43+
assert_eq!(ids.len(), 1);
44+
rooted!(in(cx) let id = ids[0]);
45+
46+
assert!(RUST_JSID_IS_STRING(id.handle()));
47+
rooted!(in(cx) let id = RUST_JSID_TO_STRING(id.handle()));
48+
49+
let mut matches = false;
50+
assert!(JS_StringEqualsAscii(cx,
51+
id.get(),
52+
b"a\0" as *const _ as *const _,
53+
&mut matches));
54+
assert!(matches);
55+
}
56+
}

0 commit comments

Comments
 (0)