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

Commit

Permalink
Add more APIs to work with AutoIdVector.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ms2ger committed Sep 15, 2016
1 parent 4d4466f commit df3e626
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ cmake = "0.1"
[[test]]
name = "callback"
[[test]]
name = "enumerate"
[[test]]
name = "evaluate"
[[test]]
name = "stack_limit"
Expand Down
3 changes: 3 additions & 0 deletions 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 AutoIdVector;
pub fn AppendToAutoIdVector(v: *mut AutoIdVector, id: jsid) -> bool;
pub fn SliceAutoIdVector(v: *const AutoIdVector, length: *mut usize) -> *const jsid;
pub fn DestroyAutoIdVector(v: *mut AutoIdVector);
pub fn CreateAutoObjectVector(aCx: *mut JSContext)
-> *mut AutoObjectVector;
pub fn AppendToAutoObjectVector(v: *mut AutoObjectVector,
Expand Down
19 changes: 19 additions & 0 deletions src/jsglue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,12 +680,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
36 changes: 36 additions & 0 deletions src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ use jsval::UndefinedValue;
use jsapi::JSCLASS_RESERVED_SLOTS_SHIFT;
use jsapi::JSClassOps;
use jsapi::InitSelfHostedCode;
use jsapi::AutoIdVector;
use glue::{CreateAutoIdVector, SliceAutoIdVector, DestroyAutoIdVector};
use glue::{CreateAutoObjectVector, CreateCallArgsFromVp, AppendToAutoObjectVector, DeleteAutoObjectVector};
use glue::{NewCompileOptions, DeleteCompileOptions};
use default_heapsize;
Expand Down Expand Up @@ -882,6 +884,40 @@ impl JSNativeWrapper {
}
}

pub struct IdVector(*mut 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 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 df3e626

Please sign in to comment.