本文整理汇总了Python中opcode.EXTENDED_ARG属性的典型用法代码示例。如果您正苦于以下问题:Python opcode.EXTENDED_ARG属性的具体用法?Python opcode.EXTENDED_ARG怎么用?Python opcode.EXTENDED_ARG使用的例子?那么恭喜您, 这里精选的属性代码示例或许可以为您提供帮助。您也可以进一步了解该属性所在类opcode
的用法示例。
在下文中一共展示了opcode.EXTENDED_ARG属性的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: _unpack_opargs
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
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)
示例2: _add_attr_values_from_insert_to_original
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def _add_attr_values_from_insert_to_original(original_code, insert_code, insert_code_list, attribute_name, op_list):
"""
This function appends values of the attribute `attribute_name` of the inserted code to the original values,
and changes indexes inside inserted code. If some bytecode instruction in the inserted code used to call argument
number i, after modification it calls argument n + i, where n - length of the values in the original code.
So it helps to avoid variables mixing between two pieces of code.
:param original_code: code to modify
:param insert_code: code to insert
:param insert_code_obj: bytes sequence of inserted code, which should be modified too
:param attribute_name: name of attribute to modify ('co_names', 'co_consts' or 'co_varnames')
:param op_list: sequence of bytecodes whose arguments should be changed
:return: modified bytes sequence of the code to insert and new values of the attribute `attribute_name` for
original code
"""
orig_value = getattr(original_code, attribute_name)
insert_value = getattr(insert_code, attribute_name)
orig_names_len = len(orig_value)
code_with_new_values = list(insert_code_list)
offset = 0
while offset < len(code_with_new_values):
op = code_with_new_values[offset]
if op in op_list:
new_val = code_with_new_values[offset + 1] + orig_names_len
if new_val > MAX_BYTE:
code_with_new_values[offset + 1] = new_val & MAX_BYTE
code_with_new_values = code_with_new_values[:offset] + [EXTENDED_ARG, new_val >> 8] + \
code_with_new_values[offset:]
offset += 2
else:
code_with_new_values[offset + 1] = new_val
offset += 2
new_values = orig_value + insert_value
return bytes(code_with_new_values), new_values
示例3: add_jump_instruction
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def add_jump_instruction(jump_arg, code_to_insert):
"""
Note: although it's adding a POP_JUMP_IF_TRUE, it's actually no longer used now
(we could only return the return and possibly the load of the 'None' before the
return -- not done yet because it needs work to fix all related tests).
"""
extended_arg_list = []
if jump_arg > MAX_BYTE:
extended_arg_list += [EXTENDED_ARG, jump_arg >> 8]
jump_arg = jump_arg & MAX_BYTE
# remove 'RETURN_VALUE' instruction and add 'POP_JUMP_IF_TRUE' with (if needed) 'EXTENDED_ARG'
return list(code_to_insert.co_code[:-RETURN_VALUE_SIZE]) + extended_arg_list + [opmap['POP_JUMP_IF_TRUE'], jump_arg]
示例4: compare_bytes_sequence
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def compare_bytes_sequence(self, code1, code2, inserted_code_size):
"""
Compare code after modification and the real code
Since we add POP_JUMP_IF_TRUE instruction, we can't compare modified code and the real code. That's why we
allow some inaccuracies while code comparison
:param code1: result code after modification
:param code2: a real code for checking
:param inserted_code_size: size of inserted code
"""
seq1 = [(offset, op, arg) for offset, op, arg in dis._unpack_opargs(code1)]
seq2 = [(offset, op, arg) for offset, op, arg in dis._unpack_opargs(code2)]
assert len(seq1) == len(seq2), "Bytes sequences have different lengths %s != %s" % (len(seq1), len(seq2))
for i in range(len(seq1)):
of, op1, arg1 = seq1[i]
_, op2, arg2 = seq2[i]
if op1 != op2:
if op1 == 115 and op2 == 1:
# it's ok, because we added POP_JUMP_IF_TRUE manually, but it's POP_TOP in the real code
# inserted code - 2 (removed return instruction) - real code inserted
# Jump should be done to the beginning of inserted fragment
self.assertEqual(arg1, of - (inserted_code_size - 2))
continue
elif op1 == EXTENDED_ARG and op2 == 12:
# we added a real UNARY_NOT to balance EXTENDED_ARG added by new jump instruction
# i.e. inserted code size was increased as well
inserted_code_size += 2
continue
self.assertEqual(op1, op2, "Different operators at offset {}".format(of))
if arg1 != arg2:
if op1 in (100, 101, 106, 116):
# Sometimes indexes of variable names and consts may be different, when we insert them, it's ok
continue
else:
self.assertEqual(arg1, arg2, "Different arguments at offset {}".format(of))
示例5: decode_codeobj
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def decode_codeobj(codeobj):
# adapted from dis.dis
extended_arg = 0
if is_py3k:
codestr = codeobj.co_code
else:
codestr = [ord(ch) for ch in codeobj.co_code]
free = None
i = 0
while i < len(codestr):
op = codestr[i]
opname = opcode.opname[op]
i += 1
argval = None
if op >= opcode.HAVE_ARGUMENT:
oparg = codestr[i] + codestr[i + 1] * 256 + extended_arg
i += 2
extended_arg = 0
if op == opcode.EXTENDED_ARG:
extended_arg = oparg * 65536
continue
if op in opcode.hasconst:
argval = codeobj.co_consts[oparg]
elif op in opcode.hasname:
argval = codeobj.co_names[oparg]
elif op in opcode.hasjrel:
argval = i + oparg
elif op in opcode.haslocal:
argval = codeobj.co_varnames[oparg]
elif op in opcode.hascompare:
argval = opcode.cmp_op[oparg]
elif op in opcode.hasfree:
if free is None:
free = codeobj.co_cellvars + codeobj.co_freevars
argval = free[oparg]
yield (opname, argval)
示例6: instructions
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def instructions(code_obj):
# easy for python 3.4+
if sys.version_info >= (3, 4):
for inst in dis.Bytecode(code_obj):
yield inst
else:
# otherwise we have to manually parse
code = code_obj.co_code
NewInstruction = namedtuple('Instruction', ('opcode', 'arg'))
if six.PY2:
code = map(ord, code)
i, L = 0, len(code)
extended_arg = 0
while i < L:
op = code[i]
i += 1
if op < opcode.HAVE_ARGUMENT:
yield NewInstruction(op, None)
continue
oparg = code[i] + (code[i + 1] << 8) + extended_arg
extended_arg = 0
i += 2
if op == opcode.EXTENDED_ARG:
extended_arg = oparg << 16
continue
yield NewInstruction(op, oparg)
示例7: write_instruction
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def write_instruction(op, arg):
if sys.version_info < (3, 6):
if arg is None:
return [chr(op)]
elif arg <= 65536:
return [chr(op), chr(arg & 255), chr((arg >> 8) & 255)]
elif arg <= 4294967296:
return [
chr(opcode.EXTENDED_ARG),
chr((arg >> 16) & 255),
chr((arg >> 24) & 255),
chr(op),
chr(arg & 255),
chr((arg >> 8) & 255)
]
else:
raise ValueError("Invalid oparg: {0} is too large".format(oparg))
else: # python 3.6+ uses wordcode instead of bytecode and they already supply all the EXTENDEND_ARG ops :)
if arg is None:
return [chr(op), 0]
return [chr(op), arg & 255]
# the code below is for case when extended args are to be determined automatically
# if op == opcode.EXTENDED_ARG:
# return [] # this will be added automatically
# elif arg < 1 << 8:
# return [chr(op), arg]
# elif arg < 1 << 32:
# subs = [1<<24, 1<<16, 1<<8] # allowed op extension sizes
# for sub in subs:
# if arg >= sub:
# fit = int(arg / sub)
# return [chr(opcode.EXTENDED_ARG), fit] + write_instruction(op, arg - fit * sub)
# else:
# raise ValueError("Invalid oparg: {0} is too large".format(oparg))
示例8: instructions
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def instructions(code_obj):
# easy for python 3.4+
if sys.version_info >= (3, 4):
for inst in dis.Bytecode(code_obj):
yield inst
else:
# otherwise we have to manually parse
code = code_obj.co_code
NewInstruction = namedtuple('Instruction', ('opcode', 'arg'))
if six.PY2:
code = map(ord, code)
i, L = 0, len(code)
extended_arg = 0
while i < L:
op = code[i]
i+= 1
if op < opcode.HAVE_ARGUMENT:
yield NewInstruction(op, None)
continue
oparg = code[i] + (code[i+1] << 8) + extended_arg
extended_arg = 0
i += 2
if op == opcode.EXTENDED_ARG:
extended_arg = oparg << 16
continue
yield NewInstruction(op, oparg)
示例9: write_instruction
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def write_instruction(op, arg):
if sys.version_info < (3, 6):
if arg is None:
return [chr(op)]
elif arg <= 65536:
return [chr(op), chr(arg & 255), chr((arg >> 8) & 255)]
elif arg <= 4294967296:
return [chr(opcode.EXTENDED_ARG),
chr((arg >> 16) & 255),
chr((arg >> 24) & 255),
chr(op),
chr(arg & 255),
chr((arg >> 8) & 255)]
else:
raise ValueError("Invalid oparg: {0} is too large".format(oparg))
else: # python 3.6+ uses wordcode instead of bytecode and they already supply all the EXTENDEND_ARG ops :)
if arg is None:
return [chr(op), 0]
return [chr(op), arg & 255]
# the code below is for case when extended args are to be determined automatically
# if op == opcode.EXTENDED_ARG:
# return [] # this will be added automatically
# elif arg < 1 << 8:
# return [chr(op), arg]
# elif arg < 1 << 32:
# subs = [1<<24, 1<<16, 1<<8] # allowed op extension sizes
# for sub in subs:
# if arg >= sub:
# fit = int(arg / sub)
# return [chr(opcode.EXTENDED_ARG), fit] + write_instruction(op, arg - fit * sub)
# else:
# raise ValueError("Invalid oparg: {0} is too large".format(oparg))
示例10: disassemble
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def disassemble(co):
code = co.co_code
labels = dis.findlabels(code)
linestarts = dict(dis.findlinestarts(co))
n = len(code)
i = 0
extended_arg = 0
free = None
lineno = None
while i < n:
c = code[i]
op = ord(c)
lineno = linestarts.get(i, lineno)
is_label = i in labels
ist = i
i += 1
if op >= opcode.HAVE_ARGUMENT:
oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg
extended_arg = 0
i += 2
if op == opcode.EXTENDED_ARG:
extended_arg = oparg * 65536L
if op in opcode.hasconst:
arg = co.co_consts[oparg]
elif op in opcode.hasname:
arg = co.co_names[oparg]
elif op in opcode.hasjrel:
arg = i + oparg
elif op in opcode.haslocal:
arg = co.co_varnames[oparg]
elif op in opcode.hascompare:
arg = opcode.cmp_op[oparg]
elif op in opcode.hasfree:
if free is None:
free = co.co_cellvars + co.co_freevars
arg = free[oparg]
else:
arg = NOVAL
else:
arg = NOVAL
yield ist, lineno, is_label, opcode.opname[op], arg
示例11: emit
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def emit(self, op, oparg, arg=None, lineno=-1):
"""
Writes the bytecode and lnotab.
"""
bytecode_inc, line_inc = 0, -1
if op >= opcode.HAVE_ARGUMENT and oparg > 0xffff:
self.append_code(opcode.EXTENDED_ARG)
self.append_code((oparg >> 16) & 0xff)
self.append_code((oparg >> 24) & 0xff)
bytecode_inc += 3
self.append_code(op)
bytecode_inc += 1
if op >= opcode.HAVE_ARGUMENT:
self.append_code(oparg & 0xff)
self.append_code((oparg >> 8) & 0xff)
bytecode_inc += 2
# We also adjust the lnotabs field
if self.prev_lineno == -1:
line_inc = 0
else:
line_inc = lineno - self.prev_lineno
if line_inc == 0 and bytecode_inc == 0:
self.lnotab.append(0) # bytecode increment
self.lnotab.append(0) # lineno increment
else:
while bytecode_inc > 255:
self.lnotab.append(255)
self.lnotab.append(0)
bytecode_inc -= 255
while line_inc > 255:
self.lnotab.append(0)
self.lnotab.append(255)
line_inc -= 255
# Add the remainder
self.lnotab.append(bytecode_inc)
self.lnotab.append(line_inc)
self.prev_lineno = lineno
示例12: _update_label_offsets
# 需要导入模块: import opcode [as 别名]
# 或者: from opcode import EXTENDED_ARG [as 别名]
def _update_label_offsets(code_obj, breakpoint_offset, breakpoint_code_list):
"""
Update labels for the relative and absolute jump targets
:param code_obj: code to modify
:param breakpoint_offset: offset for the inserted code
:param breakpoint_code_list: size of the inserted code
:return: bytes sequence with modified labels; list of tuples (resulting offset, list of code instructions) with
information about all inserted pieces of code
"""
inserted_code = list()
# the list with all inserted pieces of code
inserted_code.append((breakpoint_offset, breakpoint_code_list))
code_list = list(code_obj)
j = 0
while j < len(inserted_code):
current_offset, current_code_list = inserted_code[j]
offsets_for_modification = []
for offset, op, arg in _unpack_opargs(code_list, inserted_code, j):
if arg is not None:
if op in dis.hasjrel:
# has relative jump target
label = offset + 2 + arg
if offset < current_offset < label:
# change labels for relative jump targets if code was inserted inside
offsets_for_modification.append(offset)
elif op in dis.hasjabs:
# change label for absolute jump if code was inserted before it
if current_offset < arg:
offsets_for_modification.append(offset)
for i in range(0, len(code_list), 2):
op = code_list[i]
if i in offsets_for_modification and op >= dis.HAVE_ARGUMENT:
new_arg = code_list[i + 1] + len(current_code_list)
if new_arg <= MAX_BYTE:
code_list[i + 1] = new_arg
else:
# handle bytes overflow
if i - 2 > 0 and code_list[i - 2] == EXTENDED_ARG and code_list[i - 1] < MAX_BYTE:
# if new argument > 255 and EXTENDED_ARG already exists we need to increase it's argument
code_list[i - 1] += 1
else:
# if there isn't EXTENDED_ARG operator yet we have to insert the new operator
extended_arg_code = [EXTENDED_ARG, new_arg >> 8]
inserted_code.append((i, extended_arg_code))
code_list[i + 1] = new_arg & MAX_BYTE
code_list = code_list[:current_offset] + current_code_list + code_list[current_offset:]
for k in range(len(inserted_code)):
offset, inserted_code_list = inserted_code[k]
if current_offset < offset:
inserted_code[k] = (offset + len(current_code_list), inserted_code_list)
j += 1
return bytes(code_list), inserted_code