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

Add lifetimes for Handle and MutableHandle #393

Merged
merged 16 commits into from
Mar 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "mozjs"
description = "Rust bindings to the Mozilla SpiderMonkey JavaScript engine."
repository = "https://github.com/servo/rust-mozjs"
version = "0.5.0"
version = "0.6.0"
authors = ["The Servo Project Developers"]
build = "build.rs"
license = "MPL-2.0"
Expand Down
57 changes: 29 additions & 28 deletions src/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@
use error::throw_type_error;
use glue::RUST_JS_NumberValue;
use jsapi::AssertSameCompartment;
use jsapi::{ForOfIterator, ForOfIterator_NonIterableBehavior, HandleValue};
use jsapi::{ForOfIterator, ForOfIterator_NonIterableBehavior};
use jsapi::{Heap, JS_DefineElement, JS_GetLatin1StringCharsAndLength};
use jsapi::{JS_GetTwoByteStringCharsAndLength, JS_NewArrayObject1};
use jsapi::{JS_NewUCStringCopyN, JSPROP_ENUMERATE, JS_StringHasLatin1Chars};
use jsapi::{JSContext, JSObject, JSString, MutableHandleValue, RootedObject};
use jsapi::{JSContext, JSObject, JSString, RootedObject};
use jsval::{BooleanValue, Int32Value, NullValue, UInt32Value, UndefinedValue};
use jsval::{JSVal, ObjectValue, ObjectOrNullValue, StringValue};
use rust::{ToBoolean, ToInt32, ToInt64, ToNumber, ToUint16, ToUint32, ToUint64};
use rust::{ToString, maybe_wrap_object_or_null_value, maybe_wrap_object_value};
use rust::{HandleValue, MutableHandleValue};
use rust::maybe_wrap_value;
use libc;
use num_traits::{Bounded, Zero};
Expand Down Expand Up @@ -180,7 +181,7 @@ fn clamp_to<D>(d: f64) -> D
// https://heycam.github.io/webidl/#es-void
impl ToJSValConvertible for () {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should modify the ToJSValConvertible trait to accept a lifetime argument and use it for the rval argument.

rval.set(UndefinedValue());
}
}
Expand All @@ -197,23 +198,23 @@ impl FromJSValConvertible for JSVal {

impl ToJSValConvertible for JSVal {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(*self);
maybe_wrap_value(cx, rval);
}
}

impl ToJSValConvertible for HandleValue {
impl<'a> ToJSValConvertible for HandleValue<'a> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(self.get());
maybe_wrap_value(cx, rval);
}
}

impl ToJSValConvertible for Heap<JSVal> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(self.get());
maybe_wrap_value(cx, rval);
}
Expand All @@ -238,7 +239,7 @@ unsafe fn convert_int_from_jsval<T, M>(cx: *mut JSContext, value: HandleValue,
// https://heycam.github.io/webidl/#es-boolean
impl ToJSValConvertible for bool {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(BooleanValue(*self));
}
}
Expand All @@ -254,7 +255,7 @@ impl FromJSValConvertible for bool {
// https://heycam.github.io/webidl/#es-byte
impl ToJSValConvertible for i8 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
Expand All @@ -273,7 +274,7 @@ impl FromJSValConvertible for i8 {
// https://heycam.github.io/webidl/#es-octet
impl ToJSValConvertible for u8 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
Expand All @@ -292,7 +293,7 @@ impl FromJSValConvertible for u8 {
// https://heycam.github.io/webidl/#es-short
impl ToJSValConvertible for i16 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
Expand All @@ -311,7 +312,7 @@ impl FromJSValConvertible for i16 {
// https://heycam.github.io/webidl/#es-unsigned-short
impl ToJSValConvertible for u16 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
Expand All @@ -330,7 +331,7 @@ impl FromJSValConvertible for u16 {
// https://heycam.github.io/webidl/#es-long
impl ToJSValConvertible for i32 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self));
}
}
Expand All @@ -349,7 +350,7 @@ impl FromJSValConvertible for i32 {
// https://heycam.github.io/webidl/#es-unsigned-long
impl ToJSValConvertible for u32 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(UInt32Value(*self));
}
}
Expand All @@ -368,7 +369,7 @@ impl FromJSValConvertible for u32 {
// https://heycam.github.io/webidl/#es-long-long
impl ToJSValConvertible for i64 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(RUST_JS_NumberValue(*self as f64));
}
}
Expand All @@ -387,7 +388,7 @@ impl FromJSValConvertible for i64 {
// https://heycam.github.io/webidl/#es-unsigned-long-long
impl ToJSValConvertible for u64 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(RUST_JS_NumberValue(*self as f64));
}
}
Expand All @@ -406,7 +407,7 @@ impl FromJSValConvertible for u64 {
// https://heycam.github.io/webidl/#es-float
impl ToJSValConvertible for f32 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(RUST_JS_NumberValue(*self as f64));
}
}
Expand All @@ -423,7 +424,7 @@ impl FromJSValConvertible for f32 {
// https://heycam.github.io/webidl/#es-double
impl ToJSValConvertible for f64 {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(RUST_JS_NumberValue(*self));
}
}
Expand Down Expand Up @@ -467,7 +468,7 @@ pub unsafe fn jsstr_to_string(cx: *mut JSContext, jsstr: *mut JSString) -> Strin
// https://heycam.github.io/webidl/#es-USVString
impl ToJSValConvertible for str {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
let mut string_utf16: Vec<u16> = Vec::with_capacity(self.len());
string_utf16.extend(self.encode_utf16());
let jsstr = JS_NewUCStringCopyN(cx,
Expand Down Expand Up @@ -503,7 +504,7 @@ impl FromJSValConvertible for String {

impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
match self {
&Some(ref value) => value.to_jsval(cx, rval),
&None => rval.set(NullValue()),
Expand Down Expand Up @@ -538,16 +539,16 @@ impl<T: FromJSValConvertible> FromJSValConvertible for Option<T> {
// https://heycam.github.io/webidl/#es-sequence
impl<T: ToJSValConvertible> ToJSValConvertible for [T] {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
rooted!(in(cx) let js_array = JS_NewArrayObject1(cx, self.len() as libc::size_t));
assert!(!js_array.handle().is_null());

rooted!(in(cx) let mut val = UndefinedValue());
for (index, obj) in self.iter().enumerate() {
obj.to_jsval(cx, val.handle_mut());

assert!(JS_DefineElement(cx, js_array.handle(),
index as u32, val.handle(), JSPROP_ENUMERATE, None, None));
assert!(JS_DefineElement(cx, js_array.handle().into(),
index as u32, val.handle().into(), JSPROP_ENUMERATE, None, None));
}

rval.set(ObjectValue(js_array.handle().get()));
Expand Down Expand Up @@ -604,7 +605,7 @@ impl<C: Clone, T: FromJSValConvertible<Config=C>> FromJSValConvertible for Vec<T
let iterator = ForOfIteratorGuard::new(cx, &mut iterator);
let iterator = &mut *iterator.root;

if !iterator.init(value, ForOfIterator_NonIterableBehavior::AllowNonIterable) {
if !iterator.init(value.into(), ForOfIterator_NonIterableBehavior::AllowNonIterable) {
return Err(())
}

Expand All @@ -617,7 +618,7 @@ impl<C: Clone, T: FromJSValConvertible<Config=C>> FromJSValConvertible for Vec<T
loop {
let mut done = false;
rooted!(in(cx) let mut val = UndefinedValue());
if !iterator.next(val.handle_mut(), &mut done) {
if !iterator.next(val.handle_mut().into(), &mut done) {
return Err(())
}

Expand All @@ -638,7 +639,7 @@ impl<C: Clone, T: FromJSValConvertible<Config=C>> FromJSValConvertible for Vec<T
// https://heycam.github.io/webidl/#es-object
impl ToJSValConvertible for *mut JSObject {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(ObjectOrNullValue(*self));
maybe_wrap_object_or_null_value(cx, rval);
}
Expand All @@ -647,7 +648,7 @@ impl ToJSValConvertible for *mut JSObject {
// https://heycam.github.io/webidl/#es-object
impl ToJSValConvertible for ptr::NonNull<JSObject> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(ObjectValue(self.as_ptr()));
maybe_wrap_object_value(cx, rval);
}
Expand All @@ -656,7 +657,7 @@ impl ToJSValConvertible for ptr::NonNull<JSObject> {
// https://heycam.github.io/webidl/#es-object
impl ToJSValConvertible for Heap<*mut JSObject> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(ObjectOrNullValue(self.get()));
maybe_wrap_object_or_null_value(cx, rval);
}
Expand Down
21 changes: 21 additions & 0 deletions src/generate_wrappers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh
# This is one big heuristic but seems to work well enough
grep_heur() {
grep -v "link_name" "$1" | \
grep -v '"\]' | \
grep -F -v '/\*\*' | \
sed -z 's/,\n */, /g' | \
sed -z 's/:\n */: /g' | \
sed -z 's/\n *->/ ->/g' | \
grep -v '^\}$' | \
sed 's/^ *pub/pub/' | \
sed -z 's/\;\n/\n/g' | \
grep 'pub fn' | \
grep Handle | \
grep -v roxyHandler | \
grep -v 'pub fn Unbox' | # this function seems to be platform specific \
sed 's/Handle<\*mut JSObject>/HandleObject/g'
}

grep_heur jsapi_linux_64.rs | sed 's/\(.*\)/wrap!(jsapi: \1);/g' > jsapi_wrappers.in
grep_heur glue.rs | sed 's/\(.*\)/wrap!(glue: \1);/g' > glue_wrappers.in
12 changes: 12 additions & 0 deletions src/glue_wrappers.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
wrap!(glue: pub fn InvokeGetOwnPropertyDescriptor(handler: *const ::libc::c_void, cx: *mut JSContext, proxy: HandleObject, id: HandleId, desc: MutableHandle<PropertyDescriptor>) -> bool);
wrap!(glue: pub fn InvokeHasOwn(handler: *const ::libc::c_void, cx: *mut JSContext, proxy: HandleObject, id: HandleId, bp: *mut bool) -> bool);
wrap!(glue: pub fn CallJitGetterOp(info: *const JSJitInfo, cx: *mut JSContext, thisObj: HandleObject, specializedThis: *mut ::libc::c_void, argc: u32, vp: *mut Value) -> bool);
wrap!(glue: pub fn CallJitSetterOp(info: *const JSJitInfo, cx: *mut JSContext, thisObj: HandleObject, specializedThis: *mut ::libc::c_void, argc: u32, vp: *mut Value) -> bool);
wrap!(glue: pub fn CallJitMethodOp(info: *const JSJitInfo, cx: *mut JSContext, thisObj: HandleObject, specializedThis: *mut ::libc::c_void, argc: u32, vp: *mut Value) -> bool);
wrap!(glue: pub fn NewProxyObject(aCx: *mut JSContext, aHandler: *const ::libc::c_void, aPriv: HandleValue, proto: *mut JSObject, parent: *mut JSObject, call: *mut JSObject, construct: *mut JSObject) -> *mut JSObject);
wrap!(glue: pub fn WrapperNew(aCx: *mut JSContext, aObj: HandleObject, aHandler: *const ::libc::c_void, aClass: *const JSClass, aSingleton: bool) -> *mut JSObject);
wrap!(glue: pub fn NewWindowProxy(aCx: *mut JSContext, aObj: HandleObject, aHandler: *const ::libc::c_void) -> *mut JSObject);
wrap!(glue: pub fn RUST_JSID_IS_INT(id: HandleId) -> bool);
wrap!(glue: pub fn RUST_JSID_TO_INT(id: HandleId) -> i32);
wrap!(glue: pub fn RUST_JSID_IS_STRING(id: HandleId) -> bool);
wrap!(glue: pub fn RUST_JSID_TO_STRING(id: HandleId) -> *mut JSString);
Loading