Browse Source

Add debug info support to tree IR

jonathanvdc 8 years ago
parent
commit
a52237662d
1 changed files with 42 additions and 1 deletions
  1. 42 1
      kernel/modelverse_jit/tree_ir.py

+ 42 - 1
kernel/modelverse_jit/tree_ir.py

@@ -28,6 +28,8 @@
 # Let's just agree to disagree on map vs list comprehensions, pylint.
 # pylint: disable=I0011,W0141
 
+import modelverse_jit.source_map as source_map
+
 NOP_LITERAL = None
 """A literal that results in a nop during which execution may be interrupted
    when yielded."""
@@ -154,7 +156,6 @@ class Instruction(object):
 
 class PythonGenerator(object):
     """Generates Python code from instructions."""
-
     def __init__(self, combine_state_definitions=True):
         self.code = []
         self.state_definitions = []
@@ -163,11 +164,14 @@ class PythonGenerator(object):
         self.indentation = 0
         self.result_name_dict = {}
         self.combine_state_definitions = combine_state_definitions
+        self.source_map_builder = source_map.SourceMapBuilder()
 
     def append(self, text):
         """Appends the given string to this code generator."""
         self.flush_state_definitions()
         self.code.append(text)
+        for _ in xrange(text.count('\n')):
+            self.source_map_builder.append_line()
 
     def append_indentation(self):
         """Appends indentation to the code generator."""
@@ -498,6 +502,43 @@ class PrintInstruction(VoidInstruction):
     def __repr__(self):
         return "PrintInstruction(%r)" % self.argument
 
+class DebugInfoInstruction(Instruction):
+    """An instruction that defines debug information for its child instruction."""
+    def __init__(self, value, debug_info):
+        Instruction.__init__(self)
+        self.value = value
+        self.debug_info = debug_info
+
+    def has_definition_impl(self):
+        """Tells if this instruction requires a definition."""
+        return self.value.has_definition()
+
+    def has_result_temporary(self):
+        """Tells if this instruction stores its result in a temporary."""
+        return self.value.has_result_temporary()
+
+    def get_result_type_impl(self):
+        """Gets this instruction's result type."""
+        return self.value.get_result_type()
+
+    def get_children(self):
+        """Gets this instruction's sequence of child instructions."""
+        return [self.value]
+
+    def create(self, new_children):
+        """Creates a new instruction of this type from the given sequence of child instructions."""
+        arg, = new_children
+        return DebugInfoInstruction(arg, self.debug_info)
+
+    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)
+
+    def __repr__(self):
+        return "DebugInfoInstruction(%r, %r)" % (self.value, self.debug_info)
+
 class BinaryInstruction(Instruction):
     """An instruction that performs a binary operation."""
     def __init__(self, lhs, operator, rhs):