Browse Source

Fix an exception handling bug

jonathanvdc 8 years ago
parent
commit
2f2be3bcc5
2 changed files with 35 additions and 50 deletions
  1. 3 15
      kernel/modelverse_kernel/compiled.py
  2. 32 35
      kernel/modelverse_kernel/request_handler.py

+ 3 - 15
kernel/modelverse_kernel/compiled.py

@@ -1,4 +1,5 @@
 from modelverse_kernel.primitives import PrimitiveFinished
+import modelverse_jit.runtime as jit_runtime 
 
 def reverseKeyLookup(a, b, **remainder):
     edges, = yield [("RO", [a])]
@@ -411,7 +412,7 @@ def construct_const(**remainder):
     v, = yield [("CNV", [{"value": "constant"}])]
 
     # Get input: keep trying until we get something
-    inp, = yield [("CALL_ARGS", [__get_input, (remainder,)])]
+    inp, = yield [("CALL_KWARGS", [jit_runtime.get_input, remainder])]
 
     yield [("CD", [v, "node", inp])]
 
@@ -437,17 +438,4 @@ def retype(a, b, c, **remainder):
         yield [("DE", [prev_edge])]
     t, =        yield [("CE", [tm, mm_ref])]
     yield [("CE", [t, m_ref])]
-    raise PrimitiveFinished(None)
-
-def __get_input(parameters):
-    mvk = parameters["mvk"]
-    user_root = parameters["user_root"]
-    while 1:
-        yield [("CALL_ARGS", [mvk.input_init, (user_root,)])]
-        # Finished
-        if mvk.success:
-            # Got some input, so we can access it
-            raise PrimitiveFinished(mvk.input_value)
-        else:
-            # No input, so yield None but don't stop
-            yield None
+    raise PrimitiveFinished(None)

+ 32 - 35
kernel/modelverse_kernel/request_handler.py

@@ -96,10 +96,8 @@ class RequestHandler(object):
     def pop_generator(self):
         """Removes the top-of-stack generator from the generator stack."""
         # Pop the generator itself.
-        gen = self.generator_stack.pop()
-
+        self.generator_stack.pop()
         # print('Popped generator %s. Generator count: %d' % (gen, len(self.generator_stack)))
-
         # Pop any exception handlers defined by the generator.
         top_of_stack_index = len(self.generator_stack)
         while len(self.exception_handlers) > 0:
@@ -143,38 +141,37 @@ class RequestHandler(object):
     def handle_exception(self, exception):
         """Handles the given exception. A Boolean is returned that tells if
            the exception was handled."""
-
-        print('Exception thrown from %s: %s' % (str(self.generator_stack[-1]), str(exception)))
-        if len(self.exception_handlers) == 0:
-            # Yep, we're hosed. Make sure the caller knows this.
-            # Also, clean up.
-            self.generator_stack = []
-            self.exception_handlers = []
-            return False
-
-        # Pop the top-of-stack exception handler.
-        stack_index, handlers = self.exception_handlers.pop()
-
-        # Try to find an applicable handler.
-        applicable_handler = None
-        for handled_type, handler in handlers:
-            if isinstance(exception, handled_type):
-                applicable_handler = handler
-
-        if applicable_handler is None:
-            # We couldn't find an applicable handler. All is lost.
-            self.generator_stack = []
-            self.exception_handlers = []
-            return False
-
-        # We handle exceptions by first clearing the current stack frame and
-        # all of its children. Then, we place a dummy frame on the stack with
-        # a single 'TAIL_CALL_ARGS' request. The next iteration will replace
-        # the dummy frame by an actual frame.
-        del self.generator_stack[stack_index:]
-        self.generator_stack.append(
-            (None, [('TAIL_CALL_ARGS', [applicable_handler, (exception,)])], False, [], False))
-        return True
+        # print('Exception thrown from %s: %s' % (str(self.generator_stack[-1]), str(exception)))
+        while len(self.exception_handlers) > 0:
+            # Pop the top-of-stack exception handler.
+            stack_index, handlers = self.exception_handlers.pop()
+
+            # Try to find an applicable handler.
+            applicable_handler = None
+            for handled_type, handler in handlers:
+                if isinstance(exception, handled_type):
+                    applicable_handler = handler
+
+            if applicable_handler is not None:
+                # We handle exceptions by first clearing the current stack frame and
+                # all of its children. Then, we place a dummy frame on the stack with
+                # a single 'TAIL_CALL_ARGS' request. The next iteration will replace
+                # the dummy frame by an actual frame.
+                del self.generator_stack[stack_index:]
+                self.generator_stack.append(
+                    (None,
+                     [('TAIL_CALL_ARGS', [applicable_handler, (exception,)])],
+                     False,
+                     [],
+                     False))
+                return True
+
+        # We couldn't find an applicable exception handler, even after exhausting the
+        # entire exception handler stack. All is lost.
+        # Also, clean up after ourselves.
+        self.generator_stack = []
+        self.exception_handlers = []
+        return False
 
     def pop_requests(self):
         """Tries to pop a batch of Modelverse _state_ requests from the