mirror of https://github.com/python/cpython
Rework CALL_FUNCTION* opcodes
Issue #27213: Rework CALL_FUNCTION* opcodes to produce shorter and more efficient bytecode: * CALL_FUNCTION now only accepts position arguments * CALL_FUNCTION_KW accepts position arguments and keyword arguments, but keys of keyword arguments are packed into a constant tuple. * CALL_FUNCTION_EX is the most generic, it expects a tuple and a dict for positional and keyword arguments. CALL_FUNCTION_VAR and CALL_FUNCTION_VAR_KW opcodes have been removed. 2 tests of test_traceback are currently broken: skip test, the issue #28050 was created to track the issue. Patch by Demur Rumed, design by Serhiy Storchaka, reviewed by Serhiy Storchaka and Victor Stinner.
This commit is contained in:
parent
e53592091a
commit
f9b760f48a
|
@ -108,9 +108,8 @@ extern "C" {
|
||||||
#define LOAD_DEREF 136
|
#define LOAD_DEREF 136
|
||||||
#define STORE_DEREF 137
|
#define STORE_DEREF 137
|
||||||
#define DELETE_DEREF 138
|
#define DELETE_DEREF 138
|
||||||
#define CALL_FUNCTION_VAR 140
|
|
||||||
#define CALL_FUNCTION_KW 141
|
#define CALL_FUNCTION_KW 141
|
||||||
#define CALL_FUNCTION_VAR_KW 142
|
#define CALL_FUNCTION_EX 142
|
||||||
#define SETUP_WITH 143
|
#define SETUP_WITH 143
|
||||||
#define EXTENDED_ARG 144
|
#define EXTENDED_ARG 144
|
||||||
#define LIST_APPEND 145
|
#define LIST_APPEND 145
|
||||||
|
|
|
@ -314,7 +314,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
|
||||||
argrepr = argval
|
argrepr = argval
|
||||||
elif op in hasfree:
|
elif op in hasfree:
|
||||||
argval, argrepr = _get_name_info(arg, cells)
|
argval, argrepr = _get_name_info(arg, cells)
|
||||||
elif op in hasnargs:
|
elif op in hasnargs: # unused
|
||||||
argrepr = "%d positional, %d keyword pair" % (arg%256, arg//256)
|
argrepr = "%d positional, %d keyword pair" % (arg%256, arg//256)
|
||||||
yield Instruction(opname[op], op,
|
yield Instruction(opname[op], op,
|
||||||
arg, argval, argrepr,
|
arg, argval, argrepr,
|
||||||
|
|
|
@ -236,6 +236,7 @@ _code_type = type(_write_atomic.__code__)
|
||||||
# Python 3.6b1 3373 (add BUILD_STRING opcode #27078)
|
# Python 3.6b1 3373 (add BUILD_STRING opcode #27078)
|
||||||
# Python 3.6b1 3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes
|
# Python 3.6b1 3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes
|
||||||
# #27985)
|
# #27985)
|
||||||
|
# Python 3.6a1 3376 (simplify CALL_FUNCTIONs & BUILD_MAP_UNPACK_WITH_CALL)
|
||||||
#
|
#
|
||||||
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
||||||
# longer be understood by older implementations of the eval loop (usually
|
# longer be understood by older implementations of the eval loop (usually
|
||||||
|
@ -244,7 +245,7 @@ _code_type = type(_write_atomic.__code__)
|
||||||
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||||
# in PC/launcher.c must also be updated.
|
# in PC/launcher.c must also be updated.
|
||||||
|
|
||||||
MAGIC_NUMBER = (3375).to_bytes(2, 'little') + b'\r\n'
|
MAGIC_NUMBER = (3376).to_bytes(2, 'little') + b'\r\n'
|
||||||
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||||
|
|
||||||
_PYCACHE = '__pycache__'
|
_PYCACHE = '__pycache__'
|
||||||
|
|
|
@ -31,7 +31,7 @@ hasjabs = []
|
||||||
haslocal = []
|
haslocal = []
|
||||||
hascompare = []
|
hascompare = []
|
||||||
hasfree = []
|
hasfree = []
|
||||||
hasnargs = []
|
hasnargs = [] # unused
|
||||||
|
|
||||||
opmap = {}
|
opmap = {}
|
||||||
opname = ['<%r>' % (op,) for op in range(256)]
|
opname = ['<%r>' % (op,) for op in range(256)]
|
||||||
|
@ -172,8 +172,7 @@ haslocal.append(126)
|
||||||
name_op('STORE_ANNOTATION', 127) # Index in name list
|
name_op('STORE_ANNOTATION', 127) # Index in name list
|
||||||
|
|
||||||
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
|
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
|
||||||
def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
|
def_op('CALL_FUNCTION', 131) # #args
|
||||||
hasnargs.append(131)
|
|
||||||
def_op('MAKE_FUNCTION', 132) # Flags
|
def_op('MAKE_FUNCTION', 132) # Flags
|
||||||
def_op('BUILD_SLICE', 133) # Number of items
|
def_op('BUILD_SLICE', 133) # Number of items
|
||||||
def_op('LOAD_CLOSURE', 135)
|
def_op('LOAD_CLOSURE', 135)
|
||||||
|
@ -185,12 +184,8 @@ hasfree.append(137)
|
||||||
def_op('DELETE_DEREF', 138)
|
def_op('DELETE_DEREF', 138)
|
||||||
hasfree.append(138)
|
hasfree.append(138)
|
||||||
|
|
||||||
def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8)
|
def_op('CALL_FUNCTION_KW', 141) # #args + #kwargs
|
||||||
hasnargs.append(140)
|
def_op('CALL_FUNCTION_EX', 142) # Flags
|
||||||
def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8)
|
|
||||||
hasnargs.append(141)
|
|
||||||
def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8)
|
|
||||||
hasnargs.append(142)
|
|
||||||
|
|
||||||
jrel_op('SETUP_WITH', 143)
|
jrel_op('SETUP_WITH', 143)
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ def _f(a):
|
||||||
dis_f = """\
|
dis_f = """\
|
||||||
%3d 0 LOAD_GLOBAL 0 (print)
|
%3d 0 LOAD_GLOBAL 0 (print)
|
||||||
2 LOAD_FAST 0 (a)
|
2 LOAD_FAST 0 (a)
|
||||||
4 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
|
4 CALL_FUNCTION 1
|
||||||
6 POP_TOP
|
6 POP_TOP
|
||||||
|
|
||||||
%3d 8 LOAD_CONST 1 (1)
|
%3d 8 LOAD_CONST 1 (1)
|
||||||
|
@ -108,7 +108,7 @@ dis_f = """\
|
||||||
dis_f_co_code = """\
|
dis_f_co_code = """\
|
||||||
0 LOAD_GLOBAL 0 (0)
|
0 LOAD_GLOBAL 0 (0)
|
||||||
2 LOAD_FAST 0 (0)
|
2 LOAD_FAST 0 (0)
|
||||||
4 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
|
4 CALL_FUNCTION 1
|
||||||
6 POP_TOP
|
6 POP_TOP
|
||||||
8 LOAD_CONST 1 (1)
|
8 LOAD_CONST 1 (1)
|
||||||
10 RETURN_VALUE
|
10 RETURN_VALUE
|
||||||
|
@ -126,7 +126,7 @@ dis_bug708901 = """\
|
||||||
4 LOAD_CONST 1 (1)
|
4 LOAD_CONST 1 (1)
|
||||||
|
|
||||||
%3d 6 LOAD_CONST 2 (10)
|
%3d 6 LOAD_CONST 2 (10)
|
||||||
8 CALL_FUNCTION 2 (2 positional, 0 keyword pair)
|
8 CALL_FUNCTION 2
|
||||||
10 GET_ITER
|
10 GET_ITER
|
||||||
>> 12 FOR_ITER 4 (to 18)
|
>> 12 FOR_ITER 4 (to 18)
|
||||||
14 STORE_FAST 0 (res)
|
14 STORE_FAST 0 (res)
|
||||||
|
@ -154,11 +154,11 @@ dis_bug1333982 = """\
|
||||||
10 MAKE_FUNCTION 0
|
10 MAKE_FUNCTION 0
|
||||||
12 LOAD_FAST 0 (x)
|
12 LOAD_FAST 0 (x)
|
||||||
14 GET_ITER
|
14 GET_ITER
|
||||||
16 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
|
16 CALL_FUNCTION 1
|
||||||
|
|
||||||
%3d 18 LOAD_CONST 4 (1)
|
%3d 18 LOAD_CONST 4 (1)
|
||||||
20 BINARY_ADD
|
20 BINARY_ADD
|
||||||
22 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
|
22 CALL_FUNCTION 1
|
||||||
24 RAISE_VARARGS 1
|
24 RAISE_VARARGS 1
|
||||||
|
|
||||||
%3d >> 26 LOAD_CONST 0 (None)
|
%3d >> 26 LOAD_CONST 0 (None)
|
||||||
|
@ -224,14 +224,14 @@ dis_annot_stmt_str = """\
|
||||||
|
|
||||||
3 10 LOAD_NAME 2 (fun)
|
3 10 LOAD_NAME 2 (fun)
|
||||||
12 LOAD_CONST 0 (1)
|
12 LOAD_CONST 0 (1)
|
||||||
14 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
|
14 CALL_FUNCTION 1
|
||||||
16 STORE_ANNOTATION 3 (y)
|
16 STORE_ANNOTATION 3 (y)
|
||||||
|
|
||||||
4 18 LOAD_CONST 0 (1)
|
4 18 LOAD_CONST 0 (1)
|
||||||
20 LOAD_NAME 4 (lst)
|
20 LOAD_NAME 4 (lst)
|
||||||
22 LOAD_NAME 2 (fun)
|
22 LOAD_NAME 2 (fun)
|
||||||
24 LOAD_CONST 1 (0)
|
24 LOAD_CONST 1 (0)
|
||||||
26 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
|
26 CALL_FUNCTION 1
|
||||||
28 STORE_SUBSCR
|
28 STORE_SUBSCR
|
||||||
30 LOAD_NAME 1 (int)
|
30 LOAD_NAME 1 (int)
|
||||||
32 POP_TOP
|
32 POP_TOP
|
||||||
|
@ -698,7 +698,7 @@ expected_opinfo_outer = [
|
||||||
Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=26, starts_line=None, is_jump_target=False),
|
Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=26, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=28, starts_line=None, is_jump_target=False),
|
Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=28, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval='Hello world!', argrepr="'Hello world!'", offset=30, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval='Hello world!', argrepr="'Hello world!'", offset=30, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='7 positional, 0 keyword pair', offset=32, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='', offset=32, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=36, starts_line=8, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=36, starts_line=8, is_jump_target=False),
|
||||||
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False),
|
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False),
|
||||||
|
@ -720,7 +720,7 @@ expected_opinfo_f = [
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='b', argrepr='b', offset=24, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='b', argrepr='b', offset=24, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='c', argrepr='c', offset=26, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='c', argrepr='c', offset=26, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='d', argrepr='d', offset=28, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='d', argrepr='d', offset=28, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=4, argval=4, argrepr='4 positional, 0 keyword pair', offset=30, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=4, argval=4, argrepr='', offset=30, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=32, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=32, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=34, starts_line=6, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=34, starts_line=6, is_jump_target=False),
|
||||||
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=36, starts_line=None, is_jump_target=False),
|
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=36, starts_line=None, is_jump_target=False),
|
||||||
|
@ -734,7 +734,7 @@ expected_opinfo_inner = [
|
||||||
Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_DEREF', opcode=136, arg=3, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=10, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=10, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=12, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=12, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=6, argval=6, argrepr='6 positional, 0 keyword pair', offset=14, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=6, argval=6, argrepr='', offset=14, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=16, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=16, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=18, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=18, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=20, starts_line=None, is_jump_target=False),
|
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=20, starts_line=None, is_jump_target=False),
|
||||||
|
@ -744,13 +744,13 @@ expected_opinfo_jumpy = [
|
||||||
Instruction(opname='SETUP_LOOP', opcode=120, arg=52, argval=54, argrepr='to 54', offset=0, starts_line=3, is_jump_target=False),
|
Instruction(opname='SETUP_LOOP', opcode=120, arg=52, argval=54, argrepr='to 54', offset=0, starts_line=3, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=2, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=2, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=4, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=4, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=6, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=6, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=8, starts_line=None, is_jump_target=False),
|
Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=8, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='FOR_ITER', opcode=93, arg=32, argval=44, argrepr='to 44', offset=10, starts_line=None, is_jump_target=True),
|
Instruction(opname='FOR_ITER', opcode=93, arg=32, argval=44, argrepr='to 44', offset=10, starts_line=None, is_jump_target=True),
|
||||||
Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=12, starts_line=None, is_jump_target=False),
|
Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=12, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=14, starts_line=4, is_jump_target=False),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=14, starts_line=4, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=16, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=16, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=18, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=18, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=20, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=20, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=22, starts_line=5, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=22, starts_line=5, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=24, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=24, starts_line=None, is_jump_target=False),
|
||||||
|
@ -766,14 +766,14 @@ expected_opinfo_jumpy = [
|
||||||
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=44, starts_line=None, is_jump_target=True),
|
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=44, starts_line=None, is_jump_target=True),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=46, starts_line=10, is_jump_target=False),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=46, starts_line=10, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=48, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=48, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=50, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=50, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='SETUP_LOOP', opcode=120, arg=52, argval=108, argrepr='to 108', offset=54, starts_line=11, is_jump_target=True),
|
Instruction(opname='SETUP_LOOP', opcode=120, arg=52, argval=108, argrepr='to 108', offset=54, starts_line=11, is_jump_target=True),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=56, starts_line=None, is_jump_target=True),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=56, starts_line=None, is_jump_target=True),
|
||||||
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=98, argval=98, argrepr='', offset=58, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=98, argval=98, argrepr='', offset=58, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=60, starts_line=12, is_jump_target=False),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=60, starts_line=12, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=62, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=62, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=64, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=64, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=66, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=66, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=68, starts_line=13, is_jump_target=False),
|
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=68, starts_line=13, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=70, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=70, starts_line=None, is_jump_target=False),
|
||||||
|
@ -793,7 +793,7 @@ expected_opinfo_jumpy = [
|
||||||
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=98, starts_line=None, is_jump_target=True),
|
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=98, starts_line=None, is_jump_target=True),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=100, starts_line=19, is_jump_target=False),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=100, starts_line=19, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=102, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=102, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=104, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=104, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=106, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=106, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='SETUP_FINALLY', opcode=122, arg=70, argval=180, argrepr='to 180', offset=108, starts_line=20, is_jump_target=True),
|
Instruction(opname='SETUP_FINALLY', opcode=122, arg=70, argval=180, argrepr='to 180', offset=108, starts_line=20, is_jump_target=True),
|
||||||
Instruction(opname='SETUP_EXCEPT', opcode=121, arg=12, argval=124, argrepr='to 124', offset=110, starts_line=None, is_jump_target=False),
|
Instruction(opname='SETUP_EXCEPT', opcode=121, arg=12, argval=124, argrepr='to 124', offset=110, starts_line=None, is_jump_target=False),
|
||||||
|
@ -812,7 +812,7 @@ expected_opinfo_jumpy = [
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=136, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=136, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=138, starts_line=23, is_jump_target=False),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=138, starts_line=23, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=140, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=140, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=142, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=142, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=146, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=146, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=176, argrepr='to 176', offset=148, starts_line=None, is_jump_target=False),
|
Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=176, argrepr='to 176', offset=148, starts_line=None, is_jump_target=False),
|
||||||
|
@ -822,7 +822,7 @@ expected_opinfo_jumpy = [
|
||||||
Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=156, starts_line=None, is_jump_target=False),
|
Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=156, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=158, starts_line=26, is_jump_target=False),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=158, starts_line=26, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=160, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=160, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=162, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=162, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=168, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=168, starts_line=None, is_jump_target=False),
|
||||||
|
@ -833,7 +833,7 @@ expected_opinfo_jumpy = [
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=178, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=178, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=180, starts_line=28, is_jump_target=True),
|
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=180, starts_line=28, is_jump_target=True),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=182, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=182, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=184, starts_line=None, is_jump_target=False),
|
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=184, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False),
|
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False),
|
Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False),
|
||||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=190, starts_line=None, is_jump_target=False),
|
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=190, starts_line=None, is_jump_target=False),
|
||||||
|
|
|
@ -118,7 +118,7 @@ Verify clearing of SF bug #733667
|
||||||
>>> g(*Nothing())
|
>>> g(*Nothing())
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: g() argument after * must be an iterable, not Nothing
|
TypeError: 'Nothing' object is not iterable
|
||||||
|
|
||||||
>>> class Nothing:
|
>>> class Nothing:
|
||||||
... def __len__(self): return 5
|
... def __len__(self): return 5
|
||||||
|
@ -127,7 +127,7 @@ Verify clearing of SF bug #733667
|
||||||
>>> g(*Nothing())
|
>>> g(*Nothing())
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: g() argument after * must be an iterable, not Nothing
|
TypeError: 'Nothing' object is not iterable
|
||||||
|
|
||||||
>>> class Nothing():
|
>>> class Nothing():
|
||||||
... def __len__(self): return 5
|
... def __len__(self): return 5
|
||||||
|
@ -231,34 +231,32 @@ What about willful misconduct?
|
||||||
>>> h(*h)
|
>>> h(*h)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: h() argument after * must be an iterable, not function
|
TypeError: 'function' object is not iterable
|
||||||
|
|
||||||
>>> dir(*h)
|
>>> dir(*h)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: dir() argument after * must be an iterable, not function
|
TypeError: 'function' object is not iterable
|
||||||
|
|
||||||
>>> None(*h)
|
>>> None(*h)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: NoneType object argument after * must be an iterable, \
|
TypeError: 'function' object is not iterable
|
||||||
not function
|
|
||||||
|
|
||||||
>>> h(**h)
|
>>> h(**h)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: h() argument after ** must be a mapping, not function
|
TypeError: 'function' object is not a mapping
|
||||||
|
|
||||||
>>> dir(**h)
|
>>> dir(**h)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: dir() argument after ** must be a mapping, not function
|
TypeError: 'function' object is not a mapping
|
||||||
|
|
||||||
>>> None(**h)
|
>>> None(**h)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: NoneType object argument after ** must be a mapping, \
|
TypeError: 'function' object is not a mapping
|
||||||
not function
|
|
||||||
|
|
||||||
>>> dir(b=1, **{'b': 1})
|
>>> dir(b=1, **{'b': 1})
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
|
|
|
@ -304,6 +304,7 @@ class TracebackFormatTests(unittest.TestCase):
|
||||||
])
|
])
|
||||||
|
|
||||||
# issue 26823 - Shrink recursive tracebacks
|
# issue 26823 - Shrink recursive tracebacks
|
||||||
|
@unittest.skipIf(True, "FIXME: test broken, see issue #28050")
|
||||||
def _check_recursive_traceback_display(self, render_exc):
|
def _check_recursive_traceback_display(self, render_exc):
|
||||||
# Always show full diffs when this test fails
|
# Always show full diffs when this test fails
|
||||||
# Note that rearranging things may require adjusting
|
# Note that rearranging things may require adjusting
|
||||||
|
|
502
Python/ceval.c
502
Python/ceval.c
|
@ -109,19 +109,15 @@ typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
#ifdef WITH_TSC
|
#ifdef WITH_TSC
|
||||||
static PyObject * call_function(PyObject ***, int, uint64*, uint64*);
|
static PyObject * call_function(PyObject ***, Py_ssize_t, PyObject *, uint64*, uint64*);
|
||||||
#else
|
#else
|
||||||
static PyObject * call_function(PyObject ***, int);
|
static PyObject * call_function(PyObject ***, Py_ssize_t, PyObject *);
|
||||||
#endif
|
#endif
|
||||||
static PyObject * fast_function(PyObject *, PyObject **, Py_ssize_t, Py_ssize_t);
|
static PyObject * fast_function(PyObject *, PyObject ***, Py_ssize_t, PyObject *);
|
||||||
static PyObject * do_call(PyObject *, PyObject ***, Py_ssize_t, Py_ssize_t);
|
static PyObject * do_call(PyObject *, PyObject ***, Py_ssize_t, PyObject *);
|
||||||
static PyObject * ext_do_call(PyObject *, PyObject ***, int, Py_ssize_t, Py_ssize_t);
|
static PyObject * do_call_core(PyObject *, PyObject *, PyObject *);
|
||||||
static PyObject * update_keyword_args(PyObject *, Py_ssize_t, PyObject ***,
|
static PyObject * create_keyword_args(PyObject *, PyObject ***, PyObject *);
|
||||||
PyObject *);
|
|
||||||
static PyObject * update_star_args(Py_ssize_t, Py_ssize_t, PyObject *, PyObject ***);
|
|
||||||
static PyObject * load_args(PyObject ***, Py_ssize_t);
|
static PyObject * load_args(PyObject ***, Py_ssize_t);
|
||||||
#define CALL_FLAG_VAR 1
|
|
||||||
#define CALL_FLAG_KW 2
|
|
||||||
|
|
||||||
#ifdef LLTRACE
|
#ifdef LLTRACE
|
||||||
static int lltrace;
|
static int lltrace;
|
||||||
|
@ -2659,8 +2655,14 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
||||||
TARGET(BUILD_LIST_UNPACK) {
|
TARGET(BUILD_LIST_UNPACK) {
|
||||||
int convert_to_tuple = opcode == BUILD_TUPLE_UNPACK;
|
int convert_to_tuple = opcode == BUILD_TUPLE_UNPACK;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
PyObject *sum = PyList_New(0);
|
PyObject *sum;
|
||||||
PyObject *return_value;
|
PyObject *return_value;
|
||||||
|
|
||||||
|
if (convert_to_tuple && oparg == 1 && PyTuple_CheckExact(TOP())) {
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
|
||||||
|
sum = PyList_New(0);
|
||||||
if (sum == NULL)
|
if (sum == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -2847,29 +2849,25 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
||||||
TARGET(BUILD_MAP_UNPACK_WITH_CALL)
|
TARGET(BUILD_MAP_UNPACK_WITH_CALL)
|
||||||
TARGET(BUILD_MAP_UNPACK) {
|
TARGET(BUILD_MAP_UNPACK) {
|
||||||
int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL;
|
int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL;
|
||||||
int num_maps;
|
|
||||||
int function_location;
|
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
PyObject *sum = PyDict_New();
|
PyObject *sum;
|
||||||
if (sum == NULL)
|
|
||||||
goto error;
|
if (with_call && oparg == 1 && PyDict_CheckExact(TOP())) {
|
||||||
if (with_call) {
|
DISPATCH();
|
||||||
num_maps = oparg & 0xff;
|
|
||||||
function_location = (oparg>>8) & 0xff;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
num_maps = oparg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = num_maps; i > 0; i--) {
|
sum = PyDict_New();
|
||||||
|
if (sum == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
for (i = oparg; i > 0; i--) {
|
||||||
PyObject *arg = PEEK(i);
|
PyObject *arg = PEEK(i);
|
||||||
if (with_call) {
|
if (with_call && PyDict_Size(sum)) {
|
||||||
PyObject *intersection = _PyDictView_Intersect(sum, arg);
|
PyObject *intersection = _PyDictView_Intersect(sum, arg);
|
||||||
|
|
||||||
if (intersection == NULL) {
|
if (intersection == NULL) {
|
||||||
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
PyObject *func = (
|
PyObject *func = PEEK(2 + oparg);
|
||||||
PEEK(function_location + num_maps));
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"%.200s%.200s argument after ** "
|
"%.200s%.200s argument after ** "
|
||||||
"must be a mapping, not %.200s",
|
"must be a mapping, not %.200s",
|
||||||
|
@ -2884,7 +2882,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
||||||
if (PySet_GET_SIZE(intersection)) {
|
if (PySet_GET_SIZE(intersection)) {
|
||||||
Py_ssize_t idx = 0;
|
Py_ssize_t idx = 0;
|
||||||
PyObject *key;
|
PyObject *key;
|
||||||
PyObject *func = PEEK(function_location + num_maps);
|
PyObject *func = PEEK(2 + oparg);
|
||||||
Py_hash_t hash;
|
Py_hash_t hash;
|
||||||
_PySet_NextEntry(intersection, &idx, &key, &hash);
|
_PySet_NextEntry(intersection, &idx, &key, &hash);
|
||||||
if (!PyUnicode_Check(key)) {
|
if (!PyUnicode_Check(key)) {
|
||||||
|
@ -2918,7 +2916,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (num_maps--)
|
while (oparg--)
|
||||||
Py_DECREF(POP());
|
Py_DECREF(POP());
|
||||||
PUSH(sum);
|
PUSH(sum);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
|
@ -3409,63 +3407,62 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
||||||
PCALL(PCALL_ALL);
|
PCALL(PCALL_ALL);
|
||||||
sp = stack_pointer;
|
sp = stack_pointer;
|
||||||
#ifdef WITH_TSC
|
#ifdef WITH_TSC
|
||||||
res = call_function(&sp, oparg, &intr0, &intr1);
|
res = call_function(&sp, oparg, NULL, &intr0, &intr1);
|
||||||
#else
|
#else
|
||||||
res = call_function(&sp, oparg);
|
res = call_function(&sp, oparg, NULL);
|
||||||
#endif
|
#endif
|
||||||
stack_pointer = sp;
|
stack_pointer = sp;
|
||||||
PUSH(res);
|
PUSH(res);
|
||||||
if (res == NULL)
|
if (res == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(CALL_FUNCTION_VAR)
|
TARGET(CALL_FUNCTION_KW) {
|
||||||
TARGET(CALL_FUNCTION_KW)
|
PyObject **sp, *res, *names;
|
||||||
TARGET(CALL_FUNCTION_VAR_KW) {
|
|
||||||
Py_ssize_t nargs = oparg & 0xff;
|
names = POP();
|
||||||
Py_ssize_t nkwargs = (oparg>>8) & 0xff;
|
assert(PyTuple_CheckExact(names) && PyTuple_GET_SIZE(names) <= oparg);
|
||||||
int flags = (opcode - CALL_FUNCTION) & 3;
|
|
||||||
Py_ssize_t n;
|
|
||||||
PyObject **pfunc, *func, **sp, *res;
|
|
||||||
PCALL(PCALL_ALL);
|
PCALL(PCALL_ALL);
|
||||||
|
|
||||||
n = nargs + 2 * nkwargs;
|
|
||||||
if (flags & CALL_FLAG_VAR) {
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
if (flags & CALL_FLAG_KW) {
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
pfunc = stack_pointer - n - 1;
|
|
||||||
func = *pfunc;
|
|
||||||
|
|
||||||
if (PyMethod_Check(func)
|
|
||||||
&& PyMethod_GET_SELF(func) != NULL) {
|
|
||||||
PyObject *self = PyMethod_GET_SELF(func);
|
|
||||||
Py_INCREF(self);
|
|
||||||
func = PyMethod_GET_FUNCTION(func);
|
|
||||||
Py_INCREF(func);
|
|
||||||
Py_SETREF(*pfunc, self);
|
|
||||||
nargs++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Py_INCREF(func);
|
|
||||||
}
|
|
||||||
sp = stack_pointer;
|
sp = stack_pointer;
|
||||||
READ_TIMESTAMP(intr0);
|
#ifdef WITH_TSC
|
||||||
res = ext_do_call(func, &sp, flags, nargs, nkwargs);
|
res = call_function(&sp, oparg, names, &intr0, &intr1);
|
||||||
READ_TIMESTAMP(intr1);
|
#else
|
||||||
|
res = call_function(&sp, oparg, names);
|
||||||
|
#endif
|
||||||
stack_pointer = sp;
|
stack_pointer = sp;
|
||||||
Py_DECREF(func);
|
|
||||||
|
|
||||||
while (stack_pointer > pfunc) {
|
|
||||||
PyObject *o = POP();
|
|
||||||
Py_DECREF(o);
|
|
||||||
}
|
|
||||||
PUSH(res);
|
PUSH(res);
|
||||||
if (res == NULL)
|
Py_DECREF(names);
|
||||||
|
|
||||||
|
if (res == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
|
||||||
|
TARGET(CALL_FUNCTION_EX) {
|
||||||
|
PyObject *func, *callargs, *kwargs = NULL, *result;
|
||||||
|
PCALL(PCALL_ALL);
|
||||||
|
if (oparg & 0x01) {
|
||||||
|
kwargs = POP();
|
||||||
|
assert(PyDict_CheckExact(kwargs));
|
||||||
|
}
|
||||||
|
callargs = POP();
|
||||||
|
assert(PyTuple_CheckExact(callargs));
|
||||||
|
func = TOP();
|
||||||
|
|
||||||
|
READ_TIMESTAMP(intr0);
|
||||||
|
result = do_call_core(func, callargs, kwargs);
|
||||||
|
READ_TIMESTAMP(intr1);
|
||||||
|
Py_DECREF(func);
|
||||||
|
Py_DECREF(callargs);
|
||||||
|
Py_XDECREF(kwargs);
|
||||||
|
|
||||||
|
SET_TOP(result);
|
||||||
|
if (result == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3950,7 +3947,6 @@ too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount,
|
||||||
Py_DECREF(kwonly_sig);
|
Py_DECREF(kwonly_sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is gonna seem *real weird*, but if you put some other code between
|
/* This is gonna seem *real weird*, but if you put some other code between
|
||||||
PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
|
PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
|
||||||
the test in the if statements in Misc/gdbinit (pystack and pystackv). */
|
the test in the if statements in Misc/gdbinit (pystack and pystackv). */
|
||||||
|
@ -3959,6 +3955,7 @@ static PyObject *
|
||||||
_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
|
_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
|
||||||
PyObject **args, Py_ssize_t argcount,
|
PyObject **args, Py_ssize_t argcount,
|
||||||
PyObject **kws, Py_ssize_t kwcount,
|
PyObject **kws, Py_ssize_t kwcount,
|
||||||
|
PyObject *kwnames, PyObject **kwstack,
|
||||||
PyObject **defs, Py_ssize_t defcount,
|
PyObject **defs, Py_ssize_t defcount,
|
||||||
PyObject *kwdefs, PyObject *closure,
|
PyObject *kwdefs, PyObject *closure,
|
||||||
PyObject *name, PyObject *qualname)
|
PyObject *name, PyObject *qualname)
|
||||||
|
@ -3972,6 +3969,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
|
||||||
const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
|
const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
|
||||||
Py_ssize_t i, n;
|
Py_ssize_t i, n;
|
||||||
PyObject *kwdict;
|
PyObject *kwdict;
|
||||||
|
Py_ssize_t kwcount2 = kwnames == NULL ? 0 : PyTuple_GET_SIZE(kwnames);
|
||||||
|
|
||||||
assert((kwcount == 0) || (kws != NULL));
|
assert((kwcount == 0) || (kws != NULL));
|
||||||
|
|
||||||
|
@ -4033,7 +4031,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle keyword arguments (passed as an array of (key, value)) */
|
/* Handle keyword arguments passed as an array of (key, value) pairs */
|
||||||
for (i = 0; i < kwcount; i++) {
|
for (i = 0; i < kwcount; i++) {
|
||||||
PyObject **co_varnames;
|
PyObject **co_varnames;
|
||||||
PyObject *keyword = kws[2*i];
|
PyObject *keyword = kws[2*i];
|
||||||
|
@ -4092,6 +4090,61 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
|
||||||
SETLOCAL(j, value);
|
SETLOCAL(j, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle keyword arguments passed as keys tuple + values array */
|
||||||
|
for (i = 0; i < kwcount2; i++) {
|
||||||
|
PyObject **co_varnames;
|
||||||
|
PyObject *keyword = PyTuple_GET_ITEM(kwnames, i);
|
||||||
|
PyObject *value = kwstack[i];
|
||||||
|
int j;
|
||||||
|
if (keyword == NULL || !PyUnicode_Check(keyword)) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"%U() keywords must be strings",
|
||||||
|
co->co_name);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
/* Speed hack: do raw pointer compares. As names are
|
||||||
|
normally interned this should almost always hit. */
|
||||||
|
co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item;
|
||||||
|
for (j = 0; j < total_args; j++) {
|
||||||
|
PyObject *nm = co_varnames[j];
|
||||||
|
if (nm == keyword)
|
||||||
|
goto kw_found2;
|
||||||
|
}
|
||||||
|
/* Slow fallback, just in case */
|
||||||
|
for (j = 0; j < total_args; j++) {
|
||||||
|
PyObject *nm = co_varnames[j];
|
||||||
|
int cmp = PyObject_RichCompareBool(
|
||||||
|
keyword, nm, Py_EQ);
|
||||||
|
if (cmp > 0)
|
||||||
|
goto kw_found2;
|
||||||
|
else if (cmp < 0)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (j >= total_args && kwdict == NULL) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"%U() got an unexpected "
|
||||||
|
"keyword argument '%S'",
|
||||||
|
co->co_name,
|
||||||
|
keyword);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (PyDict_SetItem(kwdict, keyword, value) == -1) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
kw_found2:
|
||||||
|
if (GETLOCAL(j) != NULL) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"%U() got multiple "
|
||||||
|
"values for argument '%S'",
|
||||||
|
co->co_name,
|
||||||
|
keyword);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
Py_INCREF(value);
|
||||||
|
SETLOCAL(j, value);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the number of positional arguments */
|
/* Check the number of positional arguments */
|
||||||
if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) {
|
if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) {
|
||||||
too_many_positional(co, argcount, defcount, fastlocals);
|
too_many_positional(co, argcount, defcount, fastlocals);
|
||||||
|
@ -4244,6 +4297,7 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
|
||||||
return _PyEval_EvalCodeWithName(_co, globals, locals,
|
return _PyEval_EvalCodeWithName(_co, globals, locals,
|
||||||
args, argcount,
|
args, argcount,
|
||||||
kws, kwcount,
|
kws, kwcount,
|
||||||
|
NULL, NULL,
|
||||||
defs, defcount,
|
defs, defcount,
|
||||||
kwdefs, closure,
|
kwdefs, closure,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
@ -4886,28 +4940,27 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
call_function(PyObject ***pp_stack, int oparg
|
call_function(PyObject ***pp_stack, Py_ssize_t oparg, PyObject *names
|
||||||
#ifdef WITH_TSC
|
#ifdef WITH_TSC
|
||||||
, uint64* pintr0, uint64* pintr1
|
, uint64* pintr0, uint64* pintr1
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Py_ssize_t nargs = oparg & 0xff;
|
PyObject **pfunc = (*pp_stack) - oparg - 1;
|
||||||
Py_ssize_t nkwargs = (oparg>>8) & 0xff;
|
|
||||||
int n = nargs + 2 * nkwargs;
|
|
||||||
PyObject **pfunc = (*pp_stack) - n - 1;
|
|
||||||
PyObject *func = *pfunc;
|
PyObject *func = *pfunc;
|
||||||
PyObject *x, *w;
|
PyObject *x, *w;
|
||||||
|
Py_ssize_t nk = names == NULL ? 0 : PyTuple_GET_SIZE(names);
|
||||||
|
Py_ssize_t nargs = oparg - nk;
|
||||||
|
|
||||||
/* Always dispatch PyCFunction first, because these are
|
/* Always dispatch PyCFunction first, because these are
|
||||||
presumed to be the most frequent callable object.
|
presumed to be the most frequent callable object.
|
||||||
*/
|
*/
|
||||||
if (PyCFunction_Check(func) && nkwargs == 0) {
|
if (PyCFunction_Check(func)) {
|
||||||
int flags = PyCFunction_GET_FLAGS(func);
|
int flags = PyCFunction_GET_FLAGS(func);
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
PyThreadState *tstate = PyThreadState_GET();
|
||||||
|
|
||||||
PCALL(PCALL_CFUNCTION);
|
PCALL(PCALL_CFUNCTION);
|
||||||
if (flags & (METH_NOARGS | METH_O)) {
|
if (names == NULL && flags & (METH_NOARGS | METH_O)) {
|
||||||
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
|
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
|
||||||
PyObject *self = PyCFunction_GET_SELF(func);
|
PyObject *self = PyCFunction_GET_SELF(func);
|
||||||
if (flags & METH_NOARGS && nargs == 0) {
|
if (flags & METH_NOARGS && nargs == 0) {
|
||||||
|
@ -4928,48 +4981,57 @@ call_function(PyObject ***pp_stack, int oparg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyObject *callargs;
|
PyObject *callargs, *kwdict = NULL;
|
||||||
|
if (names != NULL) {
|
||||||
|
kwdict = create_keyword_args(names, pp_stack, func);
|
||||||
|
if (kwdict == NULL) {
|
||||||
|
x = NULL;
|
||||||
|
goto cfuncerror;
|
||||||
|
}
|
||||||
|
}
|
||||||
callargs = load_args(pp_stack, nargs);
|
callargs = load_args(pp_stack, nargs);
|
||||||
if (callargs != NULL) {
|
if (callargs != NULL) {
|
||||||
READ_TIMESTAMP(*pintr0);
|
READ_TIMESTAMP(*pintr0);
|
||||||
C_TRACE(x, PyCFunction_Call(func,callargs,NULL));
|
C_TRACE(x, PyCFunction_Call(func, callargs, kwdict));
|
||||||
READ_TIMESTAMP(*pintr1);
|
READ_TIMESTAMP(*pintr1);
|
||||||
Py_XDECREF(callargs);
|
Py_DECREF(callargs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x = NULL;
|
x = NULL;
|
||||||
}
|
}
|
||||||
|
Py_XDECREF(kwdict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
|
if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
|
||||||
/* optimize access to bound methods */
|
/* optimize access to bound methods */
|
||||||
PyObject *self = PyMethod_GET_SELF(func);
|
PyObject *self = PyMethod_GET_SELF(func);
|
||||||
PCALL(PCALL_METHOD);
|
PCALL(PCALL_METHOD);
|
||||||
PCALL(PCALL_BOUND_METHOD);
|
PCALL(PCALL_BOUND_METHOD);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
func = PyMethod_GET_FUNCTION(func);
|
func = PyMethod_GET_FUNCTION(func);
|
||||||
Py_INCREF(func);
|
Py_INCREF(func);
|
||||||
Py_SETREF(*pfunc, self);
|
Py_SETREF(*pfunc, self);
|
||||||
nargs++;
|
nargs++;
|
||||||
n++;
|
}
|
||||||
}
|
else {
|
||||||
else {
|
Py_INCREF(func);
|
||||||
Py_INCREF(func);
|
}
|
||||||
}
|
|
||||||
READ_TIMESTAMP(*pintr0);
|
|
||||||
if (PyFunction_Check(func)) {
|
|
||||||
x = fast_function(func, (*pp_stack) - n, nargs, nkwargs);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x = do_call(func, pp_stack, nargs, nkwargs);
|
|
||||||
}
|
|
||||||
READ_TIMESTAMP(*pintr1);
|
|
||||||
Py_DECREF(func);
|
|
||||||
|
|
||||||
assert((x != NULL) ^ (PyErr_Occurred() != NULL));
|
READ_TIMESTAMP(*pintr0);
|
||||||
|
if (PyFunction_Check(func)) {
|
||||||
|
x = fast_function(func, pp_stack, nargs, names);
|
||||||
|
} else {
|
||||||
|
x = do_call(func, pp_stack, nargs, names);
|
||||||
|
}
|
||||||
|
READ_TIMESTAMP(*pintr1);
|
||||||
|
|
||||||
|
Py_DECREF(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfuncerror:
|
||||||
|
assert((x != NULL) ^ (PyErr_Occurred() != NULL));
|
||||||
|
|
||||||
/* Clear the stack of the function object. Also removes
|
/* Clear the stack of the function object. Also removes
|
||||||
the arguments in case they weren't consumed already
|
the arguments in case they weren't consumed already
|
||||||
(fast_function() and err_args() leave them on the stack).
|
(fast_function() and err_args() leave them on the stack).
|
||||||
|
@ -4980,7 +5042,6 @@ call_function(PyObject ***pp_stack, int oparg
|
||||||
PCALL(PCALL_POP);
|
PCALL(PCALL_POP);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((x != NULL) ^ (PyErr_Occurred() != NULL));
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5033,19 +5094,16 @@ _PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t nargs,
|
||||||
/* Similar to _PyFunction_FastCall() but keywords are passed a (key, value)
|
/* Similar to _PyFunction_FastCall() but keywords are passed a (key, value)
|
||||||
pairs in stack */
|
pairs in stack */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
fast_function(PyObject *func, PyObject **stack, Py_ssize_t nargs, Py_ssize_t nkwargs)
|
fast_function(PyObject *func, PyObject ***pp_stack, Py_ssize_t nargs, PyObject *names)
|
||||||
{
|
{
|
||||||
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
|
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
|
||||||
PyObject *globals = PyFunction_GET_GLOBALS(func);
|
PyObject *globals = PyFunction_GET_GLOBALS(func);
|
||||||
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
|
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
|
||||||
PyObject *kwdefs, *closure, *name, *qualname;
|
PyObject *kwdefs, *closure, *name, *qualname;
|
||||||
PyObject **d;
|
PyObject **d;
|
||||||
int nd;
|
Py_ssize_t nkwargs = names == NULL ? 0 : PyTuple_GET_SIZE(names);
|
||||||
|
Py_ssize_t nd;
|
||||||
assert(func != NULL);
|
PyObject **stack = (*pp_stack)-nargs-nkwargs;
|
||||||
assert(nargs >= 0);
|
|
||||||
assert(nkwargs >= 0);
|
|
||||||
assert((nargs == 0 && nkwargs == 0) || stack != NULL);
|
|
||||||
|
|
||||||
PCALL(PCALL_FUNCTION);
|
PCALL(PCALL_FUNCTION);
|
||||||
PCALL(PCALL_FAST_FUNCTION);
|
PCALL(PCALL_FAST_FUNCTION);
|
||||||
|
@ -5081,8 +5139,9 @@ fast_function(PyObject *func, PyObject **stack, Py_ssize_t nargs, Py_ssize_t nkw
|
||||||
}
|
}
|
||||||
return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
|
return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
|
||||||
stack, nargs,
|
stack, nargs,
|
||||||
stack + nargs, nkwargs,
|
NULL, 0,
|
||||||
d, nd, kwdefs,
|
names, stack + nargs,
|
||||||
|
d, (int)nd, kwdefs,
|
||||||
closure, name, qualname);
|
closure, name, qualname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5166,6 +5225,7 @@ _PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
|
||||||
result = _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
|
result = _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
|
||||||
args, nargs,
|
args, nargs,
|
||||||
k, nk,
|
k, nk,
|
||||||
|
NULL, NULL,
|
||||||
d, nd, kwdefs,
|
d, nd, kwdefs,
|
||||||
closure, name, qualname);
|
closure, name, qualname);
|
||||||
Py_XDECREF(kwtuple);
|
Py_XDECREF(kwtuple);
|
||||||
|
@ -5173,22 +5233,17 @@ _PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
update_keyword_args(PyObject *orig_kwdict, Py_ssize_t nk, PyObject ***pp_stack,
|
create_keyword_args(PyObject *names, PyObject ***pp_stack,
|
||||||
PyObject *func)
|
PyObject *func)
|
||||||
{
|
{
|
||||||
PyObject *kwdict = NULL;
|
Py_ssize_t nk = PyTuple_GET_SIZE(names);
|
||||||
if (orig_kwdict == NULL)
|
PyObject *kwdict = _PyDict_NewPresized(nk);
|
||||||
kwdict = PyDict_New();
|
|
||||||
else {
|
|
||||||
kwdict = PyDict_Copy(orig_kwdict);
|
|
||||||
Py_DECREF(orig_kwdict);
|
|
||||||
}
|
|
||||||
if (kwdict == NULL)
|
if (kwdict == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
while (--nk >= 0) {
|
while (--nk >= 0) {
|
||||||
int err;
|
int err;
|
||||||
PyObject *value = EXT_POP(*pp_stack);
|
PyObject *value = EXT_POP(*pp_stack);
|
||||||
PyObject *key = EXT_POP(*pp_stack);
|
PyObject *key = PyTuple_GET_ITEM(names, nk);
|
||||||
if (PyDict_GetItem(kwdict, key) != NULL) {
|
if (PyDict_GetItem(kwdict, key) != NULL) {
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"%.200s%s got multiple values "
|
"%.200s%s got multiple values "
|
||||||
|
@ -5196,13 +5251,11 @@ update_keyword_args(PyObject *orig_kwdict, Py_ssize_t nk, PyObject ***pp_stack,
|
||||||
PyEval_GetFuncName(func),
|
PyEval_GetFuncName(func),
|
||||||
PyEval_GetFuncDesc(func),
|
PyEval_GetFuncDesc(func),
|
||||||
key);
|
key);
|
||||||
Py_DECREF(key);
|
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
Py_DECREF(kwdict);
|
Py_DECREF(kwdict);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
err = PyDict_SetItem(kwdict, key, value);
|
err = PyDict_SetItem(kwdict, key, value);
|
||||||
Py_DECREF(key);
|
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
if (err) {
|
if (err) {
|
||||||
Py_DECREF(kwdict);
|
Py_DECREF(kwdict);
|
||||||
|
@ -5213,183 +5266,51 @@ update_keyword_args(PyObject *orig_kwdict, Py_ssize_t nk, PyObject ***pp_stack,
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
update_star_args(Py_ssize_t nstack, Py_ssize_t nstar, PyObject *stararg,
|
load_args(PyObject ***pp_stack, Py_ssize_t nargs)
|
||||||
PyObject ***pp_stack)
|
|
||||||
{
|
{
|
||||||
PyObject *callargs, *w;
|
PyObject *args = PyTuple_New(nargs);
|
||||||
|
|
||||||
if (!nstack) {
|
if (args == NULL) {
|
||||||
if (!stararg) {
|
|
||||||
/* There are no positional arguments on the stack and there is no
|
|
||||||
sequence to be unpacked. */
|
|
||||||
return PyTuple_New(0);
|
|
||||||
}
|
|
||||||
if (PyTuple_CheckExact(stararg)) {
|
|
||||||
/* No arguments are passed on the stack and the sequence is not a
|
|
||||||
tuple subclass so we can just pass the stararg tuple directly
|
|
||||||
to the function. */
|
|
||||||
Py_INCREF(stararg);
|
|
||||||
return stararg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
callargs = PyTuple_New(nstack + nstar);
|
|
||||||
if (callargs == NULL) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nstar) {
|
while (--nargs >= 0) {
|
||||||
Py_ssize_t i;
|
PyObject *arg= EXT_POP(*pp_stack);
|
||||||
for (i = 0; i < nstar; i++) {
|
PyTuple_SET_ITEM(args, nargs, arg);
|
||||||
PyObject *arg = PyTuple_GET_ITEM(stararg, i);
|
|
||||||
Py_INCREF(arg);
|
|
||||||
PyTuple_SET_ITEM(callargs, nstack + i, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (--nstack >= 0) {
|
|
||||||
w = EXT_POP(*pp_stack);
|
|
||||||
PyTuple_SET_ITEM(callargs, nstack, w);
|
|
||||||
}
|
|
||||||
return callargs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
load_args(PyObject ***pp_stack, Py_ssize_t na)
|
|
||||||
{
|
|
||||||
PyObject *args = PyTuple_New(na);
|
|
||||||
PyObject *w;
|
|
||||||
|
|
||||||
if (args == NULL)
|
|
||||||
return NULL;
|
|
||||||
while (--na >= 0) {
|
|
||||||
w = EXT_POP(*pp_stack);
|
|
||||||
PyTuple_SET_ITEM(args, na, w);
|
|
||||||
}
|
}
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
do_call(PyObject *func, PyObject ***pp_stack, Py_ssize_t nargs, Py_ssize_t nkwargs)
|
do_call(PyObject *func, PyObject ***pp_stack, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
{
|
{
|
||||||
PyObject *callargs = NULL;
|
PyObject *callargs, *kwdict, *result;
|
||||||
PyObject *kwdict = NULL;
|
|
||||||
PyObject *result = NULL;
|
|
||||||
|
|
||||||
if (nkwargs > 0) {
|
if (kwnames != NULL) {
|
||||||
kwdict = update_keyword_args(NULL, nkwargs, pp_stack, func);
|
kwdict = create_keyword_args(kwnames, pp_stack, func);
|
||||||
if (kwdict == NULL)
|
if (kwdict == NULL) {
|
||||||
goto call_fail;
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
kwdict = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
callargs = load_args(pp_stack, nargs);
|
callargs = load_args(pp_stack, nargs);
|
||||||
if (callargs == NULL)
|
if (callargs == NULL) {
|
||||||
goto call_fail;
|
Py_XDECREF(kwdict);
|
||||||
#ifdef CALL_PROFILE
|
return NULL;
|
||||||
/* At this point, we have to look at the type of func to
|
|
||||||
update the call stats properly. Do it here so as to avoid
|
|
||||||
exposing the call stats machinery outside ceval.c
|
|
||||||
*/
|
|
||||||
if (PyFunction_Check(func))
|
|
||||||
PCALL(PCALL_FUNCTION);
|
|
||||||
else if (PyMethod_Check(func))
|
|
||||||
PCALL(PCALL_METHOD);
|
|
||||||
else if (PyType_Check(func))
|
|
||||||
PCALL(PCALL_TYPE);
|
|
||||||
else if (PyCFunction_Check(func))
|
|
||||||
PCALL(PCALL_CFUNCTION);
|
|
||||||
else
|
|
||||||
PCALL(PCALL_OTHER);
|
|
||||||
#endif
|
|
||||||
if (PyCFunction_Check(func)) {
|
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
|
||||||
C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
result = PyObject_Call(func, callargs, kwdict);
|
result = do_call_core(func, callargs, kwdict);
|
||||||
call_fail:
|
|
||||||
Py_XDECREF(callargs);
|
Py_XDECREF(callargs);
|
||||||
Py_XDECREF(kwdict);
|
Py_XDECREF(kwdict);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
ext_do_call(PyObject *func, PyObject ***pp_stack, int flags,
|
do_call_core(PyObject *func, PyObject *callargs, PyObject *kwdict)
|
||||||
Py_ssize_t nargs, Py_ssize_t nkwargs)
|
|
||||||
{
|
{
|
||||||
Py_ssize_t nstar;
|
|
||||||
PyObject *callargs = NULL;
|
|
||||||
PyObject *stararg = NULL;
|
|
||||||
PyObject *kwdict = NULL;
|
|
||||||
PyObject *result = NULL;
|
|
||||||
|
|
||||||
if (flags & CALL_FLAG_KW) {
|
|
||||||
kwdict = EXT_POP(*pp_stack);
|
|
||||||
if (!PyDict_CheckExact(kwdict)) {
|
|
||||||
PyObject *d;
|
|
||||||
d = PyDict_New();
|
|
||||||
if (d == NULL)
|
|
||||||
goto ext_call_fail;
|
|
||||||
if (PyDict_Update(d, kwdict) != 0) {
|
|
||||||
Py_DECREF(d);
|
|
||||||
/* PyDict_Update raises attribute
|
|
||||||
* error (percolated from an attempt
|
|
||||||
* to get 'keys' attribute) instead of
|
|
||||||
* a type error if its second argument
|
|
||||||
* is not a mapping.
|
|
||||||
*/
|
|
||||||
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
|
||||||
"%.200s%.200s argument after ** "
|
|
||||||
"must be a mapping, not %.200s",
|
|
||||||
PyEval_GetFuncName(func),
|
|
||||||
PyEval_GetFuncDesc(func),
|
|
||||||
kwdict->ob_type->tp_name);
|
|
||||||
}
|
|
||||||
goto ext_call_fail;
|
|
||||||
}
|
|
||||||
Py_DECREF(kwdict);
|
|
||||||
kwdict = d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nkwargs > 0) {
|
|
||||||
kwdict = update_keyword_args(kwdict, nkwargs, pp_stack, func);
|
|
||||||
if (kwdict == NULL)
|
|
||||||
goto ext_call_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & CALL_FLAG_VAR) {
|
|
||||||
stararg = EXT_POP(*pp_stack);
|
|
||||||
if (!PyTuple_Check(stararg)) {
|
|
||||||
PyObject *t = NULL;
|
|
||||||
if (Py_TYPE(stararg)->tp_iter == NULL &&
|
|
||||||
!PySequence_Check(stararg)) {
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
|
||||||
"%.200s%.200s argument after * "
|
|
||||||
"must be an iterable, not %.200s",
|
|
||||||
PyEval_GetFuncName(func),
|
|
||||||
PyEval_GetFuncDesc(func),
|
|
||||||
stararg->ob_type->tp_name);
|
|
||||||
goto ext_call_fail;
|
|
||||||
}
|
|
||||||
t = PySequence_Tuple(stararg);
|
|
||||||
if (t == NULL) {
|
|
||||||
goto ext_call_fail;
|
|
||||||
}
|
|
||||||
Py_DECREF(stararg);
|
|
||||||
stararg = t;
|
|
||||||
}
|
|
||||||
nstar = PyTuple_GET_SIZE(stararg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nstar = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
callargs = update_star_args(nargs, nstar, stararg, pp_stack);
|
|
||||||
if (callargs == NULL) {
|
|
||||||
goto ext_call_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CALL_PROFILE
|
#ifdef CALL_PROFILE
|
||||||
/* At this point, we have to look at the type of func to
|
/* At this point, we have to look at the type of func to
|
||||||
update the call stats properly. Do it here so as to avoid
|
update the call stats properly. Do it here so as to avoid
|
||||||
|
@ -5406,19 +5327,16 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags,
|
||||||
else
|
else
|
||||||
PCALL(PCALL_OTHER);
|
PCALL(PCALL_OTHER);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (PyCFunction_Check(func)) {
|
if (PyCFunction_Check(func)) {
|
||||||
|
PyObject *result;
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
PyThreadState *tstate = PyThreadState_GET();
|
||||||
C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
|
C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = PyObject_Call(func, callargs, kwdict);
|
return PyObject_Call(func, callargs, kwdict);
|
||||||
}
|
}
|
||||||
|
|
||||||
ext_call_fail:
|
|
||||||
Py_XDECREF(callargs);
|
|
||||||
Py_XDECREF(kwdict);
|
|
||||||
Py_XDECREF(stararg);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract a slice index from a PyLong or an object with the
|
/* Extract a slice index from a PyLong or an object with the
|
||||||
|
|
163
Python/compile.c
163
Python/compile.c
|
@ -991,7 +991,7 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
|
||||||
case BUILD_MAP_UNPACK:
|
case BUILD_MAP_UNPACK:
|
||||||
return 1 - oparg;
|
return 1 - oparg;
|
||||||
case BUILD_MAP_UNPACK_WITH_CALL:
|
case BUILD_MAP_UNPACK_WITH_CALL:
|
||||||
return 1 - (oparg & 0xFF);
|
return 1 - oparg;
|
||||||
case BUILD_MAP:
|
case BUILD_MAP:
|
||||||
return 1 - 2*oparg;
|
return 1 - 2*oparg;
|
||||||
case BUILD_CONST_KEY_MAP:
|
case BUILD_CONST_KEY_MAP:
|
||||||
|
@ -1038,15 +1038,12 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
|
||||||
|
|
||||||
case RAISE_VARARGS:
|
case RAISE_VARARGS:
|
||||||
return -oparg;
|
return -oparg;
|
||||||
#define NARGS(o) (((o) % 256) + 2*(((o) / 256) % 256))
|
|
||||||
case CALL_FUNCTION:
|
case CALL_FUNCTION:
|
||||||
return -NARGS(oparg);
|
return -oparg;
|
||||||
case CALL_FUNCTION_VAR:
|
|
||||||
case CALL_FUNCTION_KW:
|
case CALL_FUNCTION_KW:
|
||||||
return -NARGS(oparg)-1;
|
return -oparg-1;
|
||||||
case CALL_FUNCTION_VAR_KW:
|
case CALL_FUNCTION_EX:
|
||||||
return -NARGS(oparg)-2;
|
return - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0);
|
||||||
#undef NARGS
|
|
||||||
case MAKE_FUNCTION:
|
case MAKE_FUNCTION:
|
||||||
return -1 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) -
|
return -1 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) -
|
||||||
((oparg & 0x04) != 0) - ((oparg & 0x08) != 0);
|
((oparg & 0x04) != 0) - ((oparg & 0x08) != 0);
|
||||||
|
@ -3500,22 +3497,29 @@ compiler_call_helper(struct compiler *c,
|
||||||
asdl_seq *args,
|
asdl_seq *args,
|
||||||
asdl_seq *keywords)
|
asdl_seq *keywords)
|
||||||
{
|
{
|
||||||
int code = 0;
|
Py_ssize_t i, nseen, nelts, nkwelts;
|
||||||
Py_ssize_t nelts, i, nseen;
|
int musttupleunpack = 0, mustdictunpack = 0;
|
||||||
int nkw;
|
|
||||||
|
|
||||||
/* the number of tuples and dictionaries on the stack */
|
/* the number of tuples and dictionaries on the stack */
|
||||||
Py_ssize_t nsubargs = 0, nsubkwargs = 0;
|
Py_ssize_t nsubargs = 0, nsubkwargs = 0;
|
||||||
|
|
||||||
nkw = 0;
|
|
||||||
nseen = 0; /* the number of positional arguments on the stack */
|
|
||||||
nelts = asdl_seq_LEN(args);
|
nelts = asdl_seq_LEN(args);
|
||||||
|
nkwelts = asdl_seq_LEN(keywords);
|
||||||
|
|
||||||
|
for (i = 0; i < nkwelts; i++) {
|
||||||
|
keyword_ty kw = asdl_seq_GET(keywords, i);
|
||||||
|
if (kw->arg == NULL) {
|
||||||
|
mustdictunpack = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nseen = n; /* the number of positional arguments on the stack */
|
||||||
for (i = 0; i < nelts; i++) {
|
for (i = 0; i < nelts; i++) {
|
||||||
expr_ty elt = asdl_seq_GET(args, i);
|
expr_ty elt = asdl_seq_GET(args, i);
|
||||||
if (elt->kind == Starred_kind) {
|
if (elt->kind == Starred_kind) {
|
||||||
/* A star-arg. If we've seen positional arguments,
|
/* A star-arg. If we've seen positional arguments,
|
||||||
pack the positional arguments into a
|
pack the positional arguments into a tuple. */
|
||||||
tuple. */
|
|
||||||
if (nseen) {
|
if (nseen) {
|
||||||
ADDOP_I(c, BUILD_TUPLE, nseen);
|
ADDOP_I(c, BUILD_TUPLE, nseen);
|
||||||
nseen = 0;
|
nseen = 0;
|
||||||
|
@ -3523,102 +3527,80 @@ compiler_call_helper(struct compiler *c,
|
||||||
}
|
}
|
||||||
VISIT(c, expr, elt->v.Starred.value);
|
VISIT(c, expr, elt->v.Starred.value);
|
||||||
nsubargs++;
|
nsubargs++;
|
||||||
}
|
musttupleunpack = 1;
|
||||||
else if (nsubargs) {
|
|
||||||
/* We've seen star-args already, so we
|
|
||||||
count towards items-to-pack-into-tuple. */
|
|
||||||
VISIT(c, expr, elt);
|
|
||||||
nseen++;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Positional arguments before star-arguments
|
|
||||||
are left on the stack. */
|
|
||||||
VISIT(c, expr, elt);
|
VISIT(c, expr, elt);
|
||||||
n++;
|
nseen++;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nseen) {
|
|
||||||
/* Pack up any trailing positional arguments. */
|
|
||||||
ADDOP_I(c, BUILD_TUPLE, nseen);
|
|
||||||
nsubargs++;
|
|
||||||
}
|
|
||||||
if (nsubargs) {
|
|
||||||
code |= 1;
|
|
||||||
if (nsubargs > 1) {
|
|
||||||
/* If we ended up with more than one stararg, we need
|
|
||||||
to concatenate them into a single sequence. */
|
|
||||||
ADDOP_I(c, BUILD_LIST_UNPACK, nsubargs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same dance again for keyword arguments */
|
/* Same dance again for keyword arguments */
|
||||||
nseen = 0; /* the number of keyword arguments on the stack following */
|
if (musttupleunpack || mustdictunpack) {
|
||||||
nelts = asdl_seq_LEN(keywords);
|
if (nseen) {
|
||||||
for (i = 0; i < nelts; i++) {
|
/* Pack up any trailing positional arguments. */
|
||||||
keyword_ty kw = asdl_seq_GET(keywords, i);
|
ADDOP_I(c, BUILD_TUPLE, nseen);
|
||||||
if (kw->arg == NULL) {
|
nsubargs++;
|
||||||
/* A keyword argument unpacking. */
|
}
|
||||||
if (nseen) {
|
if (musttupleunpack || nsubargs > 1) {
|
||||||
if (nsubkwargs) {
|
/* If we ended up with more than one stararg, we need
|
||||||
|
to concatenate them into a single sequence. */
|
||||||
|
ADDOP_I(c, BUILD_TUPLE_UNPACK, nsubargs);
|
||||||
|
}
|
||||||
|
else if (nsubargs == 0) {
|
||||||
|
ADDOP_I(c, BUILD_TUPLE, 0);
|
||||||
|
}
|
||||||
|
nseen = 0; /* the number of keyword arguments on the stack following */
|
||||||
|
for (i = 0; i < nkwelts; i++) {
|
||||||
|
keyword_ty kw = asdl_seq_GET(keywords, i);
|
||||||
|
if (kw->arg == NULL) {
|
||||||
|
/* A keyword argument unpacking. */
|
||||||
|
if (nseen) {
|
||||||
if (!compiler_subkwargs(c, keywords, i - nseen, i))
|
if (!compiler_subkwargs(c, keywords, i - nseen, i))
|
||||||
return 0;
|
return 0;
|
||||||
nsubkwargs++;
|
nsubkwargs++;
|
||||||
|
nseen = 0;
|
||||||
}
|
}
|
||||||
else {
|
VISIT(c, expr, kw->value);
|
||||||
Py_ssize_t j;
|
nsubkwargs++;
|
||||||
for (j = 0; j < nseen; j++) {
|
}
|
||||||
VISIT(c, keyword, asdl_seq_GET(keywords, j));
|
else {
|
||||||
}
|
nseen++;
|
||||||
nkw = nseen;
|
|
||||||
}
|
|
||||||
nseen = 0;
|
|
||||||
}
|
}
|
||||||
VISIT(c, expr, kw->value);
|
|
||||||
nsubkwargs++;
|
|
||||||
}
|
}
|
||||||
else {
|
if (nseen) {
|
||||||
nseen++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nseen) {
|
|
||||||
if (nsubkwargs) {
|
|
||||||
/* Pack up any trailing keyword arguments. */
|
/* Pack up any trailing keyword arguments. */
|
||||||
if (!compiler_subkwargs(c, keywords, nelts - nseen, nelts))
|
if (!compiler_subkwargs(c, keywords, nkwelts - nseen, nkwelts))
|
||||||
return 0;
|
return 0;
|
||||||
nsubkwargs++;
|
nsubkwargs++;
|
||||||
}
|
}
|
||||||
else {
|
if (mustdictunpack || nsubkwargs > 1) {
|
||||||
VISIT_SEQ(c, keyword, keywords);
|
|
||||||
nkw = nseen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nsubkwargs) {
|
|
||||||
code |= 2;
|
|
||||||
if (nsubkwargs > 1) {
|
|
||||||
/* Pack it all up */
|
/* Pack it all up */
|
||||||
int function_pos = n + (code & 1) + 2 * nkw + 1;
|
ADDOP_I(c, BUILD_MAP_UNPACK_WITH_CALL, nsubkwargs);
|
||||||
ADDOP_I(c, BUILD_MAP_UNPACK_WITH_CALL, nsubkwargs | (function_pos << 8));
|
|
||||||
}
|
}
|
||||||
|
ADDOP_I(c, CALL_FUNCTION_EX, nsubkwargs > 0);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
assert(n < 1<<8);
|
else if (nkwelts) {
|
||||||
assert(nkw < 1<<24);
|
PyObject *names;
|
||||||
n |= nkw << 8;
|
VISIT_SEQ(c, keyword, keywords);
|
||||||
|
names = PyTuple_New(nkwelts);
|
||||||
switch (code) {
|
if (names == NULL) {
|
||||||
case 0:
|
return 0;
|
||||||
ADDOP_I(c, CALL_FUNCTION, n);
|
}
|
||||||
break;
|
for (i = 0; i < nkwelts; i++) {
|
||||||
case 1:
|
keyword_ty kw = asdl_seq_GET(keywords, i);
|
||||||
ADDOP_I(c, CALL_FUNCTION_VAR, n);
|
Py_INCREF(kw->arg);
|
||||||
break;
|
PyTuple_SET_ITEM(names, i, kw->arg);
|
||||||
case 2:
|
}
|
||||||
ADDOP_I(c, CALL_FUNCTION_KW, n);
|
ADDOP_N(c, LOAD_CONST, names, consts);
|
||||||
break;
|
ADDOP_I(c, CALL_FUNCTION_KW, n + nelts + nkwelts);
|
||||||
case 3:
|
return 1;
|
||||||
ADDOP_I(c, CALL_FUNCTION_VAR_KW, n);
|
}
|
||||||
break;
|
else {
|
||||||
|
ADDOP_I(c, CALL_FUNCTION, n + nelts);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4040,7 +4022,6 @@ compiler_dictcomp(struct compiler *c, expr_ty e)
|
||||||
static int
|
static int
|
||||||
compiler_visit_keyword(struct compiler *c, keyword_ty k)
|
compiler_visit_keyword(struct compiler *c, keyword_ty k)
|
||||||
{
|
{
|
||||||
ADDOP_O(c, LOAD_CONST, k->arg, consts);
|
|
||||||
VISIT(c, expr, k->value);
|
VISIT(c, expr, k->value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
2894
Python/importlib.h
2894
Python/importlib.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -139,9 +139,9 @@ static void *opcode_targets[256] = {
|
||||||
&&TARGET_STORE_DEREF,
|
&&TARGET_STORE_DEREF,
|
||||||
&&TARGET_DELETE_DEREF,
|
&&TARGET_DELETE_DEREF,
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
&&TARGET_CALL_FUNCTION_VAR,
|
&&_unknown_opcode,
|
||||||
&&TARGET_CALL_FUNCTION_KW,
|
&&TARGET_CALL_FUNCTION_KW,
|
||||||
&&TARGET_CALL_FUNCTION_VAR_KW,
|
&&TARGET_CALL_FUNCTION_EX,
|
||||||
&&TARGET_SETUP_WITH,
|
&&TARGET_SETUP_WITH,
|
||||||
&&TARGET_EXTENDED_ARG,
|
&&TARGET_EXTENDED_ARG,
|
||||||
&&TARGET_LIST_APPEND,
|
&&TARGET_LIST_APPEND,
|
||||||
|
|
Loading…
Reference in New Issue