aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings
diff options
context:
space:
mode:
authorAneesh Agrawal <aneeshusa@gmail.com>2015-04-10 01:49:14 -0400
committerAneesh Agrawal <aneeshusa@gmail.com>2015-04-10 01:49:14 -0400
commitf3aee90b06df39c220470881f1f90c12d8410c12 (patch)
treeafac0fb2ecb8d8676a2a1404944f5cd8f7283cee /components/script/dom/bindings
parentdb4609d722039e9477848c5e53e45ff214cb84c4 (diff)
downloadservo-f3aee90b06df39c220470881f1f90c12d8410c12.tar.gz
servo-f3aee90b06df39c220470881f1f90c12d8410c12.zip
Add Rust code for RangeErrors.
Implementation is alongside that of TypeErrors. Note: the jsapi codes are reused for our own purposes, namely distinguishing error_numbers in the get_error_message callback. See comments in components/script/dom/bindings/error.rs for details.
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r--components/script/dom/bindings/error.rs51
1 files changed, 41 insertions, 10 deletions
diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs
index 426bff64d95..181d02f0353 100644
--- a/components/script/dom/bindings/error.rs
+++ b/components/script/dom/bindings/error.rs
@@ -12,7 +12,7 @@ use util::str::DOMString;
use js::jsapi::{JSContext, JSBool, JSObject};
use js::jsapi::{JS_IsExceptionPending, JS_SetPendingException, JS_ReportPendingException};
-use js::jsapi::{JS_ReportErrorNumber, JSErrorFormatString, JSEXN_TYPEERR};
+use js::jsapi::{JS_ReportErrorNumber, JSErrorFormatString, JSEXN_TYPEERR, JSEXN_RANGEERR};
use js::jsapi::{JS_SaveFrameChain, JS_RestoreFrameChain};
use js::glue::{ReportError};
use js::rust::with_compartment;
@@ -59,6 +59,8 @@ pub enum Error {
/// TypeError JavaScript Error
Type(DOMString),
+ /// RangeError JavaScript Error
+ Range(DOMString),
/// A JavaScript exception is already pending.
JSFailed,
@@ -95,7 +97,12 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef,
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
throw_type_error(cx, &message);
return;
- }
+ },
+ Error::Range(message) => {
+ assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
+ throw_range_error(cx, &message);
+ return;
+ },
Error::JSFailed => {
assert!(unsafe { JS_IsExceptionPending(cx) } == 1);
return;
@@ -135,7 +142,7 @@ pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) -> JSBool {
return 0;
}
-/// Format string used to throw `TypeError`s.
+/// Format string used to throw javascript errors.
static ERROR_FORMAT_STRING_STRING: [libc::c_char; 4] = [
'{' as libc::c_char,
'0' as libc::c_char,
@@ -144,29 +151,53 @@ static ERROR_FORMAT_STRING_STRING: [libc::c_char; 4] = [
];
/// Format string struct used to throw `TypeError`s.
-static mut ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
+static mut TYPE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char,
argCount: 1,
exnType: JSEXN_TYPEERR as i16,
};
-/// Callback used to throw `TypeError`s.
+/// Format string struct used to throw `RangeError`s.
+static mut RANGE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
+ format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char,
+ argCount: 1,
+ exnType: JSEXN_RANGEERR as i16,
+};
+
+/// Callback used to throw javascript errors.
+/// See throw_js_error for info about error_number.
unsafe extern fn get_error_message(_user_ref: *mut libc::c_void,
_locale: *const libc::c_char,
error_number: libc::c_uint) -> *const JSErrorFormatString
{
- assert_eq!(error_number, 0);
- &ERROR_FORMAT_STRING as *const JSErrorFormatString
+ match error_number as i32 {
+ JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
+ JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
+ _ => panic!("Bad js error number given to get_error_message: {}", error_number)
+ }
}
-/// Throw a `TypeError` with the given message.
-pub fn throw_type_error(cx: *mut JSContext, error: &str) {
+/// Helper fn to throw a javascript error with the given message and number.
+/// Reuse the jsapi error codes to distinguish the error_number
+/// passed back to the get_error_message callback.
+/// c_uint is u32, so this cast is safe, as is casting to/from i32 from there.
+fn throw_js_error(cx: *mut JSContext, error: &str, error_number: u32) {
let error = CString::new(error).unwrap();
unsafe {
JS_ReportErrorNumber(cx,
Some(get_error_message as
unsafe extern "C" fn(*mut libc::c_void, *const libc::c_char,
libc::c_uint) -> *const JSErrorFormatString),
- ptr::null_mut(), 0, error.as_ptr());
+ ptr::null_mut(), error_number, error.as_ptr());
}
}
+
+/// Throw a `TypeError` with the given message.
+pub fn throw_type_error(cx: *mut JSContext, error: &str) {
+ throw_js_error(cx, error, JSEXN_TYPEERR as u32);
+}
+
+/// Throw a `RangeError` with the given message.
+pub fn throw_range_error(cx: *mut JSContext, error: &str) {
+ throw_js_error(cx, error, JSEXN_RANGEERR as u32);
+}