scanner22.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. # Copyright (c) 2016-2018, 2021-2022 by Rocky Bernstein
  2. """
  3. Python 2.2 bytecode massaging.
  4. This massages tokenized 2.2 bytecode to make it more amenable for
  5. grammar parsing.
  6. """
  7. import uncompyle6.scanners.scanner23 as scan
  8. # from uncompyle6.scanners.scanner26 import ingest as ingest26
  9. # bytecode verification, verify(), uses JUMP_OPs from here
  10. from xdis.opcodes import opcode_22
  11. JUMP_OPS = opcode_22.JUMP_OPS
  12. # We base this off of 2.3 instead of the other way around
  13. # because we cleaned things up this way.
  14. # The history is that 2.7 support is the cleanest,
  15. # then from that we got 2.6 and so on.
  16. class Scanner22(scan.Scanner23):
  17. def __init__(self, show_asm=False):
  18. scan.Scanner23.__init__(self, show_asm)
  19. self.opc = opcode_22
  20. self.opname = opcode_22.opname
  21. self.version = (2, 2)
  22. self.genexpr_name = '<generator expression>'
  23. self.parent_ingest = self.ingest
  24. self.ingest = self.ingest22
  25. return
  26. def ingest22(self, co, classname=None, code_objects={}, show_asm=None):
  27. """
  28. Create "tokens" the bytecode of an Python code object. Largely these
  29. are the opcode name, but in some cases that has been modified to make parsing
  30. easier.
  31. returning a list of uncompyle6 Token's.
  32. Some transformations are made to assist the deparsing grammar:
  33. - various types of LOAD_CONST's are categorized in terms of what they load
  34. - COME_FROM instructions are added to assist parsing control structures
  35. - operands with stack argument counts or flag masks are appended to the opcode name, e.g.:
  36. * BUILD_LIST, BUILD_SET
  37. * MAKE_FUNCTION and FUNCTION_CALLS append the number of positional arguments
  38. - EXTENDED_ARGS instructions are removed
  39. Also, when we encounter certain tokens, we add them to a set which will cause custom
  40. grammar rules. Specifically, variable arg tokens like MAKE_FUNCTION or BUILD_LIST
  41. cause specific rules for the specific number of arguments they take.
  42. """
  43. tokens, customize = self.parent_ingest(co, classname, code_objects, show_asm)
  44. tokens = [t for t in tokens if t.kind != 'SET_LINENO']
  45. return tokens, customize