Skip to content

Commit 9cd51a2

Browse files
committed
Store context in handle, run in debugmozjs mode, compiler panicing...
1 parent 3ef53b2 commit 9cd51a2

File tree

7 files changed

+244
-160
lines changed

7 files changed

+244
-160
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ libc = []
88
debugmozjs = ['mozjs/debugmozjs']
99

1010
[dependencies]
11-
mozjs = {git = "https://github.com/servo/rust-mozjs", features = ["promises"]}
11+
mozjs = {git = "https://github.com/servo/rust-mozjs", features = ["promises", "debugmozjs"]}
1212
tokio-core = "0.1.6"
1313
tokio-timer = "0.1.1"
1414
futures = "0.1"

src/jslib/eventloop.rs

Lines changed: 24 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,26 @@
11

22
extern crate tokio_core;
3-
// extern crate tokio_timer;
43
extern crate futures;
54

65
use tokio_core::reactor as tokio;
76
use futures::Future;
87
use futures::future;
98
use futures::Stream;
10-
use futures::IntoFuture;
11-
// use futures::future::{FutureResult};
12-
// use tokio_timer::{Timer, TimerError};
139
use futures::sync::oneshot;
1410
use futures::sync::mpsc;
15-
use futures::sync::mpsc::UnboundedSender;
16-
//use futures::future::IntoFuture;
1711

18-
//use std::ops::Deref;
1912
use std::sync::{Arc, Weak};
2013
use std::rc;
2114
use std::rc::Rc;
22-
//use std::boxed::FnBox;
2315
use std::clone::Clone;
2416
use std::marker::PhantomData;
2517
use slab::Slab;
26-
use std::cell::{RefCell, Ref, RefMut};
18+
use std::cell::{RefCell};
2719
use std::fmt::Debug;
2820
use downcast::Any;
2921
use mozjs::rust::{Trace, GCMethods, Runtime};
3022
use mozjs::jsapi::{JSTracer, Heap};
3123
use mozjs::jsapi::{ JS_AddExtraGCRootsTracer, JS_RemoveExtraGCRootsTracer };
32-
use mozjs::jsapi::JSRuntime;
3324
use mozjs::jsapi::{JS_GC, GCForReason, JSGCInvocationKind, Reason, JSAutoCompartment, CurrentGlobalOrNull};
3425

3526
use std::os::raw::c_void;
@@ -87,7 +78,7 @@ unsafe extern "C" fn ref_slab_tracer(trc: *mut JSTracer, data: *mut c_void) {
8778
//println!("ref_slab_tracer: {}", count);
8879
}
8980

90-
pub fn run<T, F>(rt: &Runtime, t: &T, first: F)
81+
pub fn run<T, F>(rt: &Runtime, t: T, first: F)
9182
where T: Sized,
9283
F: FnOnce(Handle<T>) -> ()
9384
{
@@ -100,10 +91,13 @@ pub fn run<T, F>(rt: &Runtime, t: &T, first: F)
10091

10192
let core_handle = core.handle();
10293

94+
let data = rc::Rc::new(t);
95+
10396
let remote = Remote(tx);
10497
let handle = Handle {
10598
remote: remote,
10699
thandle: core_handle.clone(),
100+
data: data.clone(),
107101
slab: Rc::downgrade(&slab),
108102
};
109103

@@ -120,11 +114,12 @@ pub fn run<T, F>(rt: &Runtime, t: &T, first: F)
120114
let handle = Handle {
121115
remote: remote,
122116
thandle: core_handle.clone(),
117+
data: data.clone(),
123118
slab: Rc::downgrade(&slab),
124119
};
125120
//let _ac = JSAutoCompartment::new(rt.cx(), unsafe { CurrentGlobalOrNull(rt.cx()) });
126121
unsafe { GCForReason(rt.rt(), JSGCInvocationKind::GC_SHRINK, Reason::NO_REASON) };
127-
f.call_box(t, handle);
122+
f.call_box(handle);
128123
unsafe { GCForReason(rt.rt(), JSGCInvocationKind::GC_SHRINK, Reason::NO_REASON) };
129124
Ok(())
130125
})
@@ -139,6 +134,7 @@ pub fn run<T, F>(rt: &Runtime, t: &T, first: F)
139134
pub struct Handle<T> {
140135
remote: Remote<T>,
141136
thandle: tokio::Handle,
137+
data: rc::Rc<T>,
142138
slab: rc::Weak<RefCell<Slab<RefSlabEl>>>,
143139
}
144140

@@ -147,6 +143,7 @@ impl<T> Clone for Handle<T> {
147143
Handle {
148144
remote: self.remote.clone(),
149145
thandle: self.thandle.clone(),
146+
data: self.data.clone(),
150147
slab: self.slab.clone(),
151148
}
152149
}
@@ -159,11 +156,15 @@ impl<T> Handle<T> {
159156
pub fn remote(&self) -> &Remote<T> {
160157
&self.remote
161158
}
159+
pub fn get(&self) -> &T {
160+
&self.data
161+
}
162162

163163
pub fn downgrade(&self) -> WeakHandle<T> {
164164
WeakHandle {
165165
remote: Arc::downgrade(&self.remote.0),
166166
thandle: self.thandle.clone(),
167+
data: rc::Rc::downgrade(&self.data),
167168
slab: self.slab.clone(),
168169
}
169170
}
@@ -233,66 +234,31 @@ impl<T> Handle<T> {
233234
//println!("retrieved: {:?}", val);
234235
val
235236
}
236-
237-
// This seems impossible to do without a Ref<Ref<V>>
238-
/*fn borrow<'h: 'r, 'r, V: 'static>(&self, rref: &'r RemoteRef<V>) -> Option<Ref<'r, V>> {
239-
let slab = self.slab.upgrade().unwrap();
240-
let slab = slab.borrow();
241-
let mut out = None;
242-
243-
let refopt: Ref<Option<Ref<V>>> = Ref::map(slab, |slab| {
244-
let r: &RefCell<Option<*mut ()>> = unsafe { slab.get_unchecked(rref.key) };
245-
let ro = r.try_borrow();
246-
247-
match ro {
248-
Err(_) => &out,
249-
Ok(rro) => {
250-
out = rro.rewrap_map(|vp| unsafe { &*(*vp as *mut V) });
251-
&out
252-
}
253-
}
254-
});
255-
match *refopt {
256-
Some(_) => Some(Ref::map(refopt, |o| o.unwrap())),
257-
None => None,
258-
}
259-
}
260-
fn borrow_mut<V: 'static>(&self, rref: &RemoteRef<V>) -> Option<RefMut<V>> {
261-
262-
None
263-
}*/
264237
}
265238

266239
#[derive(Clone)]
267240
pub struct WeakHandle<T> {
268241
remote: Weak<mpsc::UnboundedSender<Message<T>>>,
269242
thandle: tokio::Handle,
243+
data: rc::Weak<T>,
270244
slab: rc::Weak<RefCell<Slab<RefSlabEl>>>,
271245
}
272246

273247
impl<T> WeakHandle<T> {
274248
pub fn upgrade(&self) -> Option<Handle<T>> {
275-
self.remote.upgrade().map(|remote| {
249+
let remote = self.remote.upgrade();
250+
let data = self.data.upgrade();
251+
remote.and_then(|remote| data.map(|data| {
276252
Handle{
277253
remote: Remote(remote),
278254
thandle: self.thandle.clone(),
255+
data: data,
279256
slab: self.slab.clone(),
280257
}
281-
})
258+
}))
282259
}
283260
}
284261

285-
/*trait Rewrap<'b, T> {
286-
fn rewrap_map<V, F: FnOnce(&T) -> &V>(self, f: F) -> Option<Ref<'b, V>>;
287-
}
288-
impl<'b, T> Rewrap<'b, T> for Ref<'b, Option<T>> {
289-
fn rewrap_map<V, F: FnOnce(&T) -> &V>(self, f: F) -> Option<Ref<'b, V>> {
290-
match *self {
291-
None => None,
292-
Some(_) => Some(Ref::map(self, |o| f(&o.unwrap()))),
293-
}
294-
}
295-
}*/
296262

297263
#[derive(Clone)]
298264
pub struct RemoteRef<V> {
@@ -313,7 +279,7 @@ impl<T> Clone for Remote<T> {
313279
impl<T> Remote<T> {
314280

315281
pub fn spawn<F>(&self, f: F)
316-
where F: FnOnce(&T, Handle<T>) + Send + 'static
282+
where F: FnOnce(Handle<T>) + Send + 'static
317283
{
318284
let me: Remote<T> = (*self).clone();
319285
let myfunc: Box<FnBox<T> + 'static> = Box::new( f );
@@ -324,12 +290,12 @@ impl<T> Remote<T> {
324290
}
325291

326292
trait FnBox<T>: Send {
327-
fn call_box(self: Box<Self>, t: &T, h: Handle<T>);
293+
fn call_box(self: Box<Self>, h: Handle<T>);
328294
}
329295

330-
impl<T, F: FnOnce(&T, Handle<T>) + Send + 'static> FnBox<T> for F {
331-
fn call_box(self: Box<Self>, t: &T, h: Handle<T>) {
332-
(*self)(t, h)
296+
impl<T, F: FnOnce(Handle<T>) + Send + 'static> FnBox<T> for F {
297+
fn call_box(self: Box<Self>, h: Handle<T>) {
298+
(*self)(h)
333299
}
334300
}
335301

src/jslib/jsclass.rs

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -97,32 +97,55 @@ macro_rules! compute_once {
9797
}
9898
}
9999
}
100+
101+
#[macro_export]
102+
macro_rules! c_str {
103+
($str:expr) => {
104+
concat!($str, "\0").as_ptr() as *const ::std::os::raw::c_char
105+
}
106+
}
107+
100108
#[macro_export]
101109
macro_rules! js_class {
102110

103111
($name:ident [$flags:expr] $($body:tt)*) => {
104112
//trace_macros!{true}
105-
__jsclass_parse!{$name [$flags] [] [] [] [] $($body)*}
113+
__jsclass_parse!{$name [$flags] [()] [] [] [] [] $($body)*}
106114
};
107115
}
108116

109117
#[macro_export]
110118
macro_rules! __jsclass_parsed {
111-
($name:ident [$flags:expr] [$($constr:tt)*] [$($fns:tt)*] [$($ops:tt)*] [$($props:tt)*]) => {
119+
($name:ident [$flags:expr] [$private:ty] [$($constr:tt)*] [$($fns:tt)*] [$($ops:tt)*] [$($props:tt)*]) => {
112120

113121
$( __jsclass_toplevel!{_constr $constr} )*
114122
$( __jsclass_toplevel!{_fn $fns} )*
115123
$( __jsclass_toplevel!{_op $ops} )*
116124
$( __jsclass_toplevel!{_prop $props} )*
117125

118126

127+
impl $name {
128+
129+
fn get_private(cx: *mut JSContext, obj: Handle<*mut JSObject>, args: &mut CallArgs) -> Option<*mut $private> {
130+
unsafe {
131+
let ptr = JS_GetInstancePrivate(cx, obj, Self::class(), args as *mut CallArgs) as *mut $private;
132+
if ptr.is_null() {
133+
None
134+
} else {
135+
Some(ptr)
136+
}
137+
}
138+
}
139+
}
140+
119141
impl JSClassInitializer for $name {
120142
fn class() -> *const JSClass {
121143
compute_once!{
122144
*const JSClass = ptr::null();
123145
{
124146
Box::into_raw(Box::new( JSClass {
125-
name: CString::new(stringify!($name)).unwrap().into_raw(),
147+
//name: CString::new(stringify!($name)).unwrap().into_raw(),
148+
name: c_str!(stringify!($name)),
126149
flags: $flags,
127150
cOps: __jsclass_ops!([] $($ops)*),
128151
reserved: [0 as *mut _; 3],
@@ -131,6 +154,7 @@ impl JSClassInitializer for $name {
131154
}
132155
}
133156

157+
134158
fn constr() -> Option<Box<RJSFn>> {
135159

136160
$(
@@ -189,33 +213,38 @@ macro_rules! nothing {
189213

190214
#[macro_export]
191215
macro_rules! __jsclass_parse {
192-
($cname:ident $flags:tt $constr:tt $fns:tt $ops:tt $props:tt ) => {
193-
__jsclass_parsed!{$cname $flags $constr $fns $ops $props}
216+
($cname:ident $flags:tt $private:tt $constr:tt $fns:tt $ops:tt $props:tt ) => {
217+
__jsclass_parsed!{$cname $flags $private $constr $fns $ops $props}
218+
};
219+
($cname:ident $flags:tt [$private:ty] $constr:tt $fns:tt $ops:tt $props:tt
220+
private: $ty:ty, $($rest:tt)*) => {
221+
__jsclass_parse!{$cname $flags [$ty] $constr $fns $ops $props
222+
$($rest)*}
194223
};
195-
($cname:ident $flags:tt $constr:tt [$($fns:tt)*] $ops:tt $props:tt
224+
($cname:ident $flags:tt $private:tt $constr:tt [$($fns:tt)*] $ops:tt $props:tt
196225
fn $name:ident $args:tt -> JSRet<$ret:ty> {$($body:tt)*} $($rest:tt)*) => {
197-
__jsclass_parse!{$cname $flags $constr [$($fns)*
226+
__jsclass_parse!{$cname $flags $private $constr [$($fns)*
198227
[fn $name $args -> JSRet<$ret> { $($body)* }]
199228
] $ops $props
200229
$($rest)*}
201230
};
202-
($cname:ident $flags:tt [$($constr:tt)*] $fns:tt $ops:tt $props:tt
231+
($cname:ident $flags:tt $private:tt [$($constr:tt)*] $fns:tt $ops:tt $props:tt
203232
@constructor fn $name:ident $args:tt -> JSRet<$ret:ty> {$($body:tt)*} $($rest:tt)*) => {
204-
__jsclass_parse!{$cname $flags [$($constr)*
233+
__jsclass_parse!{$cname $flags $private [$($constr)*
205234
[fn $name $args -> JSRet<$ret> { $($body)* }]
206235
] $fns $ops $props
207236
$($rest)*}
208237
};
209-
($cname:ident $flags:tt $constr:tt $fns:tt [$($ops:tt)*] $props:tt
238+
($cname:ident $flags:tt $private:tt $constr:tt $fns:tt [$($ops:tt)*] $props:tt
210239
@op($op:ident) fn $name:ident $args:tt -> $ret:ty {$($body:tt)*} $($rest:tt)*) => {
211-
__jsclass_parse!{$cname $flags $constr $fns [$($ops)*
240+
__jsclass_parse!{$cname $flags $private $constr $fns [$($ops)*
212241
[$op fn $name $args -> $ret { $($body)* }]
213242
] $props
214243
$($rest)*}
215244
};
216-
($cname:ident $flags:tt $constr:tt $fns:tt $ops:tt [$($props:tt)*]
245+
($cname:ident $flags:tt $private:tt $constr:tt $fns:tt $ops:tt [$($props:tt)*]
217246
@prop $name:ident $body:tt $($rest:tt)*) => {
218-
__jsclass_parse!{$cname $flags $constr $fns $ops [$($props)*
247+
__jsclass_parse!{$cname $flags $private $constr $fns $ops [$($props)*
219248
[$name $body]
220249
]
221250
$($rest)*}
@@ -304,7 +333,8 @@ macro_rules! __jsclass_functionspec {
304333
$vec.push(
305334
JSFunctionSpec {
306335
//name: b"log\0" as *const u8 as *const c_char,
307-
name: CString::new(stringify!($name)).unwrap().into_raw(),
336+
//name: CString::new(stringify!($name)).unwrap().into_raw(),
337+
name: concat!(stringify!($name), "\0").as_ptr() as *const ::std::os::raw::c_char,
308338
selfHostedName: ptr::null(),
309339
flags: JSPROP_ENUMERATE as u16,
310340
nargs: $name{}.nargs() as u16,
@@ -349,7 +379,8 @@ macro_rules! __jsclass_propertyspec {
349379
$vec.push(
350380
JSPropertySpec {
351381
//name: b"window\0" as *const u8 as *const c_char,
352-
name: CString::new(stringify!($name)).unwrap().into_raw(),
382+
//name: CString::new(stringify!($name)).unwrap().into_raw(),
383+
name: concat!(stringify!($name), "\0").as_ptr() as *const ::std::os::raw::c_char,
353384
flags: (JSPROP_ENUMERATE | JSPROP_SHARED) as u8,
354385
getter: $getter,
355386
setter: $setter,

src/jslib/jsfn.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
use mozjs::jsapi::JSContext;
2-
use mozjs::jsapi::JSNative;
32
use mozjs::jsapi::JSFunction;
43
use mozjs::jsapi::JS_DefineFunction;
54
use mozjs::jsapi::Value;
65
use mozjs::jsapi::HandleObject;
76
use mozjs::conversions::ToJSValConvertible;
87

8+
use ::jslib::eventloop;
9+
use ::jslib::context::{RJSContext};
10+
911
use libc;
10-
use libc::c_uint;
12+
//use libc::c_uint;
1113
use std::ffi::CString;
1214

15+
pub type RuntimePrivate = eventloop::WeakHandle<RJSContext>;
16+
1317
pub type JSRet<T: ToJSValConvertible> = Result<T, Option<String>>;
1418

1519
pub type RJSNativeRaw = unsafe extern "C" fn(*mut JSContext, u32, *mut Value) -> bool;
@@ -35,9 +39,9 @@ macro_rules! js_fn_raw {
3539
unsafe extern "C" fn $name (cx: *mut JSContext, argc: u32, vp: *mut Value) -> bool {
3640
let args = CallArgs::from_vp(vp, argc);
3741
let rt = JS_GetRuntime(cx);
38-
let privatebox = JS_GetRuntimePrivate(rt) as *const (&RJSContext, eventloop::WeakHandle<RJSContext>);
39-
let rcx = (*privatebox).0;
40-
let handle = (*privatebox).1.upgrade().unwrap();
42+
let privatebox = JS_GetRuntimePrivate(rt) as *const $crate::jslib::jsfn::RuntimePrivate;
43+
let handle = (*privatebox).upgrade().unwrap();
44+
let rcx = handle.get();
4145
assert!(rcx.cx == cx);
4246

4347
fn rustImpl($($param : $type),*) -> JSRet<$ret> $body

src/jslib/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pub mod jsclass;
55
#[macro_use]
66
pub mod jsfn;
77
pub mod eventloop;
8+
pub mod context;

0 commit comments

Comments
 (0)