Преглед изворни кода

Fix an exception handling bug in the JIT runtime

jonathanvdc пре 8 година
родитељ
комит
ad63badde9
1 измењених фајлова са 26 додато и 26 уклоњено
  1. 26 26
      kernel/modelverse_jit/runtime.py

+ 26 - 26
kernel/modelverse_jit/runtime.py

@@ -7,30 +7,35 @@ class JitCompilationFailedException(Exception):
 def call_function(function_id, named_arguments, **kwargs):
     """Makes the interpreter run the function with the given id with the specified
        argument dictionary."""
-
     user_root = kwargs['user_root']
-    user_frame, = yield [("RD", [user_root, "frame"])]
-    inst, = yield [("RD", [user_frame, "IP"])]
-
-    body_id, = yield [("RD", [function_id, "body"])]
     kernel = kwargs['mvk']
+    body_id, = yield [("RD", [function_id, "body"])]
     kernel.jit.mark_entry_point(body_id)
 
     # Try to jit the function here. We might be able to avoid building the stack
     # frame.
-    try:
-        # Try to compile.
-        compiled_func, = yield [("CALL_ARGS", [kernel.jit_compile, (user_root, body_id)])]
-        # Add the keyword arguments to the argument dictionary.
-        named_arguments.update(kwargs)
-        # Run the function.
-        result, = yield [("CALL_KWARGS", [compiled_func, named_arguments])]
-        # Return.
-        raise primitive_functions.PrimitiveFinished(result)
-    except JitCompilationFailedException:
-        # That's quite alright. Just build a stack frame and hand the function to
-        # the interpreter.
-        pass
+    def handle_jit_failed(_):
+        interpreter_args = {'body_id' : body_id, 'named_arguments' : named_arguments}
+        interpreter_args.update(kwargs)
+        yield [("TAIL_CALL_KWARGS", [interpret_function, interpreter_args])]
+
+    yield [("TRY", [])]
+    yield [("CATCH", [JitCompilationFailedException, handle_jit_failed])]
+    # Try to compile.
+    compiled_func, = yield [("CALL_ARGS", [kernel.jit_compile, (user_root, body_id)])]
+    yield [("END_TRY", [])]
+    # Add the keyword arguments to the argument dictionary.
+    named_arguments.update(kwargs)
+    # Run the function.
+    yield [("TAIL_CALL_KWARGS", [compiled_func, named_arguments])]
+
+def interpret_function(body_id, named_arguments, **kwargs):
+    """Makes the interpreter run the function with the given id with the specified
+       argument dictionary."""
+    user_root = kwargs['user_root']
+    kernel = kwargs['mvk']
+    user_frame, = yield [("RD", [user_root, "frame"])]
+    inst, = yield [("RD", [user_frame, "IP"])]
 
     # Create a new stack frame.
     frame_link, new_phase, new_frame, new_evalstack, new_symbols, \
@@ -61,14 +66,9 @@ def call_function(function_id, named_arguments, **kwargs):
                           ]
 
     # Put the parameters in the new stack frame's symbol table.
-    try:
-        gen = kernel.jit.jit_parameters(body_id)
-        inp = None
-        while 1:
-            inp = yield gen.send(inp)
-    except primitive_functions.PrimitiveFinished as ex:
-        parameter_vars, parameter_names = ex.result
-        parameter_dict = dict(zip(parameter_names, parameter_vars))
+    (parameter_vars, parameter_names), = yield [
+        ("CALL_ARGS", [kernel.jit.jit_parameters, (body_id,)])]
+    parameter_dict = dict(zip(parameter_names, parameter_vars))
 
     for (key, value) in named_arguments.items():
         param_var = parameter_dict[key]