Skip to content

Commit d6c3bd9

Browse files
authored
Remove HandleValueArray::from_rooted_slice footgun (#533)
* Remove HandleValueArray::from_rooted_slice footgun. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Add iterator constructor for RootedVec. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Introduce optional crown annotations. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Formatting. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Update wasm example. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Formatting. Signed-off-by: Josh Matthews <josh@joshmatthews.net> --------- Signed-off-by: Josh Matthews <josh@joshmatthews.net>
1 parent e299b24 commit d6c3bd9

File tree

8 files changed

+80
-23
lines changed

8 files changed

+80
-23
lines changed

mozjs-sys/src/jsgc.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,6 @@ impl<const N: usize> ValueArray<N> {
249249
Self { elements }
250250
}
251251

252-
pub fn to_handle_value_array(&self) -> JS::HandleValueArray {
253-
JS::HandleValueArray {
254-
length_: N,
255-
elements_: self.elements.as_ptr(),
256-
}
257-
}
258-
259252
pub unsafe fn get_ptr(&self) -> *const JS::Value {
260253
self.elements.as_ptr()
261254
}

mozjs-sys/src/jsimpls.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ use crate::jsapi::JSPropertySpec_Kind;
2020
use crate::jsapi::JSPropertySpec_Name;
2121
use crate::jsapi::JS;
2222
use crate::jsapi::JS::Scalar::Type;
23-
use crate::jsgc::{RootKind, RootedBase};
23+
use crate::jsgc::{RootKind, Rooted, RootedBase, ValueArray};
2424
use crate::jsid::VoidId;
25-
use crate::jsval::UndefinedValue;
25+
use crate::jsval::{JSVal, UndefinedValue};
2626

2727
use std::marker::PhantomData;
2828
use std::ops::Deref;
@@ -132,17 +132,37 @@ impl JS::HandleValue {
132132
}
133133

134134
impl JS::HandleValueArray {
135-
pub fn new() -> JS::HandleValueArray {
135+
pub fn empty() -> JS::HandleValueArray {
136136
JS::HandleValueArray {
137137
length_: 0,
138138
elements_: ptr::null(),
139139
}
140140
}
141+
}
142+
143+
impl<const N: usize> From<&Rooted<ValueArray<N>>> for JS::HandleValueArray {
144+
fn from(array: &Rooted<ValueArray<N>>) -> JS::HandleValueArray {
145+
JS::HandleValueArray {
146+
length_: N,
147+
elements_: unsafe { array.ptr.get_ptr() },
148+
}
149+
}
150+
}
151+
152+
impl From<&JS::CallArgs> for JS::HandleValueArray {
153+
fn from(args: &JS::CallArgs) -> JS::HandleValueArray {
154+
JS::HandleValueArray {
155+
length_: args.argc_ as usize,
156+
elements_: args.argv_ as *const _,
157+
}
158+
}
159+
}
141160

142-
pub unsafe fn from_rooted_slice(values: &[JS::Value]) -> JS::HandleValueArray {
161+
impl From<JS::Handle<JSVal>> for JS::HandleValueArray {
162+
fn from(handle: JS::Handle<JSVal>) -> JS::HandleValueArray {
143163
JS::HandleValueArray {
144-
length_: values.len(),
145-
elements_: values.as_ptr(),
164+
length_: 1,
165+
elements_: handle.ptr,
146166
}
147167
}
148168
}

mozjs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ debugmozjs = ['mozjs_sys/debugmozjs']
1515
jitspew = ['mozjs_sys/jitspew']
1616
profilemozjs = ['mozjs_sys/profilemozjs']
1717
streams = ['mozjs_sys/streams']
18+
crown = []
1819

1920
[dependencies]
2021
lazy_static = "1"

mozjs/examples/wasm.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use mozjs::jsval::UndefinedValue;
1616
use mozjs::rooted;
1717
use mozjs::rust::jsapi_wrapped::{Construct1, JS_GetProperty, JS_SetProperty};
1818
use mozjs::rust::SIMPLE_GLOBAL_CLASS;
19-
use mozjs::rust::{JSEngine, RealmOptions, Runtime};
19+
use mozjs::rust::{IntoHandle, JSEngine, RealmOptions, Runtime};
2020
use mozjs_sys::jsgc::ValueArray;
2121

2222
#[repr(align(8))]
@@ -94,10 +94,7 @@ fn run(rt: Runtime) {
9494
assert!(!array_buffer.is_null());
9595

9696
rooted!(in(rt.cx()) let val = ObjectValue(array_buffer));
97-
let args = HandleValueArray {
98-
length_: 1,
99-
elements_: &*val,
100-
};
97+
let args = HandleValueArray::from(val.handle().into_handle());
10198

10299
assert!(Construct1(
103100
rt.cx(),
@@ -134,12 +131,11 @@ fn run(rt: Runtime) {
134131
));
135132

136133
rooted!(in(rt.cx()) let mut args = ValueArray::new([ObjectValue(module.get()), ObjectValue(imports.get())]));
137-
let handle = args.handle();
138134

139135
assert!(Construct1(
140136
rt.cx(),
141137
wasm_instance.handle(),
142-
&handle.to_handle_value_array(),
138+
&HandleValueArray::from(&args),
143139
&mut instance.handle_mut()
144140
));
145141
}
@@ -169,7 +165,7 @@ fn run(rt: Runtime) {
169165
rt.cx(),
170166
JS::UndefinedHandleValue,
171167
foo.handle().into(),
172-
&HandleValueArray::new(),
168+
&HandleValueArray::empty(),
173169
rval.handle_mut().into()
174170
));
175171

mozjs/src/gc/collections.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
use crate::gc::{RootedTraceableSet, Traceable};
22
use crate::jsapi::{Heap, JSTracer};
33
use crate::rust::Handle;
4+
use mozjs_sys::jsapi::JS;
45
use mozjs_sys::jsgc::GCMethods;
6+
use mozjs_sys::jsval::JSVal;
57
use std::ops::{Deref, DerefMut};
68

79
/// A vector of items to be rooted with `RootedVec`.
810
/// Guaranteed to be empty when not rooted.
11+
#[cfg_attr(feature = "crown", allow(crown::unrooted_must_root))]
12+
#[cfg_attr(
13+
feature = "crown",
14+
crown::unrooted_must_root_lint::allow_unrooted_interior
15+
)]
916
pub struct RootableVec<T: Traceable> {
1017
v: Vec<T>,
1118
}
@@ -24,17 +31,41 @@ unsafe impl<T: Traceable> Traceable for RootableVec<T> {
2431
}
2532

2633
/// A vector of items rooted for the lifetime 'a.
34+
#[cfg_attr(
35+
feature = "crown",
36+
crown::unrooted_must_root_lint::allow_unrooted_interior
37+
)]
2738
pub struct RootedVec<'a, T: Traceable + 'static> {
2839
root: &'a mut RootableVec<T>,
2940
}
3041

42+
impl From<&RootedVec<'_, JSVal>> for JS::HandleValueArray {
43+
fn from(vec: &RootedVec<'_, JSVal>) -> JS::HandleValueArray {
44+
JS::HandleValueArray {
45+
length_: vec.root.v.len(),
46+
elements_: vec.root.v.as_ptr(),
47+
}
48+
}
49+
}
50+
3151
impl<'a, T: Traceable + 'static> RootedVec<'a, T> {
3252
pub fn new(root: &'a mut RootableVec<T>) -> RootedVec<'a, T> {
3353
unsafe {
3454
RootedTraceableSet::add(root);
3555
}
3656
RootedVec { root }
3757
}
58+
59+
pub fn from_iter<I>(root: &'a mut RootableVec<T>, iter: I) -> Self
60+
where
61+
I: Iterator<Item = T>,
62+
{
63+
unsafe {
64+
RootedTraceableSet::add(root);
65+
}
66+
root.v.extend(iter);
67+
RootedVec { root }
68+
}
3869
}
3970

4071
impl<'a, T: Traceable + 'static> Drop for RootedVec<'a, T> {

mozjs/src/gc/root.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ use std::marker::PhantomData;
22
use std::ops::{Deref, DerefMut};
33
use std::ptr;
44

5-
use crate::jsapi::{jsid, JSContext, JSFunction, JSObject, JSScript, JSString, Symbol, Value};
5+
use crate::jsapi::{jsid, JSContext, JSFunction, JSObject, JSScript, JSString, Symbol, Value, JS};
66
use mozjs_sys::jsgc::{GCMethods, RootKind, Rooted};
77

88
use crate::jsapi::Handle as RawHandle;
99
use crate::jsapi::HandleValue as RawHandleValue;
1010
use crate::jsapi::MutableHandle as RawMutableHandle;
1111
use mozjs_sys::jsgc::IntoHandle as IntoRawHandle;
1212
use mozjs_sys::jsgc::IntoMutableHandle as IntoRawMutableHandle;
13+
use mozjs_sys::jsgc::ValueArray;
1314

1415
/// Rust API for keeping a Rooted value in the context's root stack.
1516
/// Example usage: `rooted!(in(cx) let x = UndefinedValue());`.
@@ -69,6 +70,12 @@ impl<'a, T: 'a + RootKind + GCMethods> Drop for RootedGuard<'a, T> {
6970
}
7071
}
7172

73+
impl<'a, const N: usize> From<&RootedGuard<'a, ValueArray<N>>> for JS::HandleValueArray {
74+
fn from(array: &RootedGuard<'a, ValueArray<N>>) -> JS::HandleValueArray {
75+
JS::HandleValueArray::from(&*array.root)
76+
}
77+
}
78+
7279
#[derive(Clone, Copy)]
7380
pub struct Handle<'a, T: 'a> {
7481
pub(crate) ptr: &'a T,

mozjs/src/gc/trace.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::c_str;
22
use crate::glue::{
33
CallBigIntTracer, CallFunctionTracer, CallIdTracer, CallObjectTracer, CallScriptTracer,
4-
CallStringTracer, CallSymbolTracer, CallValueTracer,
4+
CallStringTracer, CallSymbolTracer, CallValueRootTracer, CallValueTracer,
55
};
66
use crate::jsapi::{
77
jsid, JSFunction, JSObject, JSScript, JSString, JSTracer, PropertyDescriptor, Value,
@@ -110,6 +110,13 @@ unsafe impl Traceable for Heap<Value> {
110110
}
111111
}
112112

113+
unsafe impl Traceable for Value {
114+
#[inline]
115+
unsafe fn trace(&self, trc: *mut JSTracer) {
116+
CallValueRootTracer(trc, self as *const _ as *mut Self, c_str!("value"));
117+
}
118+
}
119+
113120
unsafe impl Traceable for Heap<jsid> {
114121
#[inline]
115122
unsafe fn trace(&self, trc: *mut JSTracer) {

mozjs/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
non_snake_case,
1111
improper_ctypes
1212
)]
13+
#![cfg_attr(feature = "crown", feature(register_tool))]
14+
#![cfg_attr(feature = "crown", register_tool(crown))]
1315

1416
//!
1517
//! This crate contains Rust bindings to the [SpiderMonkey Javascript engine][1]

0 commit comments

Comments
 (0)