aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen/CodegenRust.py
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2016-06-20 13:25:42 -0400
committerJosh Matthews <josh@joshmatthews.net>2016-06-22 09:35:19 -0400
commitb8853554dbe595dedf3d68532af66bbf0c329b42 (patch)
tree7a31274c6141630bd876a44972b799d6b56cb2d0 /components/script/dom/bindings/codegen/CodegenRust.py
parenta74ce64539e29cfef96d03e87490c9454b61f3e1 (diff)
downloadservo-b8853554dbe595dedf3d68532af66bbf0c329b42.tar.gz
servo-b8853554dbe595dedf3d68532af66bbf0c329b42.zip
Wrap executions of Rust code called from JS in catch_unwind. Propagate the interrupted panic to the origin of the JS execution via TLS before resuming. Fix #6462.
Diffstat (limited to 'components/script/dom/bindings/codegen/CodegenRust.py')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py31
1 files changed, 25 insertions, 6 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 057246f05aa..b5b5b9f2b9b 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -2145,7 +2145,7 @@ class CGAbstractMethod(CGThing):
"""
def __init__(self, descriptor, name, returnType, args, inline=False,
alwaysInline=False, extern=False, pub=False, templateArgs=None,
- unsafe=False, docs=None):
+ unsafe=False, docs=None, doesNotPanic=False):
CGThing.__init__(self)
self.descriptor = descriptor
self.name = name
@@ -2157,6 +2157,7 @@ class CGAbstractMethod(CGThing):
self.pub = pub
self.unsafe = unsafe
self.docs = docs
+ self.catchPanic = self.extern and not doesNotPanic
def _argstring(self):
return ', '.join([a.declare() for a in self.args])
@@ -2199,6 +2200,19 @@ class CGAbstractMethod(CGThing):
if self.unsafe and not self.extern:
body = CGWrapper(CGIndenter(body), pre="unsafe {\n", post="\n}")
+ if self.catchPanic:
+ body = CGWrapper(CGIndenter(body),
+ pre="let result = panic::catch_unwind(AssertUnwindSafe(|| {\n",
+ post=("""}));
+match result {
+ Ok(result) => result,
+ Err(error) => {
+ store_panic_result(error);
+ return%s;
+ }
+}
+""" % ("" if self.returnType == "void" else " false")))
+
return CGWrapper(CGIndenter(body),
pre=self.definition_prologue(),
post=self.definition_epilogue()).define()
@@ -2447,9 +2461,9 @@ class CGAbstractExternMethod(CGAbstractMethod):
Abstract base class for codegen of implementation-only (no
declaration) static methods.
"""
- def __init__(self, descriptor, name, returnType, args):
+ def __init__(self, descriptor, name, returnType, args, doesNotPanic=False):
CGAbstractMethod.__init__(self, descriptor, name, returnType, args,
- inline=False, extern=True)
+ inline=False, extern=True, doesNotPanic=doesNotPanic)
class PropertyArrays():
@@ -4830,7 +4844,7 @@ return true;""" % (getIndexedOrExpando, getNamed)
class CGDOMJSProxyHandler_className(CGAbstractExternMethod):
def __init__(self, descriptor):
args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', '_proxy')]
- CGAbstractExternMethod.__init__(self, descriptor, "className", "*const i8", args)
+ CGAbstractExternMethod.__init__(self, descriptor, "className", "*const i8", args, doesNotPanic=True)
self.descriptor = descriptor
def getBody(self):
@@ -4845,7 +4859,7 @@ class CGAbstractClassHook(CGAbstractExternMethod):
Meant for implementing JSClass hooks, like Finalize or Trace. Does very raw
'this' unwrapping as it assumes that the unwrapped type is always known.
"""
- def __init__(self, descriptor, name, returnType, args):
+ def __init__(self, descriptor, name, returnType, args, doesNotPanic=False):
CGAbstractExternMethod.__init__(self, descriptor, name, returnType,
args)
@@ -4905,7 +4919,7 @@ class CGClassTraceHook(CGAbstractClassHook):
def __init__(self, descriptor):
args = [Argument('*mut JSTracer', 'trc'), Argument('*mut JSObject', 'obj')]
CGAbstractClassHook.__init__(self, descriptor, TRACE_HOOK_NAME, 'void',
- args)
+ args, doesNotPanic=True)
self.traceGlobal = descriptor.isGlobal()
def generate_code(self):
@@ -5597,11 +5611,13 @@ class CGBindingRoot(CGThing):
'mem::heap_size_of_raw_self_and_children',
'libc',
'util::prefs',
+ 'script_runtime::{store_panic_result, maybe_take_panic_result}',
'std::borrow::ToOwned',
'std::cmp',
'std::mem',
'std::num',
'std::os',
+ 'std::panic::{self, AssertUnwindSafe}',
'std::ptr',
'std::str',
'std::rc',
@@ -6088,6 +6104,9 @@ class CallbackMethod(CallbackMember):
" length_: ${argc} as ::libc::size_t,\n"
" elements_: ${argv}\n"
" }, rval.handle_mut());\n"
+ "if let Some(error) = maybe_take_panic_result() {\n"
+ " panic::resume_unwind(error);\n"
+ "}\n"
"if !ok {\n"
" return Err(JSFailed);\n"
"}\n").substitute(replacements)