mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Update SpiderMonkey to m-c bcf4ff0c3eef.
This currently breaks Servo on Android, because there are a number of interdependent changes that cannot easily land serially in a way that keeps it working throughout. We expect to fix this in the near future.
This commit is contained in:
parent
a0c502261d
commit
89efccc426
7 changed files with 224 additions and 115 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue