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

Commit 223b907

Browse files
author
bors-servo
authored
Auto merge of #305 - servo:autoidvector, r=nox
Add more APIs to work with AutoIdVector. <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-mozjs/305) <!-- Reviewable:end -->
2 parents 4d4466f + df3e626 commit 223b907

File tree

5 files changed

+116
-0
lines changed

5 files changed

+116
-0
lines changed

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ cmake = "0.1"
1111
[[test]]
1212
name = "callback"
1313
[[test]]
14+
name = "enumerate"
15+
[[test]]
1416
name = "evaluate"
1517
[[test]]
1618
name = "stack_limit"

src/glue.rs

+3
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 AutoIdVector;
243244
pub fn AppendToAutoIdVector(v: *mut AutoIdVector, id: jsid) -> bool;
245+
pub fn SliceAutoIdVector(v: *const AutoIdVector, length: *mut usize) -> *const jsid;
246+
pub fn DestroyAutoIdVector(v: *mut AutoIdVector);
244247
pub fn CreateAutoObjectVector(aCx: *mut JSContext)
245248
-> *mut AutoObjectVector;
246249
pub fn AppendToAutoObjectVector(v: *mut AutoObjectVector,

src/jsglue.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -680,12 +680,31 @@ UncheckedUnwrapObject(JSObject* obj, bool stopAtOuter)
680680
return js::UncheckedUnwrap(obj, stopAtOuter);
681681
}
682682

683+
JS::AutoIdVector*
684+
CreateAutoIdVector(JSContext* cx)
685+
{
686+
return new JS::AutoIdVector(cx);
687+
}
688+
683689
bool
684690
AppendToAutoIdVector(JS::AutoIdVector* v, jsid id)
685691
{
686692
return v->append(id);
687693
}
688694

695+
const jsid*
696+
SliceAutoIdVector(const JS::AutoIdVector* v, size_t* length)
697+
{
698+
*length = v->length();
699+
return v->begin();
700+
}
701+
702+
void
703+
DestroyAutoIdVector(JS::AutoIdVector* v)
704+
{
705+
delete v;
706+
}
707+
689708
JS::AutoObjectVector*
690709
CreateAutoObjectVector(JSContext* aCx)
691710
{

src/rust.rs

+36
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ use jsval::UndefinedValue;
4747
use jsapi::JSCLASS_RESERVED_SLOTS_SHIFT;
4848
use jsapi::JSClassOps;
4949
use jsapi::InitSelfHostedCode;
50+
use jsapi::AutoIdVector;
51+
use glue::{CreateAutoIdVector, SliceAutoIdVector, DestroyAutoIdVector};
5052
use glue::{CreateAutoObjectVector, CreateCallArgsFromVp, AppendToAutoObjectVector, DeleteAutoObjectVector};
5153
use glue::{NewCompileOptions, DeleteCompileOptions};
5254
use default_heapsize;
@@ -882,6 +884,40 @@ impl JSNativeWrapper {
882884
}
883885
}
884886

887+
pub struct IdVector(*mut AutoIdVector);
888+
889+
impl IdVector {
890+
pub unsafe fn new(cx: *mut JSContext) -> IdVector {
891+
let vector = CreateAutoIdVector(cx);
892+
assert!(!vector.is_null());
893+
IdVector(vector)
894+
}
895+
896+
pub fn get(&self) -> *mut AutoIdVector {
897+
self.0
898+
}
899+
}
900+
901+
impl Drop for IdVector {
902+
fn drop(&mut self) {
903+
unsafe {
904+
DestroyAutoIdVector(self.0)
905+
}
906+
}
907+
}
908+
909+
impl Deref for IdVector {
910+
type Target = [jsid];
911+
912+
fn deref(&self) -> &[jsid] {
913+
unsafe {
914+
let mut length = 0;
915+
let pointer = SliceAutoIdVector(self.0 as *const _, &mut length);
916+
slice::from_raw_parts(pointer, length)
917+
}
918+
}
919+
}
920+
885921
/// Defines methods on `obj`. The last entry of `methods` must contain zeroed
886922
/// memory.
887923
///

tests/enumerate.rs

+56
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)