1.1 --- a/micropython/ast.py Fri Oct 10 00:56:20 2008 +0200
1.2 +++ b/micropython/ast.py Sat Oct 25 21:51:23 2008 +0200
1.3 @@ -76,8 +76,8 @@
1.4
1.5 self.labels = {}
1.6 self.label_number = 0
1.7 - self.loop_labels = []
1.8 - self.exception_labels = []
1.9 + self.loop_blocks = []
1.10 + self.exception_blocks = []
1.11
1.12 self.reset()
1.13
1.14 @@ -91,7 +91,7 @@
1.15 # The code itself. This is limited to the code for a particular block
1.16 # being processed.
1.17
1.18 - self.code = []
1.19 + self.blocks = []
1.20
1.21 # Information about temporary values.
1.22
1.23 @@ -116,6 +116,9 @@
1.24 self.unit = self.module
1.25 self.reset()
1.26
1.27 + block = self.new_block()
1.28 + self.set_block(block)
1.29 +
1.30 if self.module.module is not None:
1.31 self.dispatch(self.module.module)
1.32
1.33 @@ -125,7 +128,7 @@
1.34 self.new_op(Return())
1.35
1.36 self.unit.temp_usage = self.max_temp_position + 1
1.37 - return self.code
1.38 + return self.blocks
1.39
1.40 def get_code(self, unit):
1.41
1.42 @@ -134,11 +137,14 @@
1.43 self.unit = unit
1.44 self.reset()
1.45
1.46 + block = self.new_block()
1.47 + self.set_block(block)
1.48 +
1.49 if unit.astnode is not None:
1.50 self.dispatch(unit.astnode)
1.51
1.52 self.unit.temp_usage = self.max_temp_position + 1
1.53 - return self.code
1.54 + return self.blocks
1.55
1.56 def get_instantiator_code(self, cls):
1.57
1.58 @@ -147,6 +153,9 @@
1.59 self.unit = cls.get_instantiator()
1.60 self.reset()
1.61
1.62 + block = self.new_block()
1.63 + self.set_block(block)
1.64 +
1.65 init_method = cls.get_init_method()
1.66
1.67 # Convert this frame back to being an invocation frame.
1.68 @@ -174,7 +183,7 @@
1.69 self.new_op(StoreResult())
1.70 self.new_op(Return())
1.71
1.72 - return self.code
1.73 + return self.blocks
1.74
1.75 # Allocation-related methods.
1.76
1.77 @@ -231,6 +240,37 @@
1.78
1.79 # Code feature methods.
1.80
1.81 + def new_block(self):
1.82 +
1.83 + "Return a new code block."
1.84 +
1.85 + return Block()
1.86 +
1.87 + def set_block(self, block):
1.88 +
1.89 + "Add the given 'block' to the unit's list of blocks."
1.90 +
1.91 + self.optimiser.reset()
1.92 + self.blocks.append(block)
1.93 +
1.94 + def get_loop_blocks(self):
1.95 + return self.loop_blocks[-1]
1.96 +
1.97 + def add_loop_blocks(self, next_block, exit_block):
1.98 + self.loop_blocks.append((next_block, exit_block))
1.99 +
1.100 + def drop_loop_blocks(self):
1.101 + self.loop_blocks.pop()
1.102 +
1.103 + def get_exception_blocks(self):
1.104 + return self.exception_blocks[-1]
1.105 +
1.106 + def add_exception_blocks(self, handler_block, exit_block):
1.107 + self.exception_blocks.append((handler_block, exit_block))
1.108 +
1.109 + def drop_exception_blocks(self):
1.110 + self.exception_blocks.pop()
1.111 +
1.112 def new_label(self):
1.113
1.114 "Return a new label object for use with set_label."
1.115 @@ -250,24 +290,6 @@
1.116
1.117 label.location = len(self.code) + self.unit.code_location
1.118
1.119 - def get_loop_labels(self):
1.120 - return self.loop_labels[-1]
1.121 -
1.122 - def add_loop_labels(self, next_label, exit_label):
1.123 - self.loop_labels.append((next_label, exit_label))
1.124 -
1.125 - def drop_loop_labels(self):
1.126 - self.loop_labels.pop()
1.127 -
1.128 - def get_exception_labels(self):
1.129 - return self.exception_labels[-1]
1.130 -
1.131 - def add_exception_labels(self, handler_label, exit_label):
1.132 - self.exception_labels.append((handler_label, exit_label))
1.133 -
1.134 - def drop_exception_labels(self):
1.135 - self.exception_labels.pop()
1.136 -
1.137 # Assignment expression values.
1.138
1.139 def record_value(self, immediate=1):
1.140 @@ -401,14 +423,16 @@
1.141 if self.optimiser.optimise_away_no_operations(op):
1.142 return
1.143
1.144 - self.code.append(op)
1.145 + # Add the operation to the current block.
1.146 +
1.147 + self.blocks[-1].code.append(op)
1.148 self.optimiser.set_new(op)
1.149
1.150 def remove_op(self):
1.151
1.152 "Remove the last instruction."
1.153
1.154 - op = self.code.pop()
1.155 + op = self.blocks[-1].code.pop()
1.156 self.optimiser.clear_active()
1.157
1.158 def replace_op(self, op):
1.159 @@ -432,7 +456,7 @@
1.160 "Return the last added instruction."
1.161
1.162 try:
1.163 - return self.code[-1]
1.164 + return self.blocks[-1].code[-1]
1.165 except IndexError:
1.166 return None
1.167
1.168 @@ -774,10 +798,11 @@
1.169
1.170 if not self.optimiser.have_correct_self_for_target(context, self.unit):
1.171
1.172 - continue_label = self.new_label()
1.173 + continue_block = self.new_block()
1.174 +
1.175 self.new_op(CheckSelf())
1.176 self.optimiser.set_source(temp)
1.177 - self.new_op(JumpIfTrue(continue_label))
1.178 + self.new_op(JumpIfTrue(continue_block))
1.179
1.180 # Where the context is inappropriate, drop the incomplete frame and
1.181 # raise an exception.
1.182 @@ -788,7 +813,8 @@
1.183 self.load_builtin("TypeError", node)
1.184 self.new_op(StoreException())
1.185 self.new_op(RaiseException())
1.186 - self.set_label(continue_label)
1.187 +
1.188 + self.set_block(continue_block)
1.189
1.190 first = 0
1.191 frame_pos += 1
1.192 @@ -996,8 +1022,8 @@
1.193 raise TypeError
1.194 """
1.195
1.196 - type_error_label = self.new_label()
1.197 - end_label = self.new_label()
1.198 + type_error_block = self.new_block()
1.199 + end_block = self.new_block()
1.200
1.201 # Evaluate and store the operand in temporary storage.
1.202
1.203 @@ -1011,7 +1037,7 @@
1.204 self._generateAttr(node, method, self.attribute_load_instructions)
1.205 temp_method = self.optimiser.optimise_temp_storage()
1.206
1.207 - self._handleAttributeError(node, type_error_label)
1.208 + self._handleAttributeError(node, type_error_block)
1.209
1.210 # Add arguments.
1.211 # NOTE: No support for defaults.
1.212 @@ -1022,7 +1048,7 @@
1.213 self._endCallFuncArgs(1)
1.214 self._doCallFunc(temp_method)
1.215 self._endCallFunc(temp_method)
1.216 - self.new_op(Jump(end_label))
1.217 + self.new_op(Jump(end_block))
1.218
1.219 # Store the result.
1.220
1.221 @@ -1030,16 +1056,12 @@
1.222
1.223 # Raise a TypeError.
1.224
1.225 - self.set_label(type_error_label)
1.226 + self.set_block(type_error_block)
1.227 self.load_builtin("TypeError", node)
1.228 self.new_op(StoreException())
1.229 self.new_op(RaiseException())
1.230
1.231 - # Prevent incorrect optimisation.
1.232 -
1.233 - self.optimiser.reset()
1.234 -
1.235 - self.set_label(end_label)
1.236 + self.set_block(end_block)
1.237
1.238 # Produce the result.
1.239
1.240 @@ -1101,46 +1123,42 @@
1.241 A temporary storage reference is returned from this method.
1.242 """
1.243
1.244 - right_label = self.new_label()
1.245 - type_error_label = self.new_label()
1.246 - end_label = self.new_label()
1.247 + right_block = self.new_block()
1.248 + type_error_block = self.new_block()
1.249 + end_block = self.new_block()
1.250
1.251 # Left method.
1.252
1.253 - temp_out = self._generateOpMethod(node, temp1, temp2, left_method, right_label, end_label)
1.254 + temp_out = self._generateOpMethod(node, temp1, temp2, left_method, right_block, end_block)
1.255 self.discard_temp(temp_out) # NOTE: Will re-use the same storage.
1.256
1.257 # Right method.
1.258
1.259 - self.set_label(right_label)
1.260 - temp_out = self._generateOpMethod(node, temp2, temp1, right_method, type_error_label, end_label)
1.261 + self.set_block(right_block)
1.262 + temp_out = self._generateOpMethod(node, temp2, temp1, right_method, type_error_block, end_block)
1.263
1.264 # Raise a TypeError.
1.265
1.266 - self.set_label(type_error_label)
1.267 + self.set_block(type_error_block)
1.268 self.load_builtin("TypeError", node)
1.269 self.new_op(StoreException())
1.270 self.new_op(RaiseException())
1.271
1.272 - # Prevent incorrect optimisation.
1.273 -
1.274 - self.optimiser.reset()
1.275 -
1.276 - self.set_label(end_label)
1.277 + self.set_block(end_block)
1.278 return temp_out
1.279
1.280 - def _generateOpMethod(self, node, temp1, temp2, method_name, next_method_label, end_label):
1.281 + def _generateOpMethod(self, node, temp1, temp2, method_name, next_method_block, end_block):
1.282
1.283 """
1.284 For the given 'node', generate the operator method invocation using the
1.285 operands 'temp1' and 'temp2', employing the given 'method_name', and
1.286 - jumping appropriately to 'next_method_label' where a NotImplemented
1.287 - result is returned, or to 'end_label' if the method call was successful.
1.288 + jumping appropriately to 'next_method_block' where a NotImplemented
1.289 + result is returned, or to 'end_block' if the method call was successful.
1.290
1.291 A temporary storage reference is returned from this method.
1.292 """
1.293
1.294 - end_attempt_label = self.new_label()
1.295 + end_attempt_block = self.new_block()
1.296
1.297 self.new_op(temp1)
1.298
1.299 @@ -1149,7 +1167,7 @@
1.300 self._generateAttr(node, method_name, self.attribute_load_instructions)
1.301 temp_method = self.optimiser.optimise_temp_storage()
1.302
1.303 - self._handleAttributeError(node, end_attempt_label)
1.304 + self._handleAttributeError(node, end_attempt_block)
1.305
1.306 # Add arguments.
1.307 # NOTE: No support for defaults.
1.308 @@ -1171,15 +1189,15 @@
1.309 # Don't actually raise an exception.
1.310
1.311 self.new_op(TestIdentityAddress(self.get_builtin("NotImplemented", node)))
1.312 - self.new_op(JumpIfTrue(next_method_label))
1.313 - self.new_op(Jump(end_label))
1.314 + self.new_op(JumpIfTrue(next_method_block))
1.315 + self.new_op(Jump(end_block))
1.316
1.317 # End method attempt.
1.318
1.319 - self.set_label(end_attempt_label)
1.320 + self.set_block(end_attempt_block)
1.321 return temp_out
1.322
1.323 - def _handleAttributeError(self, node, end_call_label):
1.324 + def _handleAttributeError(self, node, end_call_block):
1.325
1.326 """
1.327 Add exception handling to the method acquisition instructions where the
1.328 @@ -1189,7 +1207,7 @@
1.329 if not self.optimiser.optimise_known_target():
1.330 self.load_builtin("AttributeError", node)
1.331 self.new_op(CheckException())
1.332 - self.new_op(JumpIfTrue(end_call_label))
1.333 + self.new_op(JumpIfTrue(end_call_block))
1.334
1.335 def _generateSequence(self, sequence_type, node):
1.336
1.337 @@ -1242,17 +1260,17 @@
1.338 boolean status.
1.339 """
1.340
1.341 - true_label = self.new_label()
1.342 - end_label = self.new_label()
1.343 -
1.344 - self.new_op(JumpIfTrue(true_label))
1.345 + true_block = self.new_block()
1.346 + end_block = self.new_block()
1.347 +
1.348 + self.new_op(JumpIfTrue(true_block))
1.349 self.load_builtin("False", node)
1.350 - self.new_op(Jump(end_label))
1.351 -
1.352 - self.set_label(true_label)
1.353 + self.new_op(Jump(end_block))
1.354 +
1.355 + self.set_block(true_block)
1.356 self.load_builtin("True", node)
1.357
1.358 - self.set_label(end_label)
1.359 + self.set_block(end_block)
1.360
1.361 # Concrete visitor methods.
1.362
1.363 @@ -1308,7 +1326,7 @@
1.364 # Logical operators.
1.365
1.366 def visitAnd(self, node):
1.367 - end_label = self.new_label()
1.368 + end_block = self.new_block()
1.369 temp_pos = self.reserve_temp()
1.370 temp = LoadTemp(temp_pos)
1.371
1.372 @@ -1317,16 +1335,12 @@
1.373 self.new_op(StoreTemp(temp_pos))
1.374
1.375 self._generateTestBoolean(n, temp)
1.376 - self.new_op(JumpIfFalse(end_label))
1.377 + self.new_op(JumpIfFalse(end_block))
1.378
1.379 self.dispatch(node.nodes[-1])
1.380 self.new_op(StoreTemp(temp_pos))
1.381
1.382 - self.set_label(end_label)
1.383 -
1.384 - # Prevent incorrect optimisation.
1.385 -
1.386 - self.optimiser.reset()
1.387 + self.set_block(end_block)
1.388
1.389 self.new_op(temp)
1.390 self.discard_temp(temp)
1.391 @@ -1341,12 +1355,8 @@
1.392 self.new_op(InvertBoolean())
1.393 self._generateLoadBoolean(node)
1.394
1.395 - # Prevent incorrect optimisation.
1.396 -
1.397 - self.optimiser.reset()
1.398 -
1.399 def visitOr(self, node):
1.400 - end_label = self.new_label()
1.401 + end_block = self.new_block()
1.402 temp_pos = self.reserve_temp()
1.403 temp = LoadTemp(temp_pos)
1.404
1.405 @@ -1355,16 +1365,12 @@
1.406 self.new_op(StoreTemp(temp_pos))
1.407
1.408 self._generateTestBoolean(n, temp)
1.409 - self.new_op(JumpIfTrue(end_label))
1.410 + self.new_op(JumpIfTrue(end_block))
1.411
1.412 self.dispatch(node.nodes[-1])
1.413 self.new_op(StoreTemp(temp_pos))
1.414
1.415 - self.set_label(end_label)
1.416 -
1.417 - # Prevent incorrect optimisation.
1.418 -
1.419 - self.optimiser.reset()
1.420 + self.set_block(end_block)
1.421
1.422 self.new_op(temp)
1.423 self.discard_temp(temp)
1.424 @@ -1378,7 +1384,7 @@
1.425 _t1 op1 _t2 and _t2 op2 _t3 and ...
1.426 """
1.427
1.428 - end_label = self.new_label()
1.429 + end_block = self.new_block()
1.430
1.431 self.dispatch(node.expr)
1.432 temp2 = self.optimiser.optimise_temp_storage()
1.433 @@ -1446,10 +1452,10 @@
1.434 if op_name.find("not") != -1:
1.435 self.new_op(InvertBoolean())
1.436
1.437 - # Test the result and jump to the end label if false.
1.438 + # Test the result and jump to the end block if false.
1.439
1.440 if op is not last_op:
1.441 - self.new_op(JumpIfFalse(end_label))
1.442 + self.new_op(JumpIfFalse(end_block))
1.443
1.444 # Compilation duties...
1.445
1.446 @@ -1459,11 +1465,7 @@
1.447
1.448 # With the status set above, produce a boolean result.
1.449
1.450 - self.set_label(end_label)
1.451 -
1.452 - # Prevent incorrect optimisation.
1.453 -
1.454 - self.optimiser.reset()
1.455 + self.set_block(end_block)
1.456
1.457 # Yield the appropriate value.
1.458
1.459 @@ -1595,8 +1597,8 @@
1.460 visitAssTuple = visitAssList
1.461
1.462 def visitAugAssign(self, node):
1.463 - use_binary_label = self.new_label()
1.464 - end_label = self.new_label()
1.465 + use_binary_block = self.new_block()
1.466 + end_block = self.new_block()
1.467
1.468 # Evaluate the expression.
1.469
1.470 @@ -1611,17 +1613,17 @@
1.471 # Find the augmented assignment method and attempt to use it.
1.472
1.473 aug_method, (left_method, right_method) = self.augassign_methods[node.op]
1.474 - temp_out = self._generateOpMethod(node, temp1, temp2, aug_method, use_binary_label, end_label)
1.475 + temp_out = self._generateOpMethod(node, temp1, temp2, aug_method, use_binary_block, end_block)
1.476 self.discard_temp(temp_out) # NOTE: Will re-use the same storage.
1.477
1.478 # Where no such method exists, use the binary operator methods.
1.479
1.480 - self.set_label(use_binary_label)
1.481 + self.set_block(use_binary_block)
1.482 temp_out = self._generateBinary(node, temp1, temp2, left_method, right_method)
1.483
1.484 # Assign the result to the name.
1.485
1.486 - self.set_label(end_label)
1.487 + self.set_block(end_block)
1.488 self.new_op(temp_out)
1.489 self.record_value(1)
1.490
1.491 @@ -1766,23 +1768,23 @@
1.492 def visitAssert(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Assert")
1.493
1.494 def visitBreak(self, node):
1.495 - next_label, exit_label = self.get_loop_labels()
1.496 - self.new_op(Jump(exit_label))
1.497 + next_block, exit_block = self.get_loop_blocks()
1.498 + self.new_op(Jump(exit_block))
1.499
1.500 def visitContinue(self, node):
1.501 - next_label, exit_label = self.get_loop_labels()
1.502 - self.new_op(Jump(next_label))
1.503 + next_block, exit_block = self.get_loop_blocks()
1.504 + self.new_op(Jump(next_block))
1.505
1.506 def visitDiscard(self, node):
1.507 self.dispatch(node.expr)
1.508 self.optimiser.optimise_unused_results()
1.509
1.510 def visitFor(self, node):
1.511 - next_handler_label = self.new_label()
1.512 - end_handler_label = self.new_label()
1.513 - exit_label = self.new_label()
1.514 - next_label = self.new_label()
1.515 - else_label = self.new_label()
1.516 + next_handler_block = self.new_block()
1.517 + end_handler_block = self.new_block()
1.518 + exit_block = self.new_block()
1.519 + next_block = self.new_block()
1.520 + else_block = self.new_block()
1.521
1.522 # Get the "list" to be iterated over, obtain its iterator.
1.523
1.524 @@ -1797,11 +1799,11 @@
1.525
1.526 # In the loop...
1.527
1.528 - self.set_label(next_label)
1.529 + self.set_block(next_block)
1.530
1.531 # Handle exceptions when calling "next"...
1.532
1.533 - self.new_op(PushHandler(next_handler_label))
1.534 + self.new_op(PushHandler(next_handler_block))
1.535
1.536 # Use the iterator to get the next value.
1.537
1.538 @@ -1818,11 +1820,11 @@
1.539
1.540 # Skip the handler where the call was successful.
1.541
1.542 - self.new_op(Jump(end_handler_label))
1.543 + self.new_op(Jump(end_handler_block))
1.544
1.545 # Enter the exception handler.
1.546
1.547 - self.set_label(next_handler_label)
1.548 + self.set_block(next_handler_block)
1.549 self.new_op(PopHandler())
1.550
1.551 # Test for StopIteration.
1.552 @@ -1830,9 +1832,9 @@
1.553 self.load_builtin("StopIteration", node)
1.554 self.new_op(CheckException())
1.555 if node.else_ is not None:
1.556 - self.new_op(JumpIfTrue(else_label))
1.557 + self.new_op(JumpIfTrue(else_block))
1.558 else:
1.559 - self.new_op(JumpIfTrue(exit_label))
1.560 + self.new_op(JumpIfTrue(exit_block))
1.561
1.562 # Re-raise the exception otherwise.
1.563
1.564 @@ -1840,7 +1842,7 @@
1.565
1.566 # After the handler.
1.567
1.568 - self.set_label(end_handler_label)
1.569 + self.set_block(end_handler_block)
1.570
1.571 # Assign to the target.
1.572
1.573 @@ -1849,28 +1851,24 @@
1.574
1.575 # Process the body with the current next and exit points.
1.576
1.577 - self.add_loop_labels(next_label, exit_label)
1.578 + self.add_loop_blocks(next_block, exit_block)
1.579 self.dispatch(node.body)
1.580 - self.drop_loop_labels()
1.581 + self.drop_loop_blocks()
1.582
1.583 # Repeat the loop.
1.584
1.585 - self.new_op(Jump(next_label))
1.586 + self.new_op(Jump(next_block))
1.587
1.588 # Produce the "else" section.
1.589
1.590 if node.else_ is not None:
1.591 - self.set_label(exit_label)
1.592 -
1.593 - # Prevent incorrect optimisation.
1.594 -
1.595 - self.optimiser.reset()
1.596 + self.set_block(exit_block)
1.597
1.598 self.dispatch(node.else_)
1.599
1.600 # After the loop...
1.601
1.602 - self.set_label(exit_label)
1.603 + self.set_block(exit_block)
1.604
1.605 # Compilation duties...
1.606
1.607 @@ -1878,7 +1876,7 @@
1.608
1.609 def visitIf(self, node):
1.610 first = 1
1.611 - exit_label = self.new_label()
1.612 + exit_block = self.new_block()
1.613
1.614 clauses = node.tests + [(None, node.else_)]
1.615 last_clause = clauses[-1]
1.616 @@ -1888,22 +1886,18 @@
1.617 if body is None:
1.618 break
1.619 if not first:
1.620 - self.set_label(next_label)
1.621 + self.set_block(next_block)
1.622 if test is not None:
1.623 self.dispatch(test)
1.624 - next_label = self.new_label()
1.625 - self.new_op(JumpIfFalse(next_label))
1.626 + next_block = self.new_block()
1.627 + self.new_op(JumpIfFalse(next_block))
1.628 self.dispatch(body)
1.629 if clause is not last_clause:
1.630 - self.new_op(Jump(exit_label))
1.631 -
1.632 - # Prevent incorrect optimisation.
1.633 -
1.634 - self.optimiser.reset()
1.635 + self.new_op(Jump(exit_block))
1.636
1.637 first = 0
1.638
1.639 - self.set_label(exit_label)
1.640 + self.set_block(exit_block)
1.641
1.642 def visitPass(self, node): pass
1.643
1.644 @@ -1943,36 +1937,32 @@
1.645 self.new_op(Return())
1.646
1.647 def visitTryExcept(self, node):
1.648 - exit_label = self.new_label()
1.649 - else_label = self.new_label()
1.650 - handler_label = self.new_label()
1.651 -
1.652 - self.add_exception_labels(handler_label, exit_label)
1.653 + exit_block = self.new_block()
1.654 + else_block = self.new_block()
1.655 + handler_block = self.new_block()
1.656 +
1.657 + self.add_exception_blocks(handler_block, exit_block)
1.658
1.659 # Try...
1.660 # Produce the code, then jump to the exit.
1.661
1.662 - self.new_op(PushHandler(handler_label))
1.663 + self.new_op(PushHandler(handler_block))
1.664 self.dispatch(node.body)
1.665 self.new_op(PopHandler())
1.666
1.667 if node.else_ is not None:
1.668 - self.new_op(Jump(else_label))
1.669 + self.new_op(Jump(else_block))
1.670 else:
1.671 - self.new_op(Jump(exit_label))
1.672 + self.new_op(Jump(exit_block))
1.673
1.674 # Start of handlers.
1.675
1.676 - self.set_label(handler_label)
1.677 -
1.678 - # Prevent incorrect optimisation.
1.679 -
1.680 - self.optimiser.reset()
1.681 + self.set_block(handler_block)
1.682
1.683 self.new_op(PopHandler())
1.684
1.685 for name, assignment, handler in node.handlers:
1.686 - next_label = self.new_label()
1.687 + next_block = self.new_block()
1.688
1.689 # Test the given exception against the current exception.
1.690
1.691 @@ -1980,7 +1970,7 @@
1.692 self.dispatch(name)
1.693
1.694 self.new_op(CheckException())
1.695 - self.new_op(JumpIfFalse(next_label))
1.696 + self.new_op(JumpIfFalse(next_block))
1.697
1.698 # Handle assignment to exception variable.
1.699
1.700 @@ -1996,13 +1986,9 @@
1.701 # Produce the handler code, then jump to the exit.
1.702
1.703 self.dispatch(handler)
1.704 - self.new_op(Jump(exit_label))
1.705 -
1.706 - self.set_label(next_label)
1.707 -
1.708 - # Prevent incorrect optimisation.
1.709 -
1.710 - self.optimiser.reset()
1.711 + self.new_op(Jump(exit_block))
1.712 +
1.713 + self.set_block(next_block)
1.714
1.715 # Unhandled exceptions.
1.716
1.717 @@ -2011,52 +1997,40 @@
1.718 # Optional else clause.
1.719
1.720 if node.else_ is not None:
1.721 - self.set_label(else_label)
1.722 -
1.723 - # Prevent incorrect optimisation.
1.724 -
1.725 - self.optimiser.reset()
1.726 + self.set_block(else_block)
1.727
1.728 self.dispatch(node.else_)
1.729
1.730 - self.set_label(exit_label)
1.731 - self.drop_exception_labels()
1.732 + self.set_block(exit_block)
1.733 + self.drop_exception_blocks()
1.734
1.735 def visitTryFinally(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "TryFinally")
1.736
1.737 def visitWhile(self, node):
1.738 - exit_label = self.new_label()
1.739 - next_label = self.new_label()
1.740 - else_label = self.new_label()
1.741 -
1.742 - self.set_label(next_label)
1.743 + exit_block = self.new_block()
1.744 + next_block = self.new_block()
1.745 + else_block = self.new_block()
1.746 +
1.747 + self.set_block(next_block)
1.748 self.dispatch(node.test)
1.749 if node.else_ is not None:
1.750 - self.new_op(JumpIfFalse(else_label))
1.751 + self.new_op(JumpIfFalse(else_block))
1.752 else:
1.753 - self.new_op(JumpIfFalse(exit_label))
1.754 -
1.755 - self.add_loop_labels(next_label, exit_label)
1.756 + self.new_op(JumpIfFalse(exit_block))
1.757 +
1.758 + self.add_loop_blocks(next_block, exit_block)
1.759
1.760 self.dispatch(node.body)
1.761 - self.new_op(Jump(next_label))
1.762 + self.new_op(Jump(next_block))
1.763
1.764 if node.else_ is not None:
1.765 - self.set_label(else_label)
1.766 -
1.767 - # Prevent incorrect optimisation.
1.768 -
1.769 - self.optimiser.reset()
1.770 + self.set_block(else_block)
1.771
1.772 self.dispatch(node.else_)
1.773
1.774 - self.set_label(exit_label)
1.775 -
1.776 - # Prevent incorrect optimisation.
1.777 -
1.778 - self.optimiser.reset()
1.779 -
1.780 - self.drop_loop_labels()
1.781 + self.set_block(exit_block)
1.782 +
1.783 + self.drop_loop_blocks()
1.784
1.785 def visitWith(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "With")
1.786