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

Update SpiderMonkey to m-c bcf4ff0c3eef. #12255

Merged
merged 1 commit into from Jul 28, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -1872,56 +1872,31 @@ def define(self):
elif self.descriptor.weakReferenceable:
args["slots"] = "2"
return """\
static CLASS_OPS: js::jsapi::ClassOps = js::jsapi::ClassOps {
addProperty: None,
delProperty: None,
getProperty: None,
setProperty: None,
enumerate: %(enumerateHook)s,
resolve: %(resolveHook)s,
mayResolve: None,
finalize: Some(%(finalizeHook)s),
call: None,
hasInstance: None,
construct: None,
trace: Some(%(traceHook)s),
};
static Class: DOMJSClass = DOMJSClass {
base: js::jsapi::Class {
name: %(name)s as *const u8 as *const libc::c_char,
flags: JSCLASS_IS_DOMJSCLASS | %(flags)s |
(((%(slots)s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT)
/* JSCLASS_HAS_RESERVED_SLOTS(%(slots)s) */,
addProperty: None,
delProperty: None,
getProperty: None,
setProperty: None,
enumerate: %(enumerateHook)s,
resolve: %(resolveHook)s,
mayResolve: None,
finalize: Some(%(finalizeHook)s),
call: None,
hasInstance: None,
construct: None,
trace: Some(%(traceHook)s),
spec: js::jsapi::ClassSpec {
createConstructor_: None,
createPrototype_: None,
constructorFunctions_: 0 as *const js::jsapi::JSFunctionSpec,
constructorProperties_: 0 as *const js::jsapi::JSPropertySpec,
prototypeFunctions_: 0 as *const js::jsapi::JSFunctionSpec,
prototypeProperties_: 0 as *const js::jsapi::JSPropertySpec,
finishInit_: None,
flags: 0,
},
ext: js::jsapi::ClassExtension {
isWrappedNative: false,
weakmapKeyDelegateOp: None,
objectMovedOp: None,
},
ops: js::jsapi::ObjectOps {
lookupProperty: None,
defineProperty: None,
hasProperty: None,
getProperty: None,
setProperty: None,
getOwnPropertyDescriptor: None,
deleteProperty: None,
watch: None,
unwatch: None,
getElements: None,
enumerate: None,
funToString: None,
},
cOps: &CLASS_OPS,
spec: ptr::null(),
ext: ptr::null(),
oOps: ptr::null(),
},
dom_class: %(domClass)s
};""" % args
@@ -1947,19 +1922,8 @@ def define(self):
flags:
// JSCLASS_HAS_RESERVED_SLOTS(%(slotCount)s)
(%(slotCount)s & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT,
addProperty: None,
delProperty: None,
getProperty: None,
setProperty: None,
enumerate: None,
resolve: None,
mayResolve: None,
finalize: None,
call: None,
hasInstance: None,
construct: None,
trace: None,
reserved: [0 as *mut os::raw::c_void; 23]
cOps: 0 as *const _,
reserved: [0 as *mut os::raw::c_void; 3]
};
""" % {'name': name, 'slotCount': slotCount}

@@ -1983,9 +1947,12 @@ def define(self):
"depth": self.descriptor.prototypeDepth
}
return """\
static INTERFACE_OBJECT_OPS: js::jsapi::ClassOps =
NonCallbackInterfaceObjectClass::ops(%(constructorBehavior)s);
static InterfaceObjectClass: NonCallbackInterfaceObjectClass =
NonCallbackInterfaceObjectClass::new(
%(constructorBehavior)s,
&INTERFACE_OBJECT_OPS,
%(representation)s,
PrototypeList::ID::%(id)s,
%(depth)s);
@@ -2772,6 +2739,7 @@ def definition_body(self):
ownPropertyKeys: Some(own_property_keys),
delete_: Some(%(delete)s),
enumerate: None,
getPrototypeIfOrdinary: Some(proxyhandler::get_prototype_if_ordinary),
preventExtensions: Some(proxyhandler::prevent_extensions),
isExtensible: Some(proxyhandler::is_extensible),
has: None,
@@ -4,15 +4,26 @@

//! Utilities to throw exceptions from Rust bindings.

use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
use dom::bindings::codegen::PrototypeList::proto_id_to_name;
use dom::bindings::conversions::ToJSValConvertible;
use dom::bindings::conversions::root_from_object;
use dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible};
use dom::bindings::global::GlobalRef;
use dom::bindings::str::USVString;
use dom::domexception::{DOMErrorName, DOMException};
use js::error::{throw_range_error, throw_type_error};
use js::jsapi::HandleObject;
use js::jsapi::JSAutoCompartment;
use js::jsapi::{JSContext, JSObject};
use js::jsapi::{JS_IsExceptionPending, JS_ReportPendingException, JS_SetPendingException};
use js::jsapi::JSContext;
use js::jsapi::JSObject;
use js::jsapi::JS_ClearPendingException;
use js::jsapi::JS_ErrorFromException;
use js::jsapi::JS_GetPendingException;
use js::jsapi::JS_IsExceptionPending;
use js::jsapi::JS_SetPendingException;
use js::jsval::UndefinedValue;
use libc::c_uint;
use std::slice::from_raw_parts;

/// DOM exceptions that can be thrown by a native DOM method.
#[derive(Debug, Clone, HeapSizeOf)]
@@ -123,11 +134,101 @@ pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, result:
JS_SetPendingException(cx, thrown.handle());
}

struct ErrorInfo {
filename: String,
message: String,
lineno: c_uint,
column: c_uint,
}

impl ErrorInfo {
unsafe fn from_native_error(cx: *mut JSContext, object: HandleObject)
-> Option<ErrorInfo> {
let report = JS_ErrorFromException(cx, object);
if report.is_null() {
return None;
}

let filename = {
let filename = (*report).filename as *const u8;
if !filename.is_null() {
let length = (0..).find(|idx| *filename.offset(*idx) == 0).unwrap();
let filename = from_raw_parts(filename, length as usize);
String::from_utf8_lossy(filename).into_owned()
} else {
"none".to_string()
}
};

let lineno = (*report).lineno;
let column = (*report).column;

let message = {
let message = (*report).ucmessage;
let length = (0..).find(|idx| *message.offset(*idx) == 0).unwrap();
let message = from_raw_parts(message, length as usize);
String::from_utf16_lossy(message)
};

Some(ErrorInfo {
filename: filename,
message: message,
lineno: lineno,
column: column,
})
}

fn from_dom_exception(cx: *mut JSContext, object: HandleObject) -> Option<ErrorInfo> {
let exception = match root_from_object::<DOMException>(object.get()) {
Ok(exception) => exception,
Err(_) => return None,
};

Some(ErrorInfo {
filename: "".to_string(),
message: exception.Stringifier().into(),
lineno: 0,
column: 0,
})
}
}

/// Report a pending exception, thereby clearing it.
pub unsafe fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) {
if JS_IsExceptionPending(cx) {
let _ac = JSAutoCompartment::new(cx, obj);
JS_ReportPendingException(cx);
rooted!(in(cx) let mut value = UndefinedValue());
if !JS_GetPendingException(cx, value.handle_mut()) {
JS_ClearPendingException(cx);
error!("Uncaught exception: JS_GetPendingException failed");
return;
}

JS_ClearPendingException(cx);
if !value.is_object() {
match USVString::from_jsval(cx, value.handle(), ()) {
Ok(USVString(string)) => error!("Uncaught exception: {}", string),
Err(_) => error!("Uncaught exception: failed to stringify primitive"),
}
return;
}

rooted!(in(cx) let object = value.to_object());
let error_info = ErrorInfo::from_native_error(cx, object.handle())
.or_else(|| ErrorInfo::from_dom_exception(cx, object.handle()));
let error_info = match error_info {
Some(error_info) => error_info,
None => {
error!("Uncaught exception: failed to extract information");
return;
}
};

error!("Error at {}:{}:{} {}",
error_info.filename,
error_info.lineno,
error_info.column,
error_info.message);
}
}

@@ -11,7 +11,7 @@ use dom::bindings::guard::Guard;
use dom::bindings::utils::get_proto_or_iface_array;
use js::error::throw_type_error;
use js::glue::{RUST_SYMBOL_TO_JSID, UncheckedUnwrapObject};
use js::jsapi::{Class, ClassExtension, ClassSpec, GetGlobalForObjectCrossCompartment};
use js::jsapi::{Class, ClassOps, GetGlobalForObjectCrossCompartment};
use js::jsapi::{GetWellKnownSymbol, HandleObject, HandleValue, JSClass, JSContext};
use js::jsapi::{JSFunctionSpec, JSNative, JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE};
use js::jsapi::{JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_RESOLVING, JSPropertySpec};
@@ -101,6 +101,21 @@ unsafe extern "C" fn fun_to_string_hook(cx: *mut JSContext,
ret
}

const OBJECT_OPS: ObjectOps = ObjectOps {
lookupProperty: None,
defineProperty: None,
hasProperty: None,
getProperty: None,
setProperty: None,
getOwnPropertyDescriptor: None,
deleteProperty: None,
watch: None,
unwatch: None,
getElements: None,
enumerate: None,
funToString: Some(fun_to_string_hook),
};

/// The class of a non-callback interface object.
#[derive(Copy, Clone)]
pub struct NonCallbackInterfaceObjectClass {
@@ -117,58 +132,39 @@ pub struct NonCallbackInterfaceObjectClass {
unsafe impl Sync for NonCallbackInterfaceObjectClass {}

impl NonCallbackInterfaceObjectClass {
/// Create `ClassOps` for a `NonCallbackInterfaceObjectClass`.
pub const fn ops(constructor_behavior: InterfaceConstructorBehavior)
-> ClassOps {
ClassOps {
addProperty: None,
delProperty: None,
getProperty: None,
setProperty: None,
enumerate: None,
resolve: None,
mayResolve: None,
finalize: None,
call: constructor_behavior.call,
construct: constructor_behavior.construct,
hasInstance: Some(has_instance_hook),
trace: None,
}
}

/// Create a new `NonCallbackInterfaceObjectClass` structure.
pub const fn new(
constructor_behavior: InterfaceConstructorBehavior,
string_rep: &'static [u8],
proto_id: PrototypeList::ID,
proto_depth: u16)
-> NonCallbackInterfaceObjectClass {
pub const fn new(ops: &'static ClassOps,
string_rep: &'static [u8],
proto_id: PrototypeList::ID,
proto_depth: u16)
-> NonCallbackInterfaceObjectClass {
NonCallbackInterfaceObjectClass {
class: Class {
name: b"Function\0" as *const _ as *const libc::c_char,
flags: 0,
addProperty: None,
delProperty: None,
getProperty: None,
setProperty: None,
enumerate: None,
resolve: None,
mayResolve: None,
finalize: None,
call: constructor_behavior.call,
construct: constructor_behavior.construct,
hasInstance: Some(has_instance_hook),
trace: None,
spec: ClassSpec {
createConstructor_: None,
createPrototype_: None,
constructorFunctions_: ptr::null(),
constructorProperties_: ptr::null(),
prototypeFunctions_: ptr::null(),
prototypeProperties_: ptr::null(),
finishInit_: None,
flags: 0,
},
ext: ClassExtension {
isWrappedNative: false,
weakmapKeyDelegateOp: None,
objectMovedOp: None,
},
ops: ObjectOps {
lookupProperty: None,
defineProperty: None,
hasProperty: None,
getProperty: None,
setProperty: None,
getOwnPropertyDescriptor: None,
deleteProperty: None,
watch: None,
unwatch: None,
getElements: None,
enumerate: None,
funToString: Some(fun_to_string_hook),
}
cOps: ops,
spec: ptr::null(),
ext: ptr::null(),
oOps: &OBJECT_OPS,
},
proto_id: proto_id,
proto_depth: proto_depth,
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.