|
@@ -582,6 +582,13 @@ class ModelverseKernel(object):
|
|
|
_, _ = yield [("CD", [user_root, "frame", prev_frame]),
|
|
|
("DN", [user_frame]),
|
|
|
]
|
|
|
+
|
|
|
+ # If the callee's frame is marked with the '__primitive_return' key, then
|
|
|
+ # we need to throw an exception instead of just finishing here. This design
|
|
|
+ # gives us O(1) state reads per jit-interpreter transition.
|
|
|
+ exception_return, = yield [("RD", [user_frame, primitive_functions.PRIMITIVE_RETURN_KEY])]
|
|
|
+ if exception_return is not None:
|
|
|
+ raise primitive_functions.PrimitiveFinished(None)
|
|
|
else:
|
|
|
evalstack, evalstack_link, ip_link, new_evalstack, evalstack_phase = \
|
|
|
yield [("RD", [user_frame, "evalstack"]),
|
|
@@ -601,17 +608,27 @@ class ModelverseKernel(object):
|
|
|
]
|
|
|
|
|
|
def return_eval(self, user_root):
|
|
|
- user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
- prev_frame, = yield [("RD", [user_frame, "prev"])]
|
|
|
- returnvalue, old_returnvalue_link = \
|
|
|
- yield [("RD", [user_frame, "returnvalue"]),
|
|
|
- ("RDE", [prev_frame, "returnvalue"]),
|
|
|
- ]
|
|
|
- _, _, _, _ = yield [("CD", [user_root, "frame", prev_frame]),
|
|
|
- ("CD", [prev_frame, "returnvalue", returnvalue]),
|
|
|
- ("DE", [old_returnvalue_link]),
|
|
|
- ("DN", [user_frame]),
|
|
|
- ]
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ prev_frame, exception_return, returnvalue = yield [
|
|
|
+ ("RD", [user_frame, "prev"]),
|
|
|
+ ("RD", [user_frame, primitive_functions.PRIMITIVE_RETURN_KEY]),
|
|
|
+ ("RD", [user_frame, "returnvalue"])]
|
|
|
+
|
|
|
+ # If the callee's frame is marked with the '__primitive_return' key, then
|
|
|
+ # we need to throw an exception instead of just finishing here. This design
|
|
|
+ # gives us O(1) state reads per jit-interpreter transition.
|
|
|
+ if exception_return is not None:
|
|
|
+ yield [
|
|
|
+ ("CD", [user_root, "frame", prev_frame]),
|
|
|
+ ("DN", [user_frame])]
|
|
|
+ raise primitive_functions.PrimitiveFinished(returnvalue)
|
|
|
+ else:
|
|
|
+ old_returnvalue_link, = yield [("RDE", [prev_frame, "returnvalue"])]
|
|
|
+ yield [
|
|
|
+ ("CD", [user_root, "frame", prev_frame]),
|
|
|
+ ("CD", [prev_frame, "returnvalue", returnvalue]),
|
|
|
+ ("DE", [old_returnvalue_link]),
|
|
|
+ ("DN", [user_frame])]
|
|
|
|
|
|
def constant_init(self, user_root):
|
|
|
user_frame, = yield [("RD", [user_root, "frame"])]
|