Pārlūkot izejas kodu

Fix a couple of bugs in the bytecode parser

jonathanvdc 8 gadi atpakaļ
vecāks
revīzija
29f2a59977

+ 15 - 14
kernel/modelverse_jit/bytecode_parser.py

@@ -12,7 +12,7 @@ class BytecodeParser(object):
     def parse_instruction(self, node_id):
         """Parses the instruction node with the given identifier."""
         if node_id is None:
-            return None
+            raise primitive_functions.PrimitiveFinished(None)
         elif node_id in self.parsed_nodes:
             # We've already parsed this node, so return it right away.
             raise primitive_functions.PrimitiveFinished(self.parsed_nodes[node_id])
@@ -23,7 +23,7 @@ class BytecodeParser(object):
         instruction = self.create_instruction(instruction_type)
         self.parsed_nodes[node_id] = instruction
         # Initialize the instruction from the node's data.
-        yield [("CALL_ARGS", [self.initialize_instruction, instruction, (node_id,)])]
+        yield [("CALL_ARGS", [self.initialize_instruction, (instruction, node_id)])]
         # Retrieve the debug information.
         debug_info, = yield [("RD", [node_id, "__debug"])]
         if debug_info is not None:
@@ -40,29 +40,29 @@ class BytecodeParser(object):
 
     def parse_variable(self, node_id):
         """Parses the given variable node."""
-        var_id, = yield [("RD", [node_id, "var"])]
-        var_name, = yield [("RV", [var_id])]
-        return bytecode_ir.VariableNode(var_id, var_name)
+        var_name, = yield [("RV", [node_id])]
+        raise primitive_functions.PrimitiveFinished(
+            bytecode_ir.VariableNode(node_id, var_name))
 
     def __parse_node_unchecked(self, node_id, result_type):
         """Parses the given node as the specified type of object, without
            checking that the result actually conforms to said type."""
-        if isinstance(result_type, bytecode_ir.VariableNode):
-            return self.parse_variable(node_id)
-        elif isinstance(result_type, int):
-            return node_id
+        if result_type is bytecode_ir.VariableNode:
+            yield [("TAIL_CALL_ARGS", [self.parse_variable, (node_id,)])]
+        elif result_type is int:
+            raise primitive_functions.PrimitiveFinished(node_id)
         else:
-            return self.parse_instruction(node_id)
+            yield [("TAIL_CALL_ARGS", [self.parse_instruction, (node_id,)])]
 
     def parse_node(self, node_id, result_type):
         """Parses the given node as the specified type of object."""
-        result = self.__parse_node_unchecked(node_id, result_type)
+        result, = yield [("CALL_ARGS", [self.__parse_node_unchecked, (node_id, result_type)])]
         if result is not None and not isinstance(result, result_type):
             raise jit_runtime.JitCompilationFailedException(
                 "Parsed a node as an instance of '%s', expected an instance of '%s'." % (
-                    type(result), result_type))
+                    type(result).__name__, result_type.__name__))
 
-        return result
+        raise primitive_functions.PrimitiveFinished(result)
 
     def parse_arguments(self, first_argument_id):
         """Parses the parameter-to-argument mapping started by the specified first argument
@@ -83,7 +83,7 @@ class BytecodeParser(object):
     def create_instruction(self, instruction_type):
         """Creates an instruction of the given type."""
         if instruction_type in bytecode_ir.INSTRUCTION_TYPE_MAPPING:
-            return bytecode_ir.INSTRUCTION_TYPE_MAPPING[instruction_type].__new__()
+            return object.__new__(bytecode_ir.INSTRUCTION_TYPE_MAPPING[instruction_type])
         else:
             raise jit_runtime.JitCompilationFailedException(
                 "Unknown instruction type: '%s'" % instruction_type)
@@ -101,6 +101,7 @@ class BytecodeParser(object):
     def initialize_instruction(self, instruction, node_id):
         """Initializes the given instruction with data from the given node."""
         instr_type = type(instruction)
+        # print("Initializing '%s' node" % instr_type)
         if instr_type is bytecode_ir.CallInstruction:
             # Call instructions are complicated, so they get special treatment.
             yield [("TAIL_CALL_ARGS", [self.initialize_call, (instruction, node_id)])]

+ 15 - 0
kernel/modelverse_jit/runtime.py

@@ -10,6 +10,21 @@ MUTABLE_FUNCTION_KEY = "mutable"
 FUNCTION_BODY_KEY = "body"
 """A dictionary key for function bodies."""
 
+KWARGS_PARAMETER_NAME = "kwargs"
+"""The name of the kwargs parameter in jitted functions."""
+
+CALL_FUNCTION_NAME = "__call_function"
+"""The name of the '__call_function' function, in the jitted function scope."""
+
+GET_INPUT_FUNCTION_NAME = "__get_input"
+"""The name of the '__get_input' function, in the jitted function scope."""
+
+LOCALS_NODE_NAME = "jit_locals"
+"""The name of the node that is connected to all JIT locals in a given function call."""
+
+LOCALS_EDGE_NAME = "jit_locals_edge"
+"""The name of the edge that connects the LOCALS_NODE_NAME node to a user root."""
+
 def call_function(function_id, named_arguments, **kwargs):
     """Runs the function with the given id, passing it the specified argument dictionary."""
     user_root = kwargs['user_root']