mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Issue #26110: Add LOAD_METHOD/CALL_METHOD opcodes.
Special thanks to INADA Naoki for pushing the patch through the last mile, Serhiy Storchaka for reviewing the code, and to Victor Stinner for suggesting the idea (originally implemented in the PyPy project).
This commit is contained in:
parent
e6bb53bf61
commit
f2392133eb
13 changed files with 747 additions and 483 deletions
|
@ -1040,6 +1040,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
|
|||
return -oparg;
|
||||
case CALL_FUNCTION:
|
||||
return -oparg;
|
||||
case CALL_METHOD:
|
||||
return -oparg-1;
|
||||
case CALL_FUNCTION_KW:
|
||||
return -oparg-1;
|
||||
case CALL_FUNCTION_EX:
|
||||
|
@ -1078,6 +1080,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
|
|||
/* If there's a fmt_spec on the stack, we go from 2->1,
|
||||
else 1->1. */
|
||||
return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0;
|
||||
case LOAD_METHOD:
|
||||
return 1;
|
||||
default:
|
||||
return PY_INVALID_STACK_EFFECT;
|
||||
}
|
||||
|
@ -3399,9 +3403,42 @@ compiler_compare(struct compiler *c, expr_ty e)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
maybe_optimize_method_call(struct compiler *c, expr_ty e)
|
||||
{
|
||||
Py_ssize_t argsl, i;
|
||||
expr_ty meth = e->v.Call.func;
|
||||
asdl_seq *args = e->v.Call.args;
|
||||
|
||||
/* Check that the call node is an attribute access, and that
|
||||
the call doesn't have keyword parameters. */
|
||||
if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load ||
|
||||
asdl_seq_LEN(e->v.Call.keywords))
|
||||
return -1;
|
||||
|
||||
/* Check that there are no *varargs types of arguments. */
|
||||
argsl = asdl_seq_LEN(args);
|
||||
for (i = 0; i < argsl; i++) {
|
||||
expr_ty elt = asdl_seq_GET(args, i);
|
||||
if (elt->kind == Starred_kind) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Alright, we can optimize the code. */
|
||||
VISIT(c, expr, meth->v.Attribute.value);
|
||||
ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names);
|
||||
VISIT_SEQ(c, expr, e->v.Call.args);
|
||||
ADDOP_I(c, CALL_METHOD, asdl_seq_LEN(e->v.Call.args));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
compiler_call(struct compiler *c, expr_ty e)
|
||||
{
|
||||
if (maybe_optimize_method_call(c, e) > 0)
|
||||
return 1;
|
||||
|
||||
VISIT(c, expr, e->v.Call.func);
|
||||
return compiler_call_helper(c, 0,
|
||||
e->v.Call.args,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue