mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Use throw_type_error and throw_range_error from js.
This commit is contained in:
parent
ddaa1a1960
commit
acb24e80b8
5 changed files with 24 additions and 92 deletions
|
@ -888,21 +888,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
else:
|
else:
|
||||||
handleInvalidEnumValueCode = "return true;"
|
handleInvalidEnumValueCode = "return true;"
|
||||||
|
|
||||||
transmute = "mem::transmute(index)"
|
|
||||||
if isMember == 'Dictionary':
|
|
||||||
transmute = 'unsafe { ' + transmute + ' }'
|
|
||||||
|
|
||||||
template = (
|
template = (
|
||||||
"match find_enum_string_index(cx, ${val}, %(values)s) {\n"
|
"match find_enum_string_index(cx, ${val}, %(values)s) {\n"
|
||||||
" Err(_) => { %(exceptionCode)s },\n"
|
" Err(_) => { %(exceptionCode)s },\n"
|
||||||
" Ok(None) => { %(handleInvalidEnumValueCode)s },\n"
|
" Ok(None) => { %(handleInvalidEnumValueCode)s },\n"
|
||||||
" Ok(Some(index)) => {\n"
|
" Ok(Some(index)) => {\n"
|
||||||
" //XXXjdm need some range checks up in here.\n"
|
" //XXXjdm need some range checks up in here.\n"
|
||||||
" %(transmute)s\n"
|
" mem::transmute(index)\n"
|
||||||
" },\n"
|
" },\n"
|
||||||
"}" % {"values": enum + "Values::strings",
|
"}" % {"values": enum + "Values::strings",
|
||||||
"exceptionCode": exceptionCode,
|
"exceptionCode": exceptionCode,
|
||||||
"transmute": transmute,
|
|
||||||
"handleInvalidEnumValueCode": handleInvalidEnumValueCode})
|
"handleInvalidEnumValueCode": handleInvalidEnumValueCode})
|
||||||
|
|
||||||
if defaultValue is not None:
|
if defaultValue is not None:
|
||||||
|
@ -3649,7 +3644,7 @@ class CGUnionConversionStruct(CGThing):
|
||||||
names.append(name)
|
names.append(name)
|
||||||
|
|
||||||
conversions.append(CGGeneric(
|
conversions.append(CGGeneric(
|
||||||
"throw_not_in_union(cx, \"%s\");\n"
|
"unsafe { throw_not_in_union(cx, \"%s\"); }\n"
|
||||||
"Err(())" % ", ".join(names)))
|
"Err(())" % ", ".join(names)))
|
||||||
method = CGWrapper(
|
method = CGWrapper(
|
||||||
CGIndenter(CGList(conversions, "\n\n")),
|
CGIndenter(CGList(conversions, "\n\n")),
|
||||||
|
@ -4952,10 +4947,10 @@ class CGDictionary(CGThing):
|
||||||
|
|
||||||
return string.Template(
|
return string.Template(
|
||||||
"impl ${selfName} {\n"
|
"impl ${selfName} {\n"
|
||||||
" pub fn empty(cx: *mut JSContext) -> ${selfName} {\n"
|
" pub unsafe fn empty(cx: *mut JSContext) -> ${selfName} {\n"
|
||||||
" ${selfName}::new(cx, HandleValue::null()).unwrap()\n"
|
" ${selfName}::new(cx, HandleValue::null()).unwrap()\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" pub fn new(cx: *mut JSContext, val: HandleValue) -> Result<${selfName}, ()> {\n"
|
" pub unsafe fn new(cx: *mut JSContext, val: HandleValue) -> Result<${selfName}, ()> {\n"
|
||||||
" let object = if val.get().is_null_or_undefined() {\n"
|
" let object = if val.get().is_null_or_undefined() {\n"
|
||||||
" RootedObject::new(cx, ptr::null_mut())\n"
|
" RootedObject::new(cx, ptr::null_mut())\n"
|
||||||
" } else if val.get().is_object() {\n"
|
" } else if val.get().is_object() {\n"
|
||||||
|
@ -5159,6 +5154,7 @@ class CGBindingRoot(CGThing):
|
||||||
'js::{JSCLASS_RESERVED_SLOTS_MASK}',
|
'js::{JSCLASS_RESERVED_SLOTS_MASK}',
|
||||||
'js::{JSPROP_ENUMERATE, JSPROP_SHARED}',
|
'js::{JSPROP_ENUMERATE, JSPROP_SHARED}',
|
||||||
'js::{JSITER_OWNONLY, JSITER_HIDDEN, JSITER_SYMBOLS}',
|
'js::{JSITER_OWNONLY, JSITER_HIDDEN, JSITER_SYMBOLS}',
|
||||||
|
'js::error::throw_type_error',
|
||||||
'js::jsapi::{JS_CallFunctionValue, JS_GetClass, JS_GetGlobalForObject}',
|
'js::jsapi::{JS_CallFunctionValue, JS_GetClass, JS_GetGlobalForObject}',
|
||||||
'js::jsapi::{JS_GetObjectPrototype, JS_GetProperty, JS_GetPropertyById}',
|
'js::jsapi::{JS_GetObjectPrototype, JS_GetProperty, JS_GetPropertyById}',
|
||||||
'js::jsapi::{JS_GetPropertyDescriptorById, JS_GetReservedSlot}',
|
'js::jsapi::{JS_GetPropertyDescriptorById, JS_GetReservedSlot}',
|
||||||
|
@ -5222,7 +5218,6 @@ class CGBindingRoot(CGThing):
|
||||||
'dom::bindings::error::{Fallible, Error, ErrorResult}',
|
'dom::bindings::error::{Fallible, Error, ErrorResult}',
|
||||||
'dom::bindings::error::Error::JSFailed',
|
'dom::bindings::error::Error::JSFailed',
|
||||||
'dom::bindings::error::throw_dom_exception',
|
'dom::bindings::error::throw_dom_exception',
|
||||||
'dom::bindings::error::throw_type_error',
|
|
||||||
'dom::bindings::proxyhandler',
|
'dom::bindings::proxyhandler',
|
||||||
'dom::bindings::proxyhandler::{fill_property_descriptor, get_expando_object}',
|
'dom::bindings::proxyhandler::{fill_property_descriptor, get_expando_object}',
|
||||||
'dom::bindings::proxyhandler::{get_property_descriptor}',
|
'dom::bindings::proxyhandler::{get_property_descriptor}',
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
//! | sequences | `Vec<T>` |
|
//! | sequences | `Vec<T>` |
|
||||||
//! | union types | `T` |
|
//! | union types | `T` |
|
||||||
|
|
||||||
use dom::bindings::error::throw_type_error;
|
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
|
@ -40,6 +39,7 @@ use dom::bindings::reflector::{Reflectable, Reflector};
|
||||||
use dom::bindings::str::{ByteString, USVString};
|
use dom::bindings::str::{ByteString, USVString};
|
||||||
use dom::bindings::utils::DOMClass;
|
use dom::bindings::utils::DOMClass;
|
||||||
use js;
|
use js;
|
||||||
|
use js::error::throw_type_error;
|
||||||
use js::glue::{GetProxyPrivate, IsWrapper, RUST_JS_NumberValue};
|
use js::glue::{GetProxyPrivate, IsWrapper, RUST_JS_NumberValue};
|
||||||
use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject};
|
use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject};
|
||||||
use js::jsapi::{HandleId, HandleObject, HandleValue, JS_GetClass};
|
use js::jsapi::{HandleId, HandleObject, HandleValue, JS_GetClass};
|
||||||
|
@ -146,7 +146,7 @@ fn enforce_range<D>(cx: *mut JSContext, d: f64) -> Result<D, ()>
|
||||||
f64: As<D>
|
f64: As<D>
|
||||||
{
|
{
|
||||||
if d.is_infinite() {
|
if d.is_infinite() {
|
||||||
throw_type_error(cx, "value out of range in an EnforceRange argument");
|
unsafe { throw_type_error(cx, "value out of range in an EnforceRange argument") };
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ fn enforce_range<D>(cx: *mut JSContext, d: f64) -> Result<D, ()>
|
||||||
if D::min_value().cast() <= rounded && rounded <= D::max_value().cast() {
|
if D::min_value().cast() <= rounded && rounded <= D::max_value().cast() {
|
||||||
Ok(rounded.cast())
|
Ok(rounded.cast())
|
||||||
} else {
|
} else {
|
||||||
throw_type_error(cx, "value out of range in an EnforceRange argument");
|
unsafe { throw_type_error(cx, "value out of range in an EnforceRange argument") };
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -408,7 +408,7 @@ impl<T: Float + FromJSValConvertible<Config=()>> FromJSValConvertible for Finite
|
||||||
match Finite::new(result) {
|
match Finite::new(result) {
|
||||||
Some(v) => Ok(v),
|
Some(v) => Ok(v),
|
||||||
None => {
|
None => {
|
||||||
throw_type_error(cx, "this argument is not a finite floating-point value");
|
unsafe { throw_type_error(cx, "this argument is not a finite floating-point value") };
|
||||||
Err(())
|
Err(())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,12 @@ use dom::bindings::codegen::PrototypeList::proto_id_to_name;
|
||||||
use dom::bindings::conversions::ToJSValConvertible;
|
use dom::bindings::conversions::ToJSValConvertible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::domexception::{DOMErrorName, DOMException};
|
use dom::domexception::{DOMErrorName, DOMException};
|
||||||
|
use js::error::{throw_range_error, throw_type_error};
|
||||||
use js::jsapi::JSAutoCompartment;
|
use js::jsapi::JSAutoCompartment;
|
||||||
use js::jsapi::{JSContext, JSObject, RootedValue};
|
use js::jsapi::{JSContext, JSObject, RootedValue};
|
||||||
use js::jsapi::{JSErrorFormatString, JSExnType, JS_ReportErrorNumber};
|
|
||||||
use js::jsapi::{JS_IsExceptionPending, JS_ReportPendingException, JS_SetPendingException};
|
use js::jsapi::{JS_IsExceptionPending, JS_ReportPendingException, JS_SetPendingException};
|
||||||
use js::jsapi::{JS_RestoreFrameChain, JS_SaveFrameChain};
|
use js::jsapi::{JS_RestoreFrameChain, JS_SaveFrameChain};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use libc;
|
|
||||||
use std::ffi::CString;
|
|
||||||
use std::{mem, ptr};
|
|
||||||
use util::mem::HeapSizeOf;
|
use util::mem::HeapSizeOf;
|
||||||
|
|
||||||
/// DOM exceptions that can be thrown by a native DOM method.
|
/// DOM exceptions that can be thrown by a native DOM method.
|
||||||
|
@ -80,8 +77,7 @@ pub type Fallible<T> = Result<T, Error>;
|
||||||
pub type ErrorResult = Fallible<()>;
|
pub type ErrorResult = Fallible<()>;
|
||||||
|
|
||||||
/// Set a pending exception for the given `result` on `cx`.
|
/// Set a pending exception for the given `result` on `cx`.
|
||||||
pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef,
|
pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, result: Error) {
|
||||||
result: Error) {
|
|
||||||
let code = match result {
|
let code = match result {
|
||||||
Error::IndexSize => DOMErrorName::IndexSizeError,
|
Error::IndexSize => DOMErrorName::IndexSizeError,
|
||||||
Error::NotFound => DOMErrorName::NotFoundError,
|
Error::NotFound => DOMErrorName::NotFoundError,
|
||||||
|
@ -104,28 +100,26 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef,
|
||||||
Error::QuotaExceeded => DOMErrorName::QuotaExceededError,
|
Error::QuotaExceeded => DOMErrorName::QuotaExceededError,
|
||||||
Error::TypeMismatch => DOMErrorName::TypeMismatchError,
|
Error::TypeMismatch => DOMErrorName::TypeMismatchError,
|
||||||
Error::Type(message) => {
|
Error::Type(message) => {
|
||||||
assert!(unsafe { !JS_IsExceptionPending(cx) });
|
assert!(!JS_IsExceptionPending(cx));
|
||||||
throw_type_error(cx, &message);
|
throw_type_error(cx, &message);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
Error::Range(message) => {
|
Error::Range(message) => {
|
||||||
assert!(unsafe { !JS_IsExceptionPending(cx) });
|
assert!(!JS_IsExceptionPending(cx));
|
||||||
throw_range_error(cx, &message);
|
throw_range_error(cx, &message);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
Error::JSFailed => {
|
Error::JSFailed => {
|
||||||
assert!(unsafe { JS_IsExceptionPending(cx) });
|
assert!(JS_IsExceptionPending(cx));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(unsafe { !JS_IsExceptionPending(cx) });
|
assert!(!JS_IsExceptionPending(cx));
|
||||||
let exception = DOMException::new(global, code);
|
let exception = DOMException::new(global, code);
|
||||||
let mut thrown = RootedValue::new(cx, UndefinedValue());
|
let mut thrown = RootedValue::new(cx, UndefinedValue());
|
||||||
exception.to_jsval(cx, thrown.handle_mut());
|
exception.to_jsval(cx, thrown.handle_mut());
|
||||||
unsafe {
|
JS_SetPendingException(cx, thrown.handle());
|
||||||
JS_SetPendingException(cx, thrown.handle());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Report a pending exception, thereby clearing it.
|
/// Report a pending exception, thereby clearing it.
|
||||||
|
@ -146,76 +140,17 @@ pub fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) {
|
||||||
|
|
||||||
/// Throw an exception to signal that a `JSVal` can not be converted to any of
|
/// Throw an exception to signal that a `JSVal` can not be converted to any of
|
||||||
/// the types in an IDL union type.
|
/// the types in an IDL union type.
|
||||||
pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) {
|
pub unsafe fn throw_not_in_union(cx: *mut JSContext, names: &'static str) {
|
||||||
assert!(unsafe { !JS_IsExceptionPending(cx) });
|
assert!(!JS_IsExceptionPending(cx));
|
||||||
let error = format!("argument could not be converted to any of: {}", names);
|
let error = format!("argument could not be converted to any of: {}", names);
|
||||||
throw_type_error(cx, &error);
|
throw_type_error(cx, &error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Throw an exception to signal that a `JSObject` can not be converted to a
|
/// Throw an exception to signal that a `JSObject` can not be converted to a
|
||||||
/// given DOM type.
|
/// given DOM type.
|
||||||
pub fn throw_invalid_this(cx: *mut JSContext, proto_id: u16) {
|
pub unsafe fn throw_invalid_this(cx: *mut JSContext, proto_id: u16) {
|
||||||
debug_assert!(unsafe { !JS_IsExceptionPending(cx) });
|
debug_assert!(!JS_IsExceptionPending(cx));
|
||||||
let error = format!("\"this\" object does not implement interface {}.",
|
let error = format!("\"this\" object does not implement interface {}.",
|
||||||
proto_id_to_name(proto_id));
|
proto_id_to_name(proto_id));
|
||||||
throw_type_error(cx, &error);
|
throw_type_error(cx, &error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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,
|
|
||||||
'}' as libc::c_char,
|
|
||||||
0 as libc::c_char,
|
|
||||||
];
|
|
||||||
|
|
||||||
/// Format string struct used to throw `TypeError`s.
|
|
||||||
static mut TYPE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
|
|
||||||
format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char,
|
|
||||||
argCount: 1,
|
|
||||||
exnType: JSExnType::JSEXN_TYPEERR as i16,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// 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: JSExnType::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,
|
|
||||||
error_number: libc::c_uint)
|
|
||||||
-> *const JSErrorFormatString
|
|
||||||
{
|
|
||||||
let num: JSExnType = mem::transmute(error_number);
|
|
||||||
match num {
|
|
||||||
JSExnType::JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
|
|
||||||
JSExnType::JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
|
|
||||||
_ => panic!("Bad js error number given to get_error_message: {}", error_number)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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),
|
|
||||||
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, JSExnType::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, JSExnType::JSEXN_RANGEERR as u32);
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,12 +8,13 @@ use dom::bindings::codegen::PrototypeList;
|
||||||
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
||||||
use dom::bindings::conversions::{DOM_OBJECT_SLOT, is_dom_class, jsstring_to_str};
|
use dom::bindings::conversions::{DOM_OBJECT_SLOT, is_dom_class, jsstring_to_str};
|
||||||
use dom::bindings::conversions::{private_from_proto_check, root_from_handleobject};
|
use dom::bindings::conversions::{private_from_proto_check, root_from_handleobject};
|
||||||
use dom::bindings::error::{throw_invalid_this, throw_type_error};
|
use dom::bindings::error::throw_invalid_this;
|
||||||
use dom::bindings::inheritance::TopTypeId;
|
use dom::bindings::inheritance::TopTypeId;
|
||||||
use dom::bindings::trace::trace_object;
|
use dom::bindings::trace::trace_object;
|
||||||
use dom::browsercontext;
|
use dom::browsercontext;
|
||||||
use dom::window;
|
use dom::window;
|
||||||
use js;
|
use js;
|
||||||
|
use js::error::throw_type_error;
|
||||||
use js::glue::{CallJitGetterOp, CallJitMethodOp, CallJitSetterOp, IsWrapper};
|
use js::glue::{CallJitGetterOp, CallJitMethodOp, CallJitSetterOp, IsWrapper};
|
||||||
use js::glue::{GetCrossCompartmentWrapper, WrapperNew};
|
use js::glue::{GetCrossCompartmentWrapper, WrapperNew};
|
||||||
use js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO, RUST_JSID_IS_INT};
|
use js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO, RUST_JSID_IS_INT};
|
||||||
|
|
|
@ -157,6 +157,7 @@ impl HTMLCanvasElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub fn get_or_init_webgl_context(&self,
|
pub fn get_or_init_webgl_context(&self,
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
@ -165,7 +166,7 @@ impl HTMLCanvasElement {
|
||||||
let size = self.get_size();
|
let size = self.get_size();
|
||||||
|
|
||||||
let attrs = if let Some(webgl_attributes) = attrs {
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
if let Ok(ref attrs) = unsafe { WebGLContextAttributes::new(cx, webgl_attributes) } {
|
||||||
From::from(attrs)
|
From::from(attrs)
|
||||||
} else {
|
} else {
|
||||||
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue