mirror of
https://github.com/python/cpython.git
synced 2025-07-16 07:45:20 +00:00
bpo-46329: Change calling sequence (again) (GH-31373)
* Change calling sequence: Add PUSH_NULL. Merge PRECALL_FUNCTION and PRECALL_METHOD into PRECALL.
This commit is contained in:
parent
e2c28616ce
commit
cf345e945f
13 changed files with 365 additions and 344 deletions
|
@ -1584,7 +1584,7 @@ pop_frame(PyThreadState *tstate, InterpreterFrame *frame)
|
|||
return prev_frame;
|
||||
}
|
||||
|
||||
/* It is only between a PRECALL_METHOD/FUNCTION instruction and the following CALL,
|
||||
/* It is only between the PRECALL instruction and the following CALL,
|
||||
* that these values have any meaning.
|
||||
*/
|
||||
typedef struct {
|
||||
|
@ -1872,6 +1872,12 @@ handle_eval_breaker:
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(PUSH_NULL) {
|
||||
/* Use BASIC_PUSH as NULL is not a valid object pointer */
|
||||
BASIC_PUSH(NULL);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(UNARY_POSITIVE) {
|
||||
PyObject *value = TOP();
|
||||
PyObject *res = PyNumber_Positive(value);
|
||||
|
@ -4476,25 +4482,7 @@ handle_eval_breaker:
|
|||
NOTRACE_DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(PRECALL_FUNCTION) {
|
||||
/* Move ownership of reference from stack to call_shape */
|
||||
call_shape.callable = PEEK(oparg + 1);
|
||||
call_shape.postcall_shrink = 1;
|
||||
|
||||
call_shape.total_args = oparg;
|
||||
assert(call_shape.kwnames == NULL);
|
||||
#ifdef Py_STATS
|
||||
extern int _PySpecialization_ClassifyCallable(PyObject *);
|
||||
SpecializationStats *stats =
|
||||
&_py_stats.opcode_stats[PRECALL_FUNCTION].specialization;
|
||||
stats->failure++;
|
||||
int kind = _PySpecialization_ClassifyCallable(call_shape.callable);
|
||||
stats->failure_kinds[kind]++;
|
||||
#endif
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(PRECALL_METHOD) {
|
||||
TARGET(PRECALL) {
|
||||
/* Designed to work in tamdem with LOAD_METHOD. */
|
||||
/* `meth` is NULL when LOAD_METHOD thinks that it's not
|
||||
a method call.
|
||||
|
@ -4533,7 +4521,7 @@ handle_eval_breaker:
|
|||
#ifdef Py_STATS
|
||||
extern int _PySpecialization_ClassifyCallable(PyObject *);
|
||||
SpecializationStats *stats =
|
||||
&_py_stats.opcode_stats[PRECALL_METHOD].specialization;
|
||||
&_py_stats.opcode_stats[PRECALL].specialization;
|
||||
stats->failure++;
|
||||
int kind = _PySpecialization_ClassifyCallable(call_shape.callable);
|
||||
stats->failure_kinds[kind]++;
|
||||
|
@ -5118,6 +5106,8 @@ handle_eval_breaker:
|
|||
Py_DECREF(callargs);
|
||||
Py_XDECREF(kwargs);
|
||||
|
||||
STACK_SHRINK(1);
|
||||
assert(TOP() == NULL);
|
||||
SET_TOP(result);
|
||||
if (result == NULL) {
|
||||
goto error;
|
||||
|
|
|
@ -1012,17 +1012,15 @@ stack_effect(int opcode, int oparg, int jump)
|
|||
return -oparg;
|
||||
|
||||
/* Functions and calls */
|
||||
case PRECALL_METHOD:
|
||||
return -oparg-1;
|
||||
case PRECALL_FUNCTION:
|
||||
case PRECALL:
|
||||
return -oparg;
|
||||
case KW_NAMES:
|
||||
return 0;
|
||||
case CALL:
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
case CALL_FUNCTION_EX:
|
||||
return -1 - ((oparg & 0x01) != 0);
|
||||
return -2 - ((oparg & 0x01) != 0);
|
||||
case MAKE_FUNCTION:
|
||||
return 0 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) -
|
||||
((oparg & 0x04) != 0) - ((oparg & 0x08) != 0);
|
||||
|
@ -1084,6 +1082,7 @@ stack_effect(int opcode, int oparg, int jump)
|
|||
case MATCH_KEYS:
|
||||
return 1;
|
||||
case COPY:
|
||||
case PUSH_NULL:
|
||||
return 1;
|
||||
case BINARY_OP:
|
||||
return -1;
|
||||
|
@ -1800,7 +1799,7 @@ compiler_call_exit_with_nones(struct compiler *c) {
|
|||
ADDOP_LOAD_CONST(c, Py_None);
|
||||
ADDOP_LOAD_CONST(c, Py_None);
|
||||
ADDOP_LOAD_CONST(c, Py_None);
|
||||
ADDOP_I(c, PRECALL_FUNCTION, 3);
|
||||
ADDOP_I(c, PRECALL, 2);
|
||||
ADDOP_I(c, CALL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
@ -2178,7 +2177,7 @@ compiler_apply_decorators(struct compiler *c, asdl_expr_seq* decos)
|
|||
int old_end_col_offset = c->u->u_end_col_offset;
|
||||
for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
|
||||
SET_LOC(c, (expr_ty)asdl_seq_GET(decos, i));
|
||||
ADDOP_I(c, PRECALL_FUNCTION, 1);
|
||||
ADDOP_I(c, PRECALL, 0);
|
||||
ADDOP_I(c, CALL, 0);
|
||||
}
|
||||
c->u->u_lineno = old_lineno;
|
||||
|
@ -2630,6 +2629,7 @@ compiler_class(struct compiler *c, stmt_ty s)
|
|||
return 0;
|
||||
|
||||
/* 2. load the 'build_class' function */
|
||||
ADDOP(c, PUSH_NULL);
|
||||
ADDOP(c, LOAD_BUILD_CLASS);
|
||||
|
||||
/* 3. load a function (or closure) made from the code object */
|
||||
|
@ -2645,7 +2645,6 @@ compiler_class(struct compiler *c, stmt_ty s)
|
|||
/* 5. generate the rest of the code for the call */
|
||||
if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, s->v.ClassDef.keywords))
|
||||
return 0;
|
||||
|
||||
/* 6. apply decorators */
|
||||
if (!compiler_apply_decorators(c, decos))
|
||||
return 0;
|
||||
|
@ -3858,7 +3857,7 @@ compiler_assert(struct compiler *c, stmt_ty s)
|
|||
ADDOP(c, LOAD_ASSERTION_ERROR);
|
||||
if (s->v.Assert.msg) {
|
||||
VISIT(c, expr, s->v.Assert.msg);
|
||||
ADDOP_I(c, PRECALL_FUNCTION, 1);
|
||||
ADDOP_I(c, PRECALL, 0);
|
||||
ADDOP_I(c, CALL, 0);
|
||||
}
|
||||
ADDOP_I(c, RAISE_VARARGS, 1);
|
||||
|
@ -4680,14 +4679,14 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
|
|||
|
||||
if (kwdsl) {
|
||||
VISIT_SEQ(c, keyword, kwds);
|
||||
ADDOP_I(c, PRECALL_METHOD, argsl + kwdsl);
|
||||
ADDOP_I(c, PRECALL, argsl + kwdsl);
|
||||
if (!compiler_call_simple_kw_helper(c, kwds, kwdsl)) {
|
||||
return 0;
|
||||
};
|
||||
ADDOP_I(c, CALL, kwdsl);
|
||||
}
|
||||
else {
|
||||
ADDOP_I(c, PRECALL_METHOD, argsl);
|
||||
ADDOP_I(c, PRECALL, argsl);
|
||||
ADDOP_I(c, CALL, 0);
|
||||
}
|
||||
c->u->u_lineno = old_lineno;
|
||||
|
@ -4731,6 +4730,9 @@ compiler_call(struct compiler *c, expr_ty e)
|
|||
if (!check_caller(c, e->v.Call.func)) {
|
||||
return 0;
|
||||
}
|
||||
SET_LOC(c, e->v.Call.func);
|
||||
ADDOP(c, PUSH_NULL);
|
||||
SET_LOC(c, e);
|
||||
VISIT(c, expr, e->v.Call.func);
|
||||
return compiler_call_helper(c, 0,
|
||||
e->v.Call.args,
|
||||
|
@ -4755,7 +4757,7 @@ compiler_joined_str(struct compiler *c, expr_ty e)
|
|||
VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
|
||||
ADDOP_I(c, LIST_APPEND, 1);
|
||||
}
|
||||
ADDOP_I(c, PRECALL_METHOD, 1);
|
||||
ADDOP_I(c, PRECALL, 1);
|
||||
ADDOP_I(c, CALL, 0);
|
||||
}
|
||||
else {
|
||||
|
@ -4925,7 +4927,7 @@ compiler_call_helper(struct compiler *c,
|
|||
}
|
||||
if (nkwelts) {
|
||||
VISIT_SEQ(c, keyword, keywords);
|
||||
ADDOP_I(c, PRECALL_FUNCTION, n + nelts + nkwelts);
|
||||
ADDOP_I(c, PRECALL, n + nelts + nkwelts);
|
||||
if (!compiler_call_simple_kw_helper(c, keywords, nkwelts)) {
|
||||
return 0;
|
||||
};
|
||||
|
@ -4933,7 +4935,7 @@ compiler_call_helper(struct compiler *c,
|
|||
return 1;
|
||||
}
|
||||
else {
|
||||
ADDOP_I(c, PRECALL_FUNCTION, n + nelts);
|
||||
ADDOP_I(c, PRECALL, n + nelts);
|
||||
ADDOP_I(c, CALL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
@ -5328,7 +5330,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
|
|||
ADDOP(c, GET_ITER);
|
||||
}
|
||||
|
||||
ADDOP_I(c, PRECALL_FUNCTION, 1);
|
||||
ADDOP_I(c, PRECALL, 0);
|
||||
ADDOP_I(c, CALL, 0);
|
||||
|
||||
if (is_async_generator && type != COMP_GENEXP) {
|
||||
|
|
38
Python/opcode_targets.h
generated
38
Python/opcode_targets.h
generated
|
@ -1,20 +1,21 @@
|
|||
static void *opcode_targets[256] = {
|
||||
&&_unknown_opcode,
|
||||
&&TARGET_POP_TOP,
|
||||
&&TARGET_PUSH_NULL,
|
||||
&&TARGET_BINARY_OP_ADAPTIVE,
|
||||
&&TARGET_BINARY_OP_ADD_INT,
|
||||
&&TARGET_BINARY_OP_ADD_FLOAT,
|
||||
&&TARGET_BINARY_OP_ADD_UNICODE,
|
||||
&&TARGET_BINARY_OP_INPLACE_ADD_UNICODE,
|
||||
&&TARGET_BINARY_OP_MULTIPLY_INT,
|
||||
&&TARGET_BINARY_OP_MULTIPLY_FLOAT,
|
||||
&&TARGET_NOP,
|
||||
&&TARGET_UNARY_POSITIVE,
|
||||
&&TARGET_UNARY_NEGATIVE,
|
||||
&&TARGET_UNARY_NOT,
|
||||
&&TARGET_BINARY_OP_MULTIPLY_FLOAT,
|
||||
&&TARGET_BINARY_OP_SUBTRACT_INT,
|
||||
&&TARGET_BINARY_OP_SUBTRACT_FLOAT,
|
||||
&&TARGET_UNARY_INVERT,
|
||||
&&TARGET_BINARY_OP_SUBTRACT_FLOAT,
|
||||
&&TARGET_COMPARE_OP_ADAPTIVE,
|
||||
&&TARGET_COMPARE_OP_FLOAT_JUMP,
|
||||
&&TARGET_COMPARE_OP_INT_JUMP,
|
||||
|
@ -23,18 +24,18 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_BINARY_SUBSCR_GETITEM,
|
||||
&&TARGET_BINARY_SUBSCR_LIST_INT,
|
||||
&&TARGET_BINARY_SUBSCR_TUPLE_INT,
|
||||
&&TARGET_BINARY_SUBSCR_DICT,
|
||||
&&TARGET_BINARY_SUBSCR,
|
||||
&&TARGET_BINARY_SUBSCR_DICT,
|
||||
&&TARGET_STORE_SUBSCR_ADAPTIVE,
|
||||
&&TARGET_STORE_SUBSCR_LIST_INT,
|
||||
&&TARGET_STORE_SUBSCR_DICT,
|
||||
&&TARGET_CALL_ADAPTIVE,
|
||||
&&TARGET_GET_LEN,
|
||||
&&TARGET_MATCH_MAPPING,
|
||||
&&TARGET_MATCH_SEQUENCE,
|
||||
&&TARGET_MATCH_KEYS,
|
||||
&&TARGET_CALL_BUILTIN_CLASS,
|
||||
&&TARGET_CALL_ADAPTIVE,
|
||||
&&TARGET_PUSH_EXC_INFO,
|
||||
&&TARGET_CALL_BUILTIN_CLASS,
|
||||
&&TARGET_CALL_NO_KW_BUILTIN_O,
|
||||
&&TARGET_CALL_NO_KW_BUILTIN_FAST,
|
||||
&&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS,
|
||||
|
@ -47,40 +48,39 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS,
|
||||
&&TARGET_CALL_NO_KW_STR_1,
|
||||
&&TARGET_CALL_NO_KW_TUPLE_1,
|
||||
&&TARGET_CALL_NO_KW_TYPE_1,
|
||||
&&TARGET_WITH_EXCEPT_START,
|
||||
&&TARGET_GET_AITER,
|
||||
&&TARGET_GET_ANEXT,
|
||||
&&TARGET_BEFORE_ASYNC_WITH,
|
||||
&&TARGET_BEFORE_WITH,
|
||||
&&TARGET_END_ASYNC_FOR,
|
||||
&&TARGET_CALL_NO_KW_TYPE_1,
|
||||
&&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_FAST,
|
||||
&&TARGET_JUMP_ABSOLUTE_QUICK,
|
||||
&&TARGET_LOAD_ATTR_ADAPTIVE,
|
||||
&&TARGET_LOAD_ATTR_INSTANCE_VALUE,
|
||||
&&TARGET_LOAD_ATTR_WITH_HINT,
|
||||
&&TARGET_STORE_SUBSCR,
|
||||
&&TARGET_DELETE_SUBSCR,
|
||||
&&TARGET_LOAD_ATTR_WITH_HINT,
|
||||
&&TARGET_LOAD_ATTR_SLOT,
|
||||
&&TARGET_LOAD_ATTR_MODULE,
|
||||
&&TARGET_LOAD_GLOBAL_ADAPTIVE,
|
||||
&&TARGET_LOAD_GLOBAL_MODULE,
|
||||
&&TARGET_LOAD_GLOBAL_BUILTIN,
|
||||
&&TARGET_LOAD_METHOD_ADAPTIVE,
|
||||
&&TARGET_GET_ITER,
|
||||
&&TARGET_GET_YIELD_FROM_ITER,
|
||||
&&TARGET_PRINT_EXPR,
|
||||
&&TARGET_LOAD_BUILD_CLASS,
|
||||
&&TARGET_LOAD_METHOD_CACHED,
|
||||
&&TARGET_LOAD_METHOD_ADAPTIVE,
|
||||
&&TARGET_GET_AWAITABLE,
|
||||
&&TARGET_LOAD_ASSERTION_ERROR,
|
||||
&&TARGET_RETURN_GENERATOR,
|
||||
&&TARGET_LOAD_METHOD_CACHED,
|
||||
&&TARGET_LOAD_METHOD_CLASS,
|
||||
&&TARGET_LOAD_METHOD_MODULE,
|
||||
&&TARGET_LOAD_METHOD_NO_DICT,
|
||||
&&TARGET_RESUME_QUICK,
|
||||
&&TARGET_STORE_ATTR_ADAPTIVE,
|
||||
&&TARGET_STORE_ATTR_INSTANCE_VALUE,
|
||||
&&TARGET_LIST_TO_TUPLE,
|
||||
&&TARGET_RETURN_VALUE,
|
||||
&&TARGET_IMPORT_STAR,
|
||||
|
@ -130,7 +130,7 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_POP_JUMP_IF_NOT_NONE,
|
||||
&&TARGET_POP_JUMP_IF_NONE,
|
||||
&&TARGET_RAISE_VARARGS,
|
||||
&&TARGET_STORE_ATTR_SLOT,
|
||||
&&TARGET_STORE_ATTR_INSTANCE_VALUE,
|
||||
&&TARGET_MAKE_FUNCTION,
|
||||
&&TARGET_BUILD_SLICE,
|
||||
&&TARGET_JUMP_NO_INTERRUPT,
|
||||
|
@ -139,35 +139,35 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_LOAD_DEREF,
|
||||
&&TARGET_STORE_DEREF,
|
||||
&&TARGET_DELETE_DEREF,
|
||||
&&TARGET_STORE_ATTR_SLOT,
|
||||
&&TARGET_STORE_ATTR_WITH_HINT,
|
||||
&&TARGET_UNPACK_SEQUENCE_ADAPTIVE,
|
||||
&&TARGET_CALL_FUNCTION_EX,
|
||||
&&TARGET_UNPACK_SEQUENCE_LIST,
|
||||
&&TARGET_UNPACK_SEQUENCE_ADAPTIVE,
|
||||
&&TARGET_EXTENDED_ARG,
|
||||
&&TARGET_LIST_APPEND,
|
||||
&&TARGET_SET_ADD,
|
||||
&&TARGET_MAP_ADD,
|
||||
&&TARGET_LOAD_CLASSDEREF,
|
||||
&&TARGET_COPY_FREE_VARS,
|
||||
&&TARGET_UNPACK_SEQUENCE_TUPLE,
|
||||
&&TARGET_UNPACK_SEQUENCE_LIST,
|
||||
&&TARGET_RESUME,
|
||||
&&TARGET_MATCH_CLASS,
|
||||
&&TARGET_UNPACK_SEQUENCE_TUPLE,
|
||||
&&TARGET_UNPACK_SEQUENCE_TWO_TUPLE,
|
||||
&&TARGET_LOAD_FAST__LOAD_FAST,
|
||||
&&TARGET_FORMAT_VALUE,
|
||||
&&TARGET_BUILD_CONST_KEY_MAP,
|
||||
&&TARGET_BUILD_STRING,
|
||||
&&TARGET_LOAD_FAST__LOAD_FAST,
|
||||
&&TARGET_STORE_FAST__LOAD_FAST,
|
||||
&&TARGET_LOAD_FAST__LOAD_CONST,
|
||||
&&TARGET_LOAD_METHOD,
|
||||
&&TARGET_LOAD_CONST__LOAD_FAST,
|
||||
&&TARGET_LOAD_FAST__LOAD_CONST,
|
||||
&&TARGET_LIST_EXTEND,
|
||||
&&TARGET_SET_UPDATE,
|
||||
&&TARGET_DICT_MERGE,
|
||||
&&TARGET_DICT_UPDATE,
|
||||
&&TARGET_PRECALL,
|
||||
&&TARGET_LOAD_CONST__LOAD_FAST,
|
||||
&&TARGET_STORE_FAST__STORE_FAST,
|
||||
&&TARGET_PRECALL_FUNCTION,
|
||||
&&TARGET_PRECALL_METHOD,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&TARGET_CALL,
|
||||
|
|
|
@ -178,8 +178,7 @@ print_spec_stats(FILE *out, OpcodeStats *stats)
|
|||
/* Mark some opcodes as specializable for stats,
|
||||
* even though we don't specialize them yet. */
|
||||
fprintf(out, "opcode[%d].specializable : 1\n", FOR_ITER);
|
||||
fprintf(out, "opcode[%d].specializable : 1\n", PRECALL_FUNCTION);
|
||||
fprintf(out, "opcode[%d].specializable : 1\n", PRECALL_METHOD);
|
||||
fprintf(out, "opcode[%d].specializable : 1\n", PRECALL);
|
||||
fprintf(out, "opcode[%d].specializable : 1\n", UNPACK_SEQUENCE);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (adaptive_opcodes[i]) {
|
||||
|
@ -1528,7 +1527,7 @@ specialize_method_descriptor(
|
|||
}
|
||||
assert(_list_append != NULL);
|
||||
if (nargs == 2 && descr == _list_append) {
|
||||
assert(_Py_OPCODE(instr[-1]) == PRECALL_METHOD);
|
||||
assert(_Py_OPCODE(instr[-1]) == PRECALL);
|
||||
cache[-1].obj.obj = (PyObject *)_list_append;
|
||||
*instr = _Py_MAKECODEUNIT(CALL_NO_KW_LIST_APPEND, _Py_OPARG(*instr));
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue