diff --git a/topaz/error.py b/topaz/error.py index 78ec23859..7347e9dbc 100644 --- a/topaz/error.py +++ b/topaz/error.py @@ -9,6 +9,22 @@ def __init__(self, w_value): def __str__(self): return "" % self.w_value + @jit.unroll_safe + def mark_not_escaped(self): + # This is supposed to be used when we catch a RubyError on the RPython + # level. It's a hack to not force frames if we have caught the exception + # and don't plan to re-raise it back into Ruby. TODO: find a better + # overall architecture to make the whole escaping logic go away (see + # also frame.py `unrollstack', interpreter.py `handle_ruby_error', and + # executioncontext.py `leave') + frame = self.w_value.frame + while frame is not None: + frame.escaped = False + if frame.backref.virtual: + frame = None + else: + frame = frame.backref() + def format_traceback(space, exc, top_filepath): w_bt = space.send(exc, "backtrace") diff --git a/topaz/objects/floatobject.py b/topaz/objects/floatobject.py index 10106fae6..6b359a62f 100644 --- a/topaz/objects/floatobject.py +++ b/topaz/objects/floatobject.py @@ -169,6 +169,7 @@ def method_eq(self, space, w_other): return W_NumericObject.retry_binop_coercing(space, self, w_other, "==") except RubyError as e: if isinstance(e.w_value, W_ArgumentError): + e.mark_not_escaped() return space.send(w_other, "==", [self]) else: raise @@ -186,6 +187,7 @@ def method_equalp(self, space, w_other): return W_NumericObject.retry_binop_coercing(space, self, w_other, "equal?") except RubyError as e: if isinstance(e.w_value, W_ArgumentError): + e.mark_not_escaped() return space.send(w_other, "equal?", [self]) else: raise diff --git a/topaz/objects/numericobject.py b/topaz/objects/numericobject.py index 33e48ba4d..883c1bb3f 100644 --- a/topaz/objects/numericobject.py +++ b/topaz/objects/numericobject.py @@ -21,6 +21,7 @@ def retry_binop_coercing(space, w_recv, w_arg, binop, raise_error=True): except RubyError as e: if not space.is_kind_of(e.w_value, space.w_StandardError): raise + e.mark_not_escaped() if raise_error: raise space.error(space.w_ArgumentError, "comparison of %s with %s failed" % ( diff --git a/topaz/objspace.py b/topaz/objspace.py index 93357da1a..b9c1e2f1d 100644 --- a/topaz/objspace.py +++ b/topaz/objspace.py @@ -766,6 +766,7 @@ def convert_type(self, w_obj, w_cls, method, raise_error=True, reraise_error=Fal except RubyError as e: if reraise_error: raise e + e.mark_not_escaped() if not raise_error: return self.w_nil src_cls_name = self.obj_to_s(self.getclass(w_obj))