diff --git a/src/sixtypical/analyzer.py b/src/sixtypical/analyzer.py index 6dc3262..3c4394b 100644 --- a/src/sixtypical/analyzer.py +++ b/src/sixtypical/analyzer.py @@ -101,7 +101,7 @@ class Context(object): self._touched = set() self._range = dict() self._writeable = set() - self._has_encountered_goto = False + self._gotos_encountered = set() for ref in inputs: if ref.is_constant(): @@ -273,11 +273,11 @@ class Context(object): for ref in refs: self._writeable.add(ref) - def set_encountered_goto(self): - self._has_encountered_goto = True + def encounter_gotos(self, gotos): + self._gotos_encountered |= gotos - def has_encountered_goto(self): - return self._has_encountered_goto + def encountered_gotos(self): + return self._gotos_encountered class Analyzer(object): @@ -346,7 +346,7 @@ class Analyzer(object): if ref in type_.outputs: raise UnmeaningfulOutputError(routine, ref.name) - if not context.has_encountered_goto(): + if not context.encountered_gotos(): for ref in type_.outputs: context.assert_meaningful(ref, exception_class=UnmeaningfulOutputError) for ref in context.each_touched(): @@ -379,7 +379,7 @@ class Analyzer(object): dest = instr.dest src = instr.src - if context.has_encountered_goto(): + if context.encountered_gotos(): raise IllegalJumpError(instr, instr) if opcode == 'ld': @@ -595,7 +595,7 @@ class Analyzer(object): self.assert_affected_within('outputs', type_, current_type) self.assert_affected_within('trashes', type_, current_type) - context.set_encountered_goto() + context.encounter_gotos(set([instr.location])) elif opcode == 'trash': context.set_touched(instr.dest) context.set_unmeaningful(instr.dest) @@ -636,8 +636,7 @@ class Analyzer(object): context._touched = set(context1._touched) | set(context2._touched) context.set_meaningful(*list(outgoing_meaningful)) context._writeable = set(context1._writeable) | set(context2._writeable) - if context1.has_encountered_goto() or context2.has_encountered_goto(): - context.set_encountered_goto() + context.encounter_gotos(context1.encountered_gotos() | context2.encountered_gotos()) for ref in outgoing_trashes: context.set_touched(ref)