Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to Spidermonkey 39 #6141

Closed
wants to merge 7 commits into from
Next

Upgrade to SM 39

  • Loading branch information
michaelwu committed May 20, 2015
commit 75064f2500f66582ea2e5c6fdcb565d22ae35bfd
@@ -17,6 +17,8 @@ use dom::document::DocumentHelpers;
use page::{IterablePage, Page};
use msg::constellation_msg::PipelineId;
use script_task::{get_page, ScriptTask};
use js::jsapi::RootedValue;
use js::jsval::UndefinedValue;

use std::sync::mpsc::Sender;
use std::rc::Rc;
@@ -26,22 +28,23 @@ pub fn handle_evaluate_js(page: &Rc<Page>, pipeline: PipelineId, eval: String, r
let page = get_page(&*page, pipeline);
let window = page.window().root();
let cx = window.r().get_cx();
let rval = window.r().evaluate_js_on_global_with_result(&eval);
let mut rval = RootedValue::new(cx, UndefinedValue());
window.r().evaluate_js_on_global_with_result(&eval, rval.handle_mut());

reply.send(if rval.is_undefined() {
reply.send(if rval.ptr.is_undefined() {
EvaluateJSReply::VoidValue
} else if rval.is_boolean() {
EvaluateJSReply::BooleanValue(rval.to_boolean())
} else if rval.is_double() {
EvaluateJSReply::NumberValue(FromJSValConvertible::from_jsval(cx, rval, ()).unwrap())
} else if rval.is_string() {
} else if rval.ptr.is_boolean() {
EvaluateJSReply::BooleanValue(rval.ptr.to_boolean())
} else if rval.ptr.is_double() {
EvaluateJSReply::NumberValue(FromJSValConvertible::from_jsval(cx, rval.handle(), ()).unwrap())
} else if rval.ptr.is_string() {
//FIXME: use jsstring_to_str when jsval grows to_jsstring
EvaluateJSReply::StringValue(FromJSValConvertible::from_jsval(cx, rval, StringificationBehavior::Default).unwrap())
} else if rval.is_null() {
EvaluateJSReply::StringValue(FromJSValConvertible::from_jsval(cx, rval.handle(), StringificationBehavior::Default).unwrap())
} else if rval.ptr.is_null() {
EvaluateJSReply::NullValue
} else {
//FIXME: jsvals don't have an is_int32/is_number yet
assert!(rval.is_object());
assert!(rval.ptr.is_object());
panic!("object values unimplemented")
}).unwrap();
}
@@ -7,10 +7,15 @@
use dom::bindings::global::global_object_for_js_object;
use dom::bindings::js::JSRef;
use dom::bindings::utils::Reflectable;
use js::jsapi::{JSContext, JSObject, JS_WrapObject, JS_ObjectIsCallable, JS_GetGlobalObject};
use js::jsapi::{JSContext, JSObject, JS_WrapObject, IsCallable};
use js::jsapi::{JS_GetProperty, JS_IsExceptionPending, JS_ReportPendingException};
use js::jsapi::{RootedObject, RootedValue};
use js::jsapi::{JSAutoCompartment};
use js::jsapi::{JS_BeginRequest, JS_EndRequest};
use js::jsapi::{JS_EnterCompartment, JS_LeaveCompartment, JSCompartment};
use js::jsapi::GetGlobalForObjectCrossCompartment;
use js::jsapi::{JS_SaveFrameChain, JS_RestoreFrameChain};
use js::jsval::{JSVal, UndefinedValue};
use js::rust::with_compartment;

use std::ffi::CString;
use std::ptr;
@@ -97,46 +102,52 @@ impl CallbackInterface {
/// pending.
pub fn get_callable_property(&self, cx: *mut JSContext, name: &str)
-> Result<JSVal, ()> {
let mut callable = UndefinedValue();
let mut callable = RootedValue::new(cx, UndefinedValue());
let obj = RootedObject::new(cx, self.callback());
unsafe {
let name = CString::new(name).unwrap();
if JS_GetProperty(cx, self.callback(), name.as_ptr(), &mut callable) == 0 {
if JS_GetProperty(cx, obj.handle(), name.as_ptr(),
callable.handle_mut()) == 0 {
return Err(());
}

if !callable.is_object() ||
JS_ObjectIsCallable(cx, callable.to_object()) == 0 {
if !callable.ptr.is_object() ||
IsCallable(callable.ptr.to_object()) == 0 {
// FIXME(#347)
//ThrowErrorMessage(cx, MSG_NOT_CALLABLE, description.get());
return Err(());
}
}
Ok(callable)
Ok(callable.ptr)
}
}

/// Wraps the reflector for `p` into the compartment of `cx`.
pub fn wrap_call_this_object<T: Reflectable>(cx: *mut JSContext,
p: JSRef<T>) -> *mut JSObject {
let mut obj = p.reflector().get_jsobject();
assert!(!obj.is_null());
let mut obj = RootedObject::new(cx, p.reflector().get_jsobject());
assert!(!obj.ptr.is_null());

unsafe {
if JS_WrapObject(cx, &mut obj) == 0 {
if JS_WrapObject(cx, obj.handle_mut()) == 0 {
return ptr::null_mut();
}
}

return obj;
return obj.ptr;
}

/// A class that performs whatever setup we need to safely make a call while
/// this class is on the stack. After `new` returns, the call is safe to make.
pub struct CallSetup {
/// The `JSContext` used for the call.
cx: *mut JSContext,
/// The compartment we were in before the call.
old_compartment: *mut JSCompartment,
/// The compartment for reporting exceptions.
exception_compartment: *mut JSObject,
/// The exception handling used for the call.
_handling: ExceptionHandling,
handling: ExceptionHandling,
}

impl CallSetup {
@@ -146,10 +157,13 @@ impl CallSetup {
let global = global_object_for_js_object(callback.callback());
let global = global.root();
let cx = global.r().get_cx();
unsafe { JS_BeginRequest(cx); }

CallSetup {
cx: cx,
_handling: handling,
old_compartment: unsafe { JS_EnterCompartment(cx, callback.callback()) },
exception_compartment: unsafe { GetGlobalForObjectCrossCompartment(callback.callback()) },
handling: handling,
}
}

@@ -161,14 +175,23 @@ impl CallSetup {

impl Drop for CallSetup {
fn drop(&mut self) {
let need_to_deal_with_exception = unsafe { JS_IsExceptionPending(self.cx) } != 0;
unsafe { JS_LeaveCompartment(self.cx, self.old_compartment); }
let need_to_deal_with_exception =
self.handling == ExceptionHandling::Report &&
unsafe { JS_IsExceptionPending(self.cx) } != 0;
if need_to_deal_with_exception {
unsafe {
let old_global = JS_GetGlobalObject(self.cx);
with_compartment(self.cx, old_global, || {
JS_ReportPendingException(self.cx)
});
let old_global = RootedObject::new(self.cx, self.exception_compartment);
let saved = JS_SaveFrameChain(self.cx) != 0;
{
let _ac = JSAutoCompartment::new(self.cx, old_global.ptr);
JS_ReportPendingException(self.cx);
}
if saved {
JS_RestoreFrameChain(self.cx);
}
}
}
unsafe { JS_EndRequest(self.cx); }
}
}
@@ -15,7 +15,7 @@
DOMInterfaces = {

'Window': {
'outerObjectHook': 'Some(bindings::utils::outerize_global as extern fn(*mut JSContext, JSHandleObject) -> *mut JSObject)',
'outerObjectHook': 'Some(bindings::utils::outerize_global)',
},

#FIXME(jdm): This should be 'register': False, but then we don't generate enum types
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.