|
@@ -65,6 +65,9 @@ class AnalysisState(object):
|
|
|
def analyze(self, instruction_id):
|
|
|
"""Tries to build an intermediate representation from the instruction with the
|
|
|
given id."""
|
|
|
+ # Add the instruction id to the analyzed_instructions set to avoid
|
|
|
+ # infinite loops.
|
|
|
+ self.analyzed_instructions.add(instruction_id)
|
|
|
instruction_val, = yield [("RV", [instruction_id])]
|
|
|
instruction_val = instruction_val["value"]
|
|
|
if instruction_val in self.instruction_analyzers:
|
|
@@ -77,6 +80,22 @@ class AnalysisState(object):
|
|
|
raise Exception(
|
|
|
"Instruction analyzer (for '%s') finished without returning a value!" %
|
|
|
(instruction_val))
|
|
|
+ except primitive_functions.PrimitiveFinished as outer_e:
|
|
|
+ # Check if the instruction has a 'next' instruction.
|
|
|
+ next_instr, = yield [("RD", [instruction_id, "next"])]
|
|
|
+ if next_instr is None:
|
|
|
+ raise outer_e
|
|
|
+ else:
|
|
|
+ gen = self.analyze(next_instr)
|
|
|
+ try:
|
|
|
+ inp = None
|
|
|
+ while True:
|
|
|
+ inp = yield gen.send(inp)
|
|
|
+ except primitive_functions.PrimitiveFinished as inner_e:
|
|
|
+ raise primitive_functions.PrimitiveFinished(
|
|
|
+ tree_ir.CompoundInstruction(
|
|
|
+ outer_e.result,
|
|
|
+ inner_e.result))
|
|
|
else:
|
|
|
raise JitCompilationFailedException(
|
|
|
"Unknown instruction type: '%s'" % (instruction_val))
|
|
@@ -114,26 +133,23 @@ class AnalysisState(object):
|
|
|
|
|
|
def analyze_if(self, instruction_id):
|
|
|
"""Tries to analyze the given 'if' instruction."""
|
|
|
- cond, true, false, next_inst = yield [
|
|
|
+ cond, true, false = yield [
|
|
|
("RD", [instruction_id, "cond"]),
|
|
|
("RD", [instruction_id, "then"]),
|
|
|
- ("RD", [instruction_id, "else"]),
|
|
|
- ("RD", [instruction_id, "next"])]
|
|
|
+ ("RD", [instruction_id, "else"])]
|
|
|
|
|
|
- gen = self.analyze_all([cond, true, false, next_inst])
|
|
|
+ gen = self.analyze_all([cond, true, false])
|
|
|
try:
|
|
|
inp = None
|
|
|
while True:
|
|
|
inp = yield gen.send(inp)
|
|
|
except primitive_functions.PrimitiveFinished as e:
|
|
|
- cond_r, true_r, false_r, next_r = e.result
|
|
|
+ cond_r, true_r, false_r = e.result
|
|
|
raise primitive_functions.PrimitiveFinished(
|
|
|
- tree_ir.CompoundInstruction(
|
|
|
- tree_ir.SelectInstruction(
|
|
|
- tree_ir.ReadValueInstruction(cond_r),
|
|
|
- true_r,
|
|
|
- false_r),
|
|
|
- next_r))
|
|
|
+ tree_ir.SelectInstruction(
|
|
|
+ tree_ir.ReadValueInstruction(cond_r),
|
|
|
+ true_r,
|
|
|
+ false_r))
|
|
|
|
|
|
def analyze_constant(self, instruction_id):
|
|
|
"""Tries to analyze the given 'constant' (literal) instruction."""
|