Skip to content
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 mozjs/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.workspace = true
version = "0.20.1"
version = "0.21.0"
authors = ["The Servo Project Developers"]
license.workspace = true
edition.workspace = true
Expand Down
109 changes: 53 additions & 56 deletions mozjs/src/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@
#![deny(missing_docs)]

use crate::error::throw_type_error;
use crate::jsapi::NewArrayObject1;
use crate::jsapi::Heap;
use crate::jsapi::JS;
use crate::jsapi::{Heap, JS_DefineElement};
use crate::jsapi::{JSContext, JSObject, JSString};
use crate::jsapi::{JS_DeprecatedStringHasLatin1Chars, JS_NewStringCopyUTF8N, JSPROP_ENUMERATE};
use crate::jsapi::{JS_DeprecatedStringHasLatin1Chars, JSPROP_ENUMERATE};
use crate::jsval::{BooleanValue, DoubleValue, Int32Value, NullValue, UInt32Value, UndefinedValue};
use crate::jsval::{JSVal, ObjectOrNullValue, ObjectValue, StringValue, SymbolValue};
use crate::rooted;
use crate::rust::for_of;
use crate::rust::maybe_wrap_value;
use crate::rust::wrappers2::{
AssertSameCompartment, JS_GetLatin1StringCharsAndLength, JS_GetTwoByteStringCharsAndLength,
AssertSameCompartment, JS_DefineElement, JS_GetLatin1StringCharsAndLength,
JS_GetTwoByteStringCharsAndLength, JS_NewStringCopyUTF8N, NewArrayObject1,
};
use crate::rust::ForOfIterationFailure;
use crate::rust::{maybe_wrap_object_or_null_value, maybe_wrap_object_value, ToString};
Expand Down Expand Up @@ -134,12 +134,7 @@ impl_num!(f64, 0.0, f64::MIN, f64::MAX);
/// A trait to convert Rust types to `JSVal`s.
pub trait ToJSValConvertible {
/// Convert `self` to a `JSVal`. JSAPI failure causes a panic.
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue);

/// Convert `self` to a `JSVal`. JSAPI failure causes a panic.
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, rval: MutableHandleValue) {
unsafe { self.to_jsval(cx.raw_cx(), rval) }
}
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, rval: MutableHandleValue);
}

/// An enum to better support enums through FromJSValConvertible::from_jsval.
Expand Down Expand Up @@ -296,7 +291,7 @@ where
// https://heycam.github.io/webidl/#es-void
impl ToJSValConvertible for () {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(UndefinedValue());
}
}
Expand All @@ -315,23 +310,23 @@ impl FromJSValConvertible for JSVal {

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

impl<'a> ToJSValConvertible for HandleValue<'a> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, cx: &mut crate::context::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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(self.get());
maybe_wrap_value(cx, rval);
}
Expand Down Expand Up @@ -366,7 +361,7 @@ where
// https://heycam.github.io/webidl/#es-boolean
impl ToJSValConvertible for bool {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(BooleanValue(*self));
}
}
Expand All @@ -387,7 +382,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
Expand All @@ -408,7 +403,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
Expand All @@ -429,7 +424,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
Expand All @@ -450,7 +445,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
Expand All @@ -471,7 +466,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(Int32Value(*self));
}
}
Expand All @@ -492,7 +487,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(UInt32Value(*self));
}
}
Expand All @@ -513,7 +508,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(DoubleValue(*self as f64));
}
}
Expand All @@ -534,7 +529,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(DoubleValue(*self as f64));
}
}
Expand All @@ -555,7 +550,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(DoubleValue(*self as f64));
}
}
Expand All @@ -577,7 +572,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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(DoubleValue(*self))
}
}
Expand Down Expand Up @@ -666,7 +661,7 @@ pub unsafe fn unsafe_jsstr_to_string(cx: *mut JSContext, jsstr: NonNull<JSString
impl ToJSValConvertible for str {
#[inline]
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
// Spidermonkey will automatically only copy latin1
// or similar if the given encoding can be small enough.
// So there is no need to distinguish between ascii only or similar.
Expand All @@ -684,8 +679,8 @@ impl ToJSValConvertible for str {
// https://heycam.github.io/webidl/#es-USVString
impl ToJSValConvertible for String {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
(**self).to_jsval(cx, rval);
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, rval: MutableHandleValue) {
(**self).safe_to_jsval(cx, rval);
}
}

Expand All @@ -709,9 +704,9 @@ impl FromJSValConvertible for String {

impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
match self {
&Some(ref value) => value.to_jsval(cx, rval),
&Some(ref value) => value.safe_to_jsval(cx, rval),
&None => rval.set(NullValue()),
}
}
Expand Down Expand Up @@ -740,43 +735,45 @@ impl<T: FromJSValConvertible> FromJSValConvertible for Option<T> {

impl<T: ToJSValConvertible> ToJSValConvertible for &'_ T {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
(**self).to_jsval(cx, rval)
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, rval: MutableHandleValue) {
(**self).safe_to_jsval(cx, rval)
}
}

impl<T: ToJSValConvertible> ToJSValConvertible for Box<T> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
(**self).to_jsval(cx, rval)
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, rval: MutableHandleValue) {
(**self).safe_to_jsval(cx, rval)
}
}

impl<T: ToJSValConvertible> ToJSValConvertible for Rc<T> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
(**self).to_jsval(cx, rval)
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, rval: MutableHandleValue) {
(**self).safe_to_jsval(cx, rval)
}
}

// https://heycam.github.io/webidl/#es-sequence
impl<T: ToJSValConvertible> ToJSValConvertible for [T] {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
rooted!(in(cx) let js_array = NewArrayObject1(cx, self.len() as libc::size_t));
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rooted!(&in(cx) let js_array = unsafe { NewArrayObject1(cx, self.len() as libc::size_t) });
assert!(!js_array.handle().is_null());

rooted!(in(cx) let mut val = UndefinedValue());
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().into(),
index as u32,
val.handle().into(),
JSPROP_ENUMERATE as u32
));
obj.safe_to_jsval(cx, val.handle_mut());

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

rval.set(ObjectValue(js_array.handle().get()));
Expand All @@ -786,8 +783,8 @@ impl<T: ToJSValConvertible> ToJSValConvertible for [T] {
// https://heycam.github.io/webidl/#es-sequence
impl<T: ToJSValConvertible> ToJSValConvertible for Vec<T> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
<[_]>::to_jsval(self, cx, rval)
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, rval: MutableHandleValue) {
<[_]>::safe_to_jsval(self, cx, rval)
}
}

Expand Down Expand Up @@ -834,7 +831,7 @@ impl<C: Clone, T: FromJSValConvertible<Config = C>> FromJSValConvertible for Vec
// https://heycam.github.io/webidl/#es-object
impl ToJSValConvertible for *mut JSObject {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(ObjectOrNullValue(*self));
maybe_wrap_object_or_null_value(cx, rval);
}
Expand All @@ -843,16 +840,16 @@ 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, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(ObjectValue(self.as_ptr()));
maybe_wrap_object_value(cx, rval);
unsafe { maybe_wrap_object_value(cx, rval) };
}
}

// https://heycam.github.io/webidl/#es-object
impl ToJSValConvertible for Heap<*mut JSObject> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
rval.set(ObjectOrNullValue(self.get()));
maybe_wrap_object_or_null_value(cx, rval);
}
Expand Down Expand Up @@ -883,8 +880,8 @@ impl FromJSValConvertible for *mut JSObject {

impl ToJSValConvertible for *mut JS::Symbol {
#[inline]
unsafe fn to_jsval(&self, _: *mut JSContext, mut rval: MutableHandleValue) {
rval.set(SymbolValue(&**self));
fn safe_to_jsval(&self, _cx: &mut crate::context::JSContext, mut rval: MutableHandleValue) {
unsafe { rval.set(SymbolValue(&**self)) };
}
}

Expand Down
22 changes: 14 additions & 8 deletions mozjs/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,30 +984,36 @@ pub unsafe fn maybe_wrap_object(cx: *mut JSContext, mut obj: MutableHandleObject
}

#[inline]
pub unsafe fn maybe_wrap_object_value(cx: *mut JSContext, rval: MutableHandleValue) {
pub unsafe fn maybe_wrap_object_value(
cx: &mut crate::context::JSContext,
rval: MutableHandleValue,
) {
assert!(rval.is_object());
let obj = rval.to_object();
if get_object_realm(obj) != get_context_realm(cx) {
assert!(JS_WrapValue(cx, rval.into()));
if get_object_realm(obj) != get_context_realm(cx.raw_cx()) {
assert!(JS_WrapValue(cx.raw_cx(), rval.into()));
} else if is_dom_object(obj) {
try_to_outerize(rval);
}
}

#[inline]
pub unsafe fn maybe_wrap_object_or_null_value(cx: *mut JSContext, rval: MutableHandleValue) {
pub fn maybe_wrap_object_or_null_value(
cx: &mut crate::context::JSContext,
rval: MutableHandleValue,
) {
assert!(rval.is_object_or_null());
if !rval.is_null() {
maybe_wrap_object_value(cx, rval);
unsafe { maybe_wrap_object_value(cx, rval) };
}
}

#[inline]
pub unsafe fn maybe_wrap_value(cx: *mut JSContext, rval: MutableHandleValue) {
pub fn maybe_wrap_value(cx: &mut crate::context::JSContext, rval: MutableHandleValue) {
if rval.is_string() {
assert!(JS_WrapValue(cx, rval.into()));
assert!(unsafe { JS_WrapValue(cx.raw_cx(), rval.into()) });
} else if rval.is_object() {
maybe_wrap_object_value(cx, rval);
unsafe { maybe_wrap_object_value(cx, rval) };
}
}

Expand Down
4 changes: 2 additions & 2 deletions mozjs/src/typedarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ impl<T: TypedArrayElement, S: JSObjectStorage> FromJSValConvertible for TypedArr

impl<T: TypedArrayElement, S: JSObjectStorage> ToJSValConvertible for TypedArray<T, S> {
#[inline]
unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
ToJSValConvertible::to_jsval(&self.object.as_raw(), cx, rval);
fn safe_to_jsval(&self, cx: &mut crate::context::JSContext, rval: MutableHandleValue) {
ToJSValConvertible::safe_to_jsval(&self.object.as_raw(), cx, rval);
}
}

Expand Down
Loading