263 | 263 |
self.set_meaningful(*refs)
|
264 | 264 |
|
265 | 265 |
def set_unwriteable(self, *refs):
|
|
266 |
"""Intended to be used for implementing analyzing `for`."""
|
266 | 267 |
for ref in refs:
|
267 | 268 |
self._writeable.remove(ref)
|
|
269 |
|
|
270 |
def set_writeable(self, *refs):
|
|
271 |
"""Intended to be used for implementing analyzing `for`."""
|
|
272 |
for ref in refs:
|
|
273 |
self._writeable.add(ref)
|
268 | 274 |
|
269 | 275 |
def set_encountered_goto(self):
|
270 | 276 |
self._has_encountered_goto = True
|
|
669 | 675 |
))
|
670 | 676 |
bottom = final
|
671 | 677 |
|
672 | |
subcontext = context.clone()
|
673 | |
subcontext.set_range(instr.dest, bottom, top)
|
674 | |
subcontext.set_unwriteable(instr.dest)
|
675 | |
self.analyze_block(instr.block, subcontext)
|
676 | |
|
|
678 |
# inside the block, the loop variable cannot be modified, and we know its range.
|
|
679 |
context.set_range(instr.dest, bottom, top)
|
|
680 |
context.set_unwriteable(instr.dest)
|
|
681 |
|
|
682 |
# it will always be executed at least once, so analyze it having
|
|
683 |
# been executed the first time.
|
|
684 |
self.analyze_block(instr.block, context)
|
|
685 |
|
|
686 |
# now analyze it having been executed a second time, with the context
|
|
687 |
# of it having already been executed.
|
|
688 |
self.analyze_block(instr.block, context)
|
|
689 |
|
|
690 |
# after it is executed, we know the range of the loop variable.
|
677 | 691 |
context.set_range(instr.dest, instr.final, instr.final)
|
|
692 |
context.set_writeable(instr.dest)
|