|
@@ -409,6 +409,7 @@ class AnalysisState(object):
|
|
|
self.jit = jit
|
|
|
self.local_mapping = local_mapping
|
|
|
self.function_name = jit.jitted_entry_points[body_id]
|
|
|
+ self.enclosing_loop_instruction = None
|
|
|
|
|
|
def get_local_name(self, local_id):
|
|
|
"""Gets the name for a local with the given id."""
|
|
@@ -544,7 +545,15 @@ class AnalysisState(object):
|
|
|
("RD", [instruction_id, "cond"]),
|
|
|
("RD", [instruction_id, "body"])]
|
|
|
|
|
|
- (cond_r, body_r), = yield [("CALL_ARGS", [self.analyze_all, ([cond, body],)])]
|
|
|
+ # Analyze the condition.
|
|
|
+ cond_r, = yield [("CALL_ARGS", [self.analyze, (cond,)])]
|
|
|
+ # Store the old enclosing loop on the stack, and make this loop the
|
|
|
+ # new enclosing loop.
|
|
|
+ old_loop_instruction = self.enclosing_loop_instruction
|
|
|
+ self.enclosing_loop_instruction = instruction_id
|
|
|
+ body_r, = yield [("CALL_ARGS", [self.analyze, (body,)])]
|
|
|
+ # Restore hte old enclosing loop.
|
|
|
+ self.enclosing_loop_instruction = old_loop_instruction
|
|
|
if self.jit.nop_insertion_enabled:
|
|
|
create_loop_body = lambda check, body: tree_ir.create_block(
|
|
|
check,
|
|
@@ -1016,6 +1025,24 @@ class AnalysisState(object):
|
|
|
yield [("END_TRY", [])]
|
|
|
raise primitive_functions.PrimitiveFinished(result)
|
|
|
|
|
|
+ def analyze_break(self, instruction_id):
|
|
|
+ """Tries to analyze the given 'break' instruction."""
|
|
|
+ target_instruction_id, = yield [("RD", [instruction_id, "while"])]
|
|
|
+ if target_instruction_id == self.enclosing_loop_instruction:
|
|
|
+ raise primitive_functions.PrimitiveFinished(tree_ir.BreakInstruction())
|
|
|
+ else:
|
|
|
+ raise JitCompilationFailedException(
|
|
|
+ "Multilevel 'break' is not supported by the baseline JIT.")
|
|
|
+
|
|
|
+ def analyze_continue(self, instruction_id):
|
|
|
+ """Tries to analyze the given 'continue' instruction."""
|
|
|
+ target_instruction_id, = yield [("RD", [instruction_id, "while"])]
|
|
|
+ if target_instruction_id == self.enclosing_loop_instruction:
|
|
|
+ raise primitive_functions.PrimitiveFinished(tree_ir.ContinueInstruction())
|
|
|
+ else:
|
|
|
+ raise JitCompilationFailedException(
|
|
|
+ "Multilevel 'continue' is not supported by the baseline JIT.")
|
|
|
+
|
|
|
instruction_analyzers = {
|
|
|
'if' : analyze_if,
|
|
|
'while' : analyze_while,
|
|
@@ -1028,6 +1055,8 @@ class AnalysisState(object):
|
|
|
'access' : analyze_access,
|
|
|
'output' : analyze_output,
|
|
|
'input' : analyze_input,
|
|
|
- 'call' : analyze_call
|
|
|
+ 'call' : analyze_call,
|
|
|
+ 'break' : analyze_break,
|
|
|
+ 'continue' : analyze_continue
|
|
|
}
|
|
|
|