我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用dis.HAVE_ARGUMENT。
def scan_opcodes(self, co, unpack = struct.unpack): # Scan the code, and yield 'interesting' opcode combinations # Version for Python 2.4 and older code = co.co_code names = co.co_names consts = co.co_consts while code: c = code[0] if c in STORE_OPS: oparg, = unpack('<H', code[1:3]) yield "store", (names[oparg],) code = code[3:] continue if c == LOAD_CONST and code[3] == IMPORT_NAME: oparg_1, oparg_2 = unpack('<xHxH', code[:6]) yield "import", (consts[oparg_1], names[oparg_2]) code = code[6:] continue if c >= HAVE_ARGUMENT: code = code[3:] else: code = code[1:]
def bytecode(fun): co = fun.func_code code = co.co_code names = co.co_names n = len(code) i = 0 while i < n: end = i c = code[i] op = ord(c) i += 1 oparg = None if op >= dis.HAVE_ARGUMENT: oparg = ord(code[i]) + ord(code[i+1])*256 i += 2 yield (end, op, oparg) return
def _get_opcodes(codeobj): """_get_opcodes(codeobj) -> [opcodes] Extract the actual opcodes as a list from a code object >>> c = compile("[1 + 2, (1,2)]", "", "eval") >>> _get_opcodes(c) [100, 100, 23, 100, 100, 102, 103, 83] """ i = 0 opcodes = [] s = codeobj.co_code while i < len(s): code = ord(s[i]) opcodes.append(code) if code >= dis.HAVE_ARGUMENT: i += 3 else: i += 1 return opcodes
def get_opcode(self): # Based on the settings decide to show the line-by-line trace # Get the current line being executed ip = self.__ip op = self.__code[self.__ip] ip += 1 opmethod = "execute_%s" % dis.opname[op] oparg = None if op >= dis.HAVE_ARGUMENT: low = self.__code[ip] high = self.__code[ip + 1] oparg = (high << 8) | low return opmethod, oparg
def decode_at(self, offset): assert offset < len(self.insBytes) opcode = self.insBytes[offset] if opcode == dis.opmap['EXTENDED_ARG']: raise Exception('EXTENDED_ARG not yet implemented') # Invalid instruction if opcode not in dis.opmap.values(): return Instruction(-1, None, 1) if opcode < dis.HAVE_ARGUMENT: return Instruction(opcode, None, 1) if opcode >= dis.HAVE_ARGUMENT: arg = (self.insBytes[offset + 2] << 8) | self.insBytes[offset + 1] return Instruction(opcode, arg, 3)
def _unpack_opargs(code): # enumerate() is not an option, since we sometimes process # multiple elements on a single pass through the loop extended_arg = 0 n = len(code) i = 0 while i < n: op = ord(code[i]) offset = i i = i+1 arg = None if op >= HAVE_ARGUMENT: arg = ord(code[i]) + ord(code[i+1])*256 + extended_arg extended_arg = 0 i = i+2 if op == EXTENDED_ARG: extended_arg = arg*65536 yield (offset, op, arg) # Modulefinder does a good job at simulating Python's, but it can not # handle __path__ modifications packages make at runtime. Therefore there # is a mechanism whereby you can register extra paths in this map for a # package, and it will be honored. # Note this is a mapping is lists of paths.
def __iter__(self): i = 0 extended_arg = 0 code = self.co_code n = len(code) while i < n: op = code[i] if op >= HAVE_ARGUMENT: oparg = code[i + 1] + code[i + 2] * 256 + extended_arg extended_arg = 0 if op == EXTENDED_ARG: extended_arg = oparg * 65536 i += 3 continue yield i, op, oparg i += 3 else: yield i, op, None i += 1
def _get_opcodes(codeobj): """_get_opcodes(codeobj) -> [opcodes] Extract the actual opcodes as a list from a code object >>> c = compile("[1 + 2, (1,2)]", "", "eval") >>> _get_opcodes(c) [100, 100, 103, 83] """ import dis i = 0 opcodes = [] s = codeobj.co_code while i < len(s): code = ord(s[i]) opcodes.append(code) if code >= dis.HAVE_ARGUMENT: i += 3 else: i += 1 return opcodes
def _get_instructions(code_obj): if hasattr(dis, 'get_instructions'): return list(dis.get_instructions(code_obj)) instructions = [] instruction = None for byte in code_obj.co_code: byte = _six_ord(byte) if instruction is None: instruction = [byte] else: instruction.append(byte) if instruction[0] < dis.HAVE_ARGUMENT or len(instruction) == 3: op_code = instruction[0] op_name = dis.opname[op_code] if instruction[0] < dis.HAVE_ARGUMENT: instructions.append(_Instruction(op_code, op_name, None, None)) else: arg = instruction[1] instructions.append(_Instruction(op_code, op_name, arg, arg)) instruction = None return instructions
def _unpack_opargs(code, inserted_code_list, current_index): """ Modified version of `_unpack_opargs` function from module `dis`. We have to use it, because sometimes code can be in an inconsistent state: if EXTENDED_ARG operator was introduced into the code, but it hasn't been inserted into `code_list` yet. In this case we can't use standard `_unpack_opargs` and we should check whether there are some new operators in `inserted_code_list`. """ extended_arg = 0 for i in range(0, len(code), 2): op = code[i] if op >= HAVE_ARGUMENT: if not extended_arg: # in case if we added EXTENDED_ARG, but haven't inserted it to the source code yet. for code_index in range(current_index, len(inserted_code_list)): inserted_offset, inserted_code = inserted_code_list[code_index] if inserted_offset == i and inserted_code[0] == EXTENDED_ARG: extended_arg = inserted_code[1] << 8 arg = code[i+1] | extended_arg extended_arg = (arg << 8) if op == EXTENDED_ARG else 0 else: arg = None yield (i, op, arg)
def _UnpackOpArgs(self, code): """Unpack the operations and arguments from the byte code. From Python 3.5 onwards this is found in the private method _unpack_opargs but for earlier releases this wasn't available as a separate method.""" opIndex = 0 numOps = len(code) while opIndex < numOps: offset = opIndex op = code[opIndex] opIndex += 1 arg = None if op >= dis.HAVE_ARGUMENT: arg = code[opIndex] + code[opIndex + 1] * 256 opIndex += 2 yield (offset, op, arg)
def _walk_global_ops(code): """ Yield (opcode, argument number) tuples for all global-referencing instructions in *code*. """ code = getattr(code, 'co_code', b'') if not PY3: code = map(ord, code) n = len(code) i = 0 extended_arg = 0 while i < n: op = code[i] i += 1 if op >= HAVE_ARGUMENT: oparg = code[i] + code[i + 1] * 256 + extended_arg extended_arg = 0 i += 2 if op == EXTENDED_ARG: extended_arg = oparg * 65536 if op in GLOBAL_OPS: yield op, oparg
def __iter__(self): """Yield '(op,arg)' pair for each operation in code object 'code'""" bytes = array.array('b', self.code.co_code) eof = len(self.code.co_code) ptr = 0 extended_arg = 0 while ptr < eof: op = bytes[ptr] if op >= dis.HAVE_ARGUMENT: arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg ptr += 3 if op == dis.EXTENDED_ARG: long_type = six.integer_types[-1] extended_arg = arg * long_type(65536) continue else: arg = None ptr += 1 yield OpArg(op, arg)
def parse_byte_and_args(self): code = self.f_code opcode = code.co_code[self.f_lasti] self.f_lasti = self.f_lasti + 1 if opcode >= dis.HAVE_ARGUMENT: int_arg = ( code.co_code[self.f_lasti] + (code.co_code[self.f_lasti+1] << 8)) self.f_lasti = self.f_lasti + 2 if opcode in dis.hasconst: arg = code.co_consts[int_arg] elif opcode in dis.hasfree: if int_arg < len(code.co_cellvars): arg = code.co_cellvars[int_arg] else: arg = code.co_freevars[int_arg - len(code.co_cellvars)] elif opcode in dis.hasname: arg = code.co_names[int_arg] elif opcode in dis.haslocal: arg = code.co_varnames[int_arg] elif opcode in dis.hasjrel: arg = self.f_lasti + int_arg else: arg = int_arg return dis.opname[opcode], (arg,) return dis.opname[opcode], ()
def denotation(opcode): if opcode < dis.HAVE_ARGUMENT: return Instruction(opcode, None) else: return lambda arg: Instruction(opcode, arg)
def scan_opcodes_25(self, co, unpack = struct.unpack): # Scan the code, and yield 'interesting' opcode combinations # Python 2.5 version (has absolute and relative imports) code = co.co_code names = co.co_names consts = co.co_consts LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME while code: c = code[0] if c in STORE_OPS: oparg, = unpack('<H', code[1:3]) yield "store", (names[oparg],) code = code[3:] continue if code[:9:3] == LOAD_LOAD_AND_IMPORT: oparg_1, oparg_2, oparg_3 = unpack('<xHxHxH', code[:9]) level = consts[oparg_1] if level == -1: # normal import yield "import", (consts[oparg_2], names[oparg_3]) elif level == 0: # absolute import yield "absolute_import", (consts[oparg_2], names[oparg_3]) else: # relative import yield "relative_import", (level, consts[oparg_2], names[oparg_3]) code = code[9:] continue if c >= HAVE_ARGUMENT: code = code[3:] else: code = code[1:]
def _iter_code(code): """Yield '(op,arg)' pair for each operation in code object 'code'""" from array import array from dis import HAVE_ARGUMENT, EXTENDED_ARG bytes = array('b',code.co_code) eof = len(code.co_code) ptr = 0 extended_arg = 0 while ptr<eof: op = bytes[ptr] if op>=HAVE_ARGUMENT: arg = bytes[ptr+1] + bytes[ptr+2]*256 + extended_arg ptr += 3 if op==EXTENDED_ARG: extended_arg = arg * long_type(65536) continue else: arg = None ptr += 1 yield op,arg
def find_code(code, f): i = 0 while i < len(code): if f(code, i): return i elif code[i] < dis.HAVE_ARGUMENT: i += 1 else: i += 3 # http://nedbatchelder.com/blog/201301/byterun_and_making_cells.html
def _iter_code(code): """Yield '(op,arg)' pair for each operation in code object 'code'""" from array import array from dis import HAVE_ARGUMENT, EXTENDED_ARG bytes = array('b', code.co_code) eof = len(code.co_code) ptr = 0 extended_arg = 0 while ptr < eof: op = bytes[ptr] if op >= HAVE_ARGUMENT: arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg ptr += 3 if op == EXTENDED_ARG: long_type = six.integer_types[-1] extended_arg = arg * long_type(65536) continue else: arg = None ptr += 1 yield op, arg
def _iter_code(code): """Yield '(op,arg)' pair for each operation in code object 'code'""" from array import array from dis import HAVE_ARGUMENT, EXTENDED_ARG bytes = array('b',code.co_code) eof = len(code.co_code) ptr = 0 extended_arg = 0 while ptr<eof: op = bytes[ptr] if op>=HAVE_ARGUMENT: arg = bytes[ptr+1] + bytes[ptr+2]*256 + extended_arg ptr += 3 if op==EXTENDED_ARG: extended_arg = arg * compat.long_type(65536) continue else: arg = None ptr += 1 yield op,arg
def _iter_code(code): """Yield '(op,arg)' pair for each operation in code object 'code'""" from array import array from dis import HAVE_ARGUMENT, EXTENDED_ARG bytes = array('b',code.co_code) eof = len(code.co_code) ptr = 0 extended_arg = 0 while ptr<eof: op = bytes[ptr] if op>=HAVE_ARGUMENT: arg = bytes[ptr+1] + bytes[ptr+2]*256 + extended_arg ptr += 3 if op==EXTENDED_ARG: long_type = six.integer_types[-1] extended_arg = arg * long_type(65536) continue else: arg = None ptr += 1 yield op,arg
def extract_code_globals(co): """ Find all globals names read or written to by codeblock co """ code = co.co_code if not PY3: code = [ord(c) for c in code] names = co.co_names out_names = set() n = len(code) i = 0 extended_arg = 0 while i < n: op = code[i] i += 1 if op >= HAVE_ARGUMENT: oparg = code[i] + code[i+1] * 256 + extended_arg extended_arg = 0 i += 2 if op == EXTENDED_ARG: extended_arg = oparg*65536 if op in GLOBAL_OPS: out_names.add(names[oparg]) # see if nested function have any global refs if co.co_consts: for const in co.co_consts: if type(const) is types.CodeType: out_names |= CloudPickler.extract_code_globals(const) return out_names
def _get_base_class_names(frame): """Get baseclass names from the code object""" co, lasti = frame.f_code, frame.f_lasti code = co.co_code i = 0 extended_arg = 0 extends = [] while i <= lasti: c = code[i] op = ord(c) i += 1 if op >= dis.HAVE_ARGUMENT: oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg extended_arg = 0 i += 2 if op == dis.EXTENDED_ARG: extended_arg = oparg*int(65536) if op in dis.hasconst: if type(co.co_consts[oparg]) == str: extends = [] elif op in dis.hasname: if dis.opname[op] == 'LOAD_NAME': extends.append(('name', co.co_names[oparg])) if dis.opname[op] == 'LOAD_ATTR': extends.append(('attr', co.co_names[oparg])) items = [] previous_item = [] for t, s in extends: if t == 'name': if previous_item: items.append(previous_item) previous_item = [s] else: previous_item += [s] if previous_item: items.append(previous_item) return items
def get_opcode(self): # Based on the settings decide to show the line-by-line trace # Get the current line being executed current_lineno = self.__exec_frame.line_no_obj.line_number(self.__exec_frame.ip) ip = self.__exec_frame.ip # Update the line number only if the currently executing line has changed. if self.__exec_frame.line_no_obj.currently_executing_line is None or \ self.__exec_frame.line_no_obj.currently_executing_line != current_lineno: self.__exec_frame.line_no_obj.currently_executing_line = current_lineno self.__exec_frame.line_no_obj.currently_executing_line = current_lineno if self.__config.show_line_execution: current_line = self.__exec_frame.line_no_obj.get_source_line(current_lineno) print("Execution Line: %s" % current_line) op = self.__exec_frame.program[self.__exec_frame.ip] ip += 1 opmethod = "execute_%s" % dis.opname[op] oparg = None if op >= dis.HAVE_ARGUMENT: low = self.__exec_frame.program[ip] high = self.__exec_frame.program[ip + 1] oparg = (high << 8) | low return opmethod, oparg, current_lineno
def scan_code_imports(co, LOAD_CONST=dis.opname.index('LOAD_CONST'), IMPORT_NAME=dis.opname.index('IMPORT_NAME')): """Given a code object `co`, scan its bytecode yielding any ``IMPORT_NAME`` and associated prior ``LOAD_CONST`` instructions representing an `Import` statement or `ImportFrom` statement. :return: Generator producing `(level, modname, namelist)` tuples, where: * `level`: -1 for normal import, 0, for absolute import, and >0 for relative import. * `modname`: Name of module to import, or from where `namelist` names are imported. * `namelist`: for `ImportFrom`, the list of names to be imported from `modname`. """ # Yield `(op, oparg)` tuples from the code object `co`. ordit = itertools.imap(ord, co.co_code) nextb = ordit.next opit = ((c, (None if c < dis.HAVE_ARGUMENT else (nextb() | (nextb() << 8)))) for c in ordit) opit, opit2, opit3 = itertools.tee(opit, 3) next(opit2) next(opit3) next(opit3) for oparg1, oparg2, (op3, arg3) in itertools.izip(opit, opit2, opit3): if op3 == IMPORT_NAME: op2, arg2 = oparg2 op1, arg1 = oparg1 if op1 == op2 == LOAD_CONST: yield (co.co_consts[arg1], co.co_names[arg3], co.co_consts[arg2] or ())