Skip to content

Commit 2b94a05

Browse files
authored
gh-106581: Add 10 new opcodes by allowing assert(kwnames == NULL) (#106707)
By turning `assert(kwnames == NULL)` into a macro that is not in the "forbidden" list, many instructions that formerly were skipped because they contained such an assert (but no other mention of `kwnames`) are now supported in Tier 2. This covers 10 instructions in total (all specializations of `CALL` that invoke some C code): - `CALL_NO_KW_TYPE_1` - `CALL_NO_KW_STR_1` - `CALL_NO_KW_TUPLE_1` - `CALL_NO_KW_BUILTIN_O` - `CALL_NO_KW_BUILTIN_FAST` - `CALL_NO_KW_LEN` - `CALL_NO_KW_ISINSTANCE` - `CALL_NO_KW_METHOD_DESCRIPTOR_O` - `CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS` - `CALL_NO_KW_METHOD_DESCRIPTOR_FAST`
1 parent b2b261a commit 2b94a05

File tree

7 files changed

+385
-34
lines changed

7 files changed

+385
-34
lines changed

Include/internal/pycore_opcode_metadata.h

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/bytecodes.c

+15-15
Original file line numberDiff line numberDiff line change
@@ -2776,7 +2776,7 @@ dummy_func(
27762776
}
27772777

27782778
inst(KW_NAMES, (--)) {
2779-
assert(kwnames == NULL);
2779+
ASSERT_KWNAMES_IS_NULL();
27802780
assert(oparg < PyTuple_GET_SIZE(FRAME_CO_CONSTS));
27812781
kwnames = GETITEM(FRAME_CO_CONSTS, oparg);
27822782
}
@@ -2927,7 +2927,7 @@ dummy_func(
29272927
}
29282928

29292929
inst(CALL_PY_EXACT_ARGS, (unused/1, func_version/2, method, callable, args[oparg] -- unused)) {
2930-
assert(kwnames == NULL);
2930+
ASSERT_KWNAMES_IS_NULL();
29312931
DEOPT_IF(tstate->interp->eval_frame, CALL);
29322932
int is_meth = method != NULL;
29332933
int argcount = oparg;
@@ -2955,7 +2955,7 @@ dummy_func(
29552955
}
29562956

29572957
inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, method, callable, args[oparg] -- unused)) {
2958-
assert(kwnames == NULL);
2958+
ASSERT_KWNAMES_IS_NULL();
29592959
DEOPT_IF(tstate->interp->eval_frame, CALL);
29602960
int is_meth = method != NULL;
29612961
int argcount = oparg;
@@ -2993,7 +2993,7 @@ dummy_func(
29932993
}
29942994

29952995
inst(CALL_NO_KW_TYPE_1, (unused/1, unused/2, null, callable, args[oparg] -- res)) {
2996-
assert(kwnames == NULL);
2996+
ASSERT_KWNAMES_IS_NULL();
29972997
assert(oparg == 1);
29982998
DEOPT_IF(null != NULL, CALL);
29992999
PyObject *obj = args[0];
@@ -3005,7 +3005,7 @@ dummy_func(
30053005
}
30063006

30073007
inst(CALL_NO_KW_STR_1, (unused/1, unused/2, null, callable, args[oparg] -- res)) {
3008-
assert(kwnames == NULL);
3008+
ASSERT_KWNAMES_IS_NULL();
30093009
assert(oparg == 1);
30103010
DEOPT_IF(null != NULL, CALL);
30113011
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
@@ -3019,7 +3019,7 @@ dummy_func(
30193019
}
30203020

30213021
inst(CALL_NO_KW_TUPLE_1, (unused/1, unused/2, null, callable, args[oparg] -- res)) {
3022-
assert(kwnames == NULL);
3022+
ASSERT_KWNAMES_IS_NULL();
30233023
assert(oparg == 1);
30243024
DEOPT_IF(null != NULL, CALL);
30253025
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
@@ -3038,7 +3038,7 @@ dummy_func(
30383038
* 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``)
30393039
* 3. Pushes the frame for ``__init__`` to the frame stack
30403040
* */
3041-
assert(kwnames == NULL);
3041+
ASSERT_KWNAMES_IS_NULL();
30423042
_PyCallCache *cache = (_PyCallCache *)next_instr;
30433043
DEOPT_IF(null != NULL, CALL);
30443044
DEOPT_IF(!PyType_Check(callable), CALL);
@@ -3122,7 +3122,7 @@ dummy_func(
31223122

31233123
inst(CALL_NO_KW_BUILTIN_O, (unused/1, unused/2, method, callable, args[oparg] -- res)) {
31243124
/* Builtin METH_O functions */
3125-
assert(kwnames == NULL);
3125+
ASSERT_KWNAMES_IS_NULL();
31263126
int is_meth = method != NULL;
31273127
int total_args = oparg;
31283128
if (is_meth) {
@@ -3153,7 +3153,7 @@ dummy_func(
31533153

31543154
inst(CALL_NO_KW_BUILTIN_FAST, (unused/1, unused/2, method, callable, args[oparg] -- res)) {
31553155
/* Builtin METH_FASTCALL functions, without keywords */
3156-
assert(kwnames == NULL);
3156+
ASSERT_KWNAMES_IS_NULL();
31573157
int is_meth = method != NULL;
31583158
int total_args = oparg;
31593159
if (is_meth) {
@@ -3222,7 +3222,7 @@ dummy_func(
32223222
}
32233223

32243224
inst(CALL_NO_KW_LEN, (unused/1, unused/2, method, callable, args[oparg] -- res)) {
3225-
assert(kwnames == NULL);
3225+
ASSERT_KWNAMES_IS_NULL();
32263226
/* len(o) */
32273227
int is_meth = method != NULL;
32283228
int total_args = oparg;
@@ -3249,7 +3249,7 @@ dummy_func(
32493249
}
32503250

32513251
inst(CALL_NO_KW_ISINSTANCE, (unused/1, unused/2, method, callable, args[oparg] -- res)) {
3252-
assert(kwnames == NULL);
3252+
ASSERT_KWNAMES_IS_NULL();
32533253
/* isinstance(o, o2) */
32543254
int is_meth = method != NULL;
32553255
int total_args = oparg;
@@ -3279,7 +3279,7 @@ dummy_func(
32793279

32803280
// This is secretly a super-instruction
32813281
inst(CALL_NO_KW_LIST_APPEND, (unused/1, unused/2, method, self, args[oparg] -- unused)) {
3282-
assert(kwnames == NULL);
3282+
ASSERT_KWNAMES_IS_NULL();
32833283
assert(oparg == 1);
32843284
assert(method != NULL);
32853285
PyInterpreterState *interp = _PyInterpreterState_GET();
@@ -3299,7 +3299,7 @@ dummy_func(
32993299
}
33003300

33013301
inst(CALL_NO_KW_METHOD_DESCRIPTOR_O, (unused/1, unused/2, method, unused, args[oparg] -- res)) {
3302-
assert(kwnames == NULL);
3302+
ASSERT_KWNAMES_IS_NULL();
33033303
int is_meth = method != NULL;
33043304
int total_args = oparg;
33053305
if (is_meth) {
@@ -3365,7 +3365,7 @@ dummy_func(
33653365
}
33663366

33673367
inst(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, (unused/1, unused/2, method, unused, args[oparg] -- res)) {
3368-
assert(kwnames == NULL);
3368+
ASSERT_KWNAMES_IS_NULL();
33693369
assert(oparg == 0 || oparg == 1);
33703370
int is_meth = method != NULL;
33713371
int total_args = oparg;
@@ -3397,7 +3397,7 @@ dummy_func(
33973397
}
33983398

33993399
inst(CALL_NO_KW_METHOD_DESCRIPTOR_FAST, (unused/1, unused/2, method, unused, args[oparg] -- res)) {
3400-
assert(kwnames == NULL);
3400+
ASSERT_KWNAMES_IS_NULL();
34013401
int is_meth = method != NULL;
34023402
int total_args = oparg;
34033403
if (is_meth) {

Python/ceval.c

+4
Original file line numberDiff line numberDiff line change
@@ -2706,6 +2706,9 @@ void Py_LeaveRecursiveCall(void)
27062706

27072707
///////////////////// Experimental UOp Interpreter /////////////////////
27082708

2709+
#undef ASSERT_KWNAMES_IS_NULL
2710+
#define ASSERT_KWNAMES_IS_NULL() (void)0
2711+
27092712
#undef DEOPT_IF
27102713
#define DEOPT_IF(COND, INSTNAME) \
27112714
if ((COND)) { \
@@ -2746,6 +2749,7 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
27462749
int opcode;
27472750
uint64_t operand;
27482751
int oparg;
2752+
27492753
for (;;) {
27502754
opcode = self->trace[pc].opcode;
27512755
operand = self->trace[pc].operand;

Python/ceval_macros.h

+2
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,5 @@ static const convertion_func_ptr CONVERSION_FUNCTIONS[4] = {
349349
[FVC_REPR] = PyObject_Repr,
350350
[FVC_ASCII] = PyObject_ASCII
351351
};
352+
353+
#define ASSERT_KWNAMES_IS_NULL() assert(kwnames == NULL)

0 commit comments

Comments
 (0)