зеркало из https://github.com/mozilla/gecko-dev.git
Source-Repo: https://github.com/servo/servo Source-Revision: 39e3c64ead997b3a8c6be6e188aad27fcbe3220b
This commit is contained in:
Родитель
5788f29d55
Коммит
e642799ed4
|
@ -2129,19 +2129,21 @@ class CGCallGenerator(CGThing):
|
||||||
A class to generate an actual call to a C++ object. Assumes that the C++
|
A class to generate an actual call to a C++ object. Assumes that the C++
|
||||||
object is stored in a variable whose name is given by the |object| argument.
|
object is stored in a variable whose name is given by the |object| argument.
|
||||||
|
|
||||||
errorReport should be a CGThing for an error report or None if no
|
errorResult should be a string for the value to return in case of an
|
||||||
error reporting is needed.
|
exception from the native code, or None if no error reporting is needed.
|
||||||
"""
|
"""
|
||||||
def __init__(self, errorReport, arguments, argsPre, returnType,
|
def __init__(self, errorResult, arguments, argsPre, returnType,
|
||||||
extendedAttributes, descriptorProvider, nativeMethodName,
|
extendedAttributes, descriptorProvider, nativeMethodName,
|
||||||
static, object="this"):
|
static, object="this"):
|
||||||
CGThing.__init__(self)
|
CGThing.__init__(self)
|
||||||
|
|
||||||
assert errorReport is None or isinstance(errorReport, CGThing)
|
assert errorResult is None or isinstance(errorResult, str)
|
||||||
|
|
||||||
isFallible = errorReport is not None
|
isFallible = errorResult is not None
|
||||||
|
|
||||||
result = getRetvalDeclarationForType(returnType, descriptorProvider)
|
result = getRetvalDeclarationForType(returnType, descriptorProvider)
|
||||||
|
if isFallible:
|
||||||
|
result = CGWrapper(result, pre="Result<", post=", Error>")
|
||||||
|
|
||||||
args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
|
args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
|
||||||
for (a, name) in arguments:
|
for (a, name) in arguments:
|
||||||
|
@ -2172,26 +2174,29 @@ class CGCallGenerator(CGThing):
|
||||||
call = CGWrapper(call, pre="(*%s)." % object)
|
call = CGWrapper(call, pre="(*%s)." % object)
|
||||||
call = CGList([call, CGWrapper(args, pre="(", post=");")])
|
call = CGList([call, CGWrapper(args, pre="(", post=");")])
|
||||||
|
|
||||||
if isFallible:
|
self.cgRoot.append(CGList([
|
||||||
self.cgRoot.prepend(CGWrapper(result,
|
CGGeneric("let result: "),
|
||||||
pre="let result_fallible: Result<", post=",Error>;"))
|
result,
|
||||||
|
CGGeneric(" = "),
|
||||||
result = CGWrapper(result, pre="let result: ", post=";")
|
call,
|
||||||
self.cgRoot.prepend(result)
|
CGGeneric(";"),
|
||||||
|
]))
|
||||||
|
|
||||||
if isFallible:
|
if isFallible:
|
||||||
call = CGWrapper(call, pre="result_fallible = ")
|
if static:
|
||||||
else:
|
glob = ""
|
||||||
call = CGWrapper(call, pre="result = ")
|
else:
|
||||||
|
glob = " let global = global_object_for_js_object(this.reflector().get_jsobject()).root();\n"
|
||||||
|
|
||||||
call = CGWrapper(call)
|
self.cgRoot.append(CGGeneric(
|
||||||
self.cgRoot.append(call)
|
"let result = match result {\n"
|
||||||
|
" Ok(result) => result,\n"
|
||||||
if isFallible:
|
" Err(e) => {\n"
|
||||||
self.cgRoot.append(CGGeneric("if result_fallible.is_err() {"))
|
"%s"
|
||||||
self.cgRoot.append(CGIndenter(errorReport))
|
" throw_dom_exception(cx, &*global, e);\n"
|
||||||
self.cgRoot.append(CGGeneric("}"))
|
" return%s;"
|
||||||
self.cgRoot.append(CGGeneric("result = result_fallible.unwrap();"))
|
" },\n"
|
||||||
|
"};\n" % (glob, errorResult)))
|
||||||
|
|
||||||
if typeRetValNeedsRooting(returnType):
|
if typeRetValNeedsRooting(returnType):
|
||||||
self.cgRoot.append(CGGeneric("let result = result.root();"))
|
self.cgRoot.append(CGGeneric("let result = result.root();"))
|
||||||
|
@ -2250,7 +2255,7 @@ class CGPerSignatureCall(CGThing):
|
||||||
i in range(argConversionStartsAt, self.argCount)])
|
i in range(argConversionStartsAt, self.argCount)])
|
||||||
|
|
||||||
cgThings.append(CGCallGenerator(
|
cgThings.append(CGCallGenerator(
|
||||||
self.getErrorReport() if self.isFallible() else None,
|
' false as JSBool' if self.isFallible() else None,
|
||||||
self.getArguments(), self.argsPre, returnType,
|
self.getArguments(), self.argsPre, returnType,
|
||||||
self.extendedAttributes, descriptor, nativeMethodName,
|
self.extendedAttributes, descriptor, nativeMethodName,
|
||||||
static))
|
static))
|
||||||
|
@ -2276,12 +2281,6 @@ class CGPerSignatureCall(CGThing):
|
||||||
def wrap_return_value(self):
|
def wrap_return_value(self):
|
||||||
return wrapForType('*vp')
|
return wrapForType('*vp')
|
||||||
|
|
||||||
def getErrorReport(self):
|
|
||||||
return CGGeneric(
|
|
||||||
'return throw_method_failed_with_details(cx, result_fallible, "%s", "%s");' %
|
|
||||||
(self.descriptor.interface.identifier.name,
|
|
||||||
self.idlNode.identifier.name))
|
|
||||||
|
|
||||||
def define(self):
|
def define(self):
|
||||||
return (self.cgRoot.define() + "\n" + self.wrap_return_value())
|
return (self.cgRoot.define() + "\n" + self.wrap_return_value())
|
||||||
|
|
||||||
|
@ -4302,7 +4301,7 @@ class CGBindingRoot(CGThing):
|
||||||
'dom::bindings::codegen::BindingDeclarations::*',
|
'dom::bindings::codegen::BindingDeclarations::*',
|
||||||
'dom::bindings::codegen::UnionTypes::*',
|
'dom::bindings::codegen::UnionTypes::*',
|
||||||
'dom::bindings::error::{FailureUnknown, Fallible, Error, ErrorResult}',
|
'dom::bindings::error::{FailureUnknown, Fallible, Error, ErrorResult}',
|
||||||
'dom::bindings::error::{throw_method_failed_with_details}',
|
'dom::bindings::error::throw_dom_exception',
|
||||||
'dom::bindings::error::throw_type_error',
|
'dom::bindings::error::throw_type_error',
|
||||||
'dom::bindings::proxyhandler',
|
'dom::bindings::proxyhandler',
|
||||||
'dom::bindings::proxyhandler::{_obj_toString, defineProperty}',
|
'dom::bindings::proxyhandler::{_obj_toString, defineProperty}',
|
||||||
|
|
|
@ -2,8 +2,13 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use dom::bindings::conversions::ToJSValConvertible;
|
||||||
|
use dom::bindings::js::JSRef;
|
||||||
|
use dom::domexception::DOMException;
|
||||||
|
use dom::window::Window;
|
||||||
|
|
||||||
use js::jsapi::{JSContext, JSBool};
|
use js::jsapi::{JSContext, JSBool};
|
||||||
use js::jsapi::{JS_IsExceptionPending};
|
use js::jsapi::{JS_IsExceptionPending, JS_SetPendingException};
|
||||||
use js::jsapi::{JS_ReportErrorNumber, JSErrorFormatString, JSEXN_TYPEERR};
|
use js::jsapi::{JS_ReportErrorNumber, JSErrorFormatString, JSEXN_TYPEERR};
|
||||||
use js::glue::{ReportError};
|
use js::glue::{ReportError};
|
||||||
|
|
||||||
|
@ -29,17 +34,14 @@ pub type Fallible<T> = Result<T, Error>;
|
||||||
|
|
||||||
pub type ErrorResult = Fallible<()>;
|
pub type ErrorResult = Fallible<()>;
|
||||||
|
|
||||||
pub fn throw_method_failed_with_details<T>(cx: *mut JSContext,
|
pub fn throw_dom_exception(cx: *mut JSContext, global: &JSRef<Window>,
|
||||||
result: Result<T, Error>,
|
result: Error) {
|
||||||
interface: &'static str,
|
|
||||||
member: &'static str) -> JSBool {
|
|
||||||
assert!(result.is_err());
|
|
||||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
||||||
let message = format!("Method failed: {}.{}", interface, member);
|
let exception = DOMException::new_from_error(global, result).root();
|
||||||
message.with_c_str(|string| {
|
let thrown = exception.to_jsval(cx);
|
||||||
unsafe { ReportError(cx, string) };
|
unsafe {
|
||||||
});
|
JS_SetPendingException(cx, thrown);
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) -> JSBool {
|
pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) -> JSBool {
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::BindingDeclarations::DOMExceptionBinding;
|
use dom::bindings::codegen::BindingDeclarations::DOMExceptionBinding;
|
||||||
use dom::bindings::codegen::BindingDeclarations::DOMExceptionBinding::DOMExceptionConstants;
|
use dom::bindings::codegen::BindingDeclarations::DOMExceptionBinding::DOMExceptionConstants;
|
||||||
|
use dom::bindings::error;
|
||||||
|
use dom::bindings::error::Error;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::{JSRef, Temporary};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
@ -35,6 +37,24 @@ pub enum DOMErrorName {
|
||||||
EncodingError
|
EncodingError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DOMErrorName {
|
||||||
|
fn from_error(error: Error) -> DOMErrorName {
|
||||||
|
match error {
|
||||||
|
error::IndexSize => IndexSizeError,
|
||||||
|
error::NotFound => NotFoundError,
|
||||||
|
error::HierarchyRequest => HierarchyRequestError,
|
||||||
|
error::InvalidCharacter => InvalidCharacterError,
|
||||||
|
error::NotSupported => NotSupportedError,
|
||||||
|
error::InvalidState => InvalidStateError,
|
||||||
|
error::NamespaceError => NamespaceError,
|
||||||
|
error::Syntax => SyntaxError,
|
||||||
|
error::Security => SecurityError,
|
||||||
|
error::Network => NetworkError,
|
||||||
|
error::FailureUnknown => fail!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
pub struct DOMException {
|
pub struct DOMException {
|
||||||
pub code: DOMErrorName,
|
pub code: DOMErrorName,
|
||||||
|
@ -52,6 +72,10 @@ impl DOMException {
|
||||||
pub fn new(window: &JSRef<Window>, code: DOMErrorName) -> Temporary<DOMException> {
|
pub fn new(window: &JSRef<Window>, code: DOMErrorName) -> Temporary<DOMException> {
|
||||||
reflect_dom_object(box DOMException::new_inherited(code), window, DOMExceptionBinding::Wrap)
|
reflect_dom_object(box DOMException::new_inherited(code), window, DOMExceptionBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_from_error(window: &JSRef<Window>, code: Error) -> Temporary<DOMException> {
|
||||||
|
DOMException::new(window, DOMErrorName::from_error(code))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Reflectable for DOMException {
|
impl Reflectable for DOMException {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче