Преглед на файлове

Implement source map generation for the baseline JIT

jonathanvdc преди 8 години
родител
ревизия
01277aee16
променени са 4 файла, в които са добавени 35 реда и са изтрити 7 реда
  1. 8 3
      kernel/modelverse_jit/bytecode_to_tree.py
  2. 5 1
      kernel/modelverse_jit/runtime.py
  3. 8 0
      kernel/modelverse_jit/source_map.py
  4. 14 3
      kernel/modelverse_jit/tree_ir.py

+ 8 - 3
kernel/modelverse_jit/bytecode_to_tree.py

@@ -305,9 +305,14 @@ class AnalysisState(object):
             # Analyze the instruction itself.
             outer_result, = yield [
                 ("CALL_ARGS", [self.instruction_analyzers[instruction_type], (self, instruction)])]
-            if self.jit.tracing_enabled and instruction.debug_information is not None:
-                outer_result = with_debug_info_trace(
-                    outer_result, instruction.debug_information, self.function_name)
+            if instruction.debug_information is not None:
+                if self.jit.tracing_enabled:
+                    outer_result = with_debug_info_trace(
+                        outer_result, instruction.debug_information, self.function_name)
+                if self.jit.source_maps_enabled:
+                    outer_result = tree_ir.DebugInfoInstruction(
+                        outer_result, instruction.debug_information)
+
             # Check if the instruction has a 'next' instruction.
             if instruction.next_instruction is None:
                 raise primitive_functions.PrimitiveFinished(outer_result)

+ 5 - 1
kernel/modelverse_jit/runtime.py

@@ -148,9 +148,13 @@ def interpret_function_body(body_id, named_arguments, **kwargs):
         # An instruction has completed. Forward it.
         yield result
 
+class UnreachableCodeException(Exception):
+    """The type of exception that is thrown when supposedly unreachable code is executed."""
+    pass
+
 def unreachable():
     """Marks unreachable code."""
-    raise Exception('An unreachable statement was reached.')
+    raise UnreachableCodeException('An unreachable statement was reached.')
 
 def get_input(**parameters):
     """Retrieves input."""

+ 8 - 0
kernel/modelverse_jit/source_map.py

@@ -14,6 +14,11 @@ class SourceMap(object):
            found."""
         return self.lines[line_number]
 
+    def __str__(self):
+        return '\n'.join(
+            ['%d: %s' % pair
+             for pair in sorted(self.lines.items(), key=lambda (key, _): key)])
+
 class SourceMapBuilder(object):
     """A type of object that makes it easy to build source maps for hierarchical instructions."""
     def __init__(self, initial_line_number=0):
@@ -39,3 +44,6 @@ class SourceMapBuilder(object):
         if len(self.debug_info_stack) > 0:
             self.source_map.map_line(self.line_number, self.debug_info_stack[-1])
 
+    def __str__(self):
+        return str(self.source_map)
+

+ 14 - 3
kernel/modelverse_jit/tree_ir.py

@@ -521,6 +521,11 @@ class DebugInfoInstruction(Instruction):
         """Gets this instruction's result type."""
         return self.value.get_result_type()
 
+    def get_result_name_override(self, code_generator):
+        """Gets a value that overrides the code generator's result name for this
+           instruction if it is not None."""
+        return self.value.get_result_name_override(code_generator)
+
     def get_children(self):
         """Gets this instruction's sequence of child instructions."""
         return [self.value]
@@ -532,9 +537,15 @@ class DebugInfoInstruction(Instruction):
 
     def generate_python_def(self, code_generator):
         """Generates Python code for this instruction."""
-        code_generator.source_map_builder.push_debug_info(self.debug_info)
-        self.value.generate_python_def(code_generator)
-        code_generator.source_map_builder.pop_debug_info(self.debug_info)
+        if self.has_result_temporary():
+            code_generator.source_map_builder.push_debug_info(self.debug_info)
+            code_generator.append_move_definition(self, self.value)
+            code_generator.source_map_builder.pop_debug_info()
+
+    def generate_python_use(self, code_generator):
+        """Generates a Python expression that retrieves this instruction's
+           result. The expression is returned as a string."""
+        return self.value.generate_python_use(code_generator)
 
     def __repr__(self):
         return "DebugInfoInstruction(%r, %r)" % (self.value, self.debug_info)