|
@@ -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):
|