and_check.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. # Copyright (c) 2020, 2022 Rocky Bernstein
  2. # This program is free software: you can redistribute it and/or modify
  3. # it under the terms of the GNU General Public License as published by
  4. # the Free Software Foundation, either version 3 of the License, or
  5. def and_invalid(
  6. self, lhs: str, n: int, rule, ast, tokens: list, first: int, last: int
  7. ) -> bool:
  8. jmp = ast[1]
  9. if jmp.kind.startswith("jmp_"):
  10. if last == n:
  11. return True
  12. jmp_target = jmp[0].attr
  13. jmp_offset = jmp[0].offset
  14. if tokens[first].off2int() <= jmp_target < tokens[last].off2int():
  15. return True
  16. if rule == ("and", ("expr", "jmp_false", "expr", "jmp_false")):
  17. jmp2_target = ast[3][0].attr
  18. return jmp_target != jmp2_target
  19. elif rule == ("and", ("expr", "jmp_false", "expr", "POP_JUMP_IF_TRUE")):
  20. jmp2_target = ast[3].attr
  21. return jmp_target == jmp2_target
  22. elif rule == ("and", ("expr", "jmp_false", "expr")):
  23. if tokens[last] == "POP_JUMP_IF_FALSE":
  24. # Ok if jump_target doesn't jump to last instruction
  25. return jmp_target != tokens[last].attr
  26. elif tokens[last] in ("POP_JUMP_IF_TRUE", "JUMP_IF_TRUE_OR_POP"):
  27. # Ok if jump_target jumps to a COME_FROM after
  28. # the last instruction or jumps right after last instruction
  29. if last + 1 < n and tokens[last + 1] == "COME_FROM":
  30. return jmp_target != tokens[last + 1].off2int()
  31. return jmp_target + 2 != tokens[last].attr
  32. elif rule == ("and", ("expr", "jmp_false", "expr", "COME_FROM")):
  33. return ast[-1].attr != jmp_offset
  34. # elif rule == ("and", ("expr", "jmp_false", "expr", "COME_FROM")):
  35. # return jmp_offset != tokens[first+3].attr
  36. return jmp_target != tokens[last].off2int()
  37. return False