Skip to content

Commit be2779c

Browse files
authored
gh-105481: add flags to each instr in the opcode metadata table, to replace opcode.hasarg/hasname/hasconst (#105482)
1 parent 2211454 commit be2779c

File tree

6 files changed

+679
-623
lines changed

6 files changed

+679
-623
lines changed

Python/bytecodes.c

+27-25
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ dummy_func(
210210
}
211211

212212
inst(LOAD_CONST, (-- value)) {
213-
value = GETITEM(frame->f_code->co_consts, oparg);
213+
value = GETITEM(FRAME_CO_CONSTS, oparg);
214214
Py_INCREF(value);
215215
}
216216

@@ -711,7 +711,7 @@ dummy_func(
711711
}
712712

713713
inst(RETURN_CONST, (--)) {
714-
PyObject *retval = GETITEM(frame->f_code->co_consts, oparg);
714+
PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg);
715715
Py_INCREF(retval);
716716
assert(EMPTY());
717717
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -727,7 +727,7 @@ dummy_func(
727727
}
728728

729729
inst(INSTRUMENTED_RETURN_CONST, (--)) {
730-
PyObject *retval = GETITEM(frame->f_code->co_consts, oparg);
730+
PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg);
731731
int err = _Py_call_instrumentation_arg(
732732
tstate, PY_MONITORING_EVENT_PY_RETURN,
733733
frame, next_instr-1, retval);
@@ -924,6 +924,7 @@ dummy_func(
924924

925925
inst(INSTRUMENTED_YIELD_VALUE, (retval -- unused)) {
926926
assert(frame != &entry_frame);
927+
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
927928
PyGenObject *gen = _PyFrame_GetGenerator(frame);
928929
gen->gi_frame_state = FRAME_SUSPENDED;
929930
_PyFrame_SetStackPointer(frame, stack_pointer - 1);
@@ -945,6 +946,7 @@ dummy_func(
945946
// NOTE: It's important that YIELD_VALUE never raises an exception!
946947
// The compiler treats any exception raised here as a failed close()
947948
// or throw() call.
949+
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
948950
assert(frame != &entry_frame);
949951
PyGenObject *gen = _PyFrame_GetGenerator(frame);
950952
gen->gi_frame_state = FRAME_SUSPENDED;
@@ -1040,7 +1042,7 @@ dummy_func(
10401042

10411043

10421044
inst(STORE_NAME, (v -- )) {
1043-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
1045+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
10441046
PyObject *ns = LOCALS();
10451047
int err;
10461048
if (ns == NULL) {
@@ -1058,7 +1060,7 @@ dummy_func(
10581060
}
10591061

10601062
inst(DELETE_NAME, (--)) {
1061-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
1063+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
10621064
PyObject *ns = LOCALS();
10631065
int err;
10641066
if (ns == NULL) {
@@ -1150,7 +1152,7 @@ dummy_func(
11501152
inst(STORE_ATTR, (counter/1, unused/3, v, owner --)) {
11511153
#if ENABLE_SPECIALIZATION
11521154
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
1153-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
1155+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
11541156
next_instr--;
11551157
_Py_Specialize_StoreAttr(owner, next_instr, name);
11561158
DISPATCH_SAME_OPARG();
@@ -1161,28 +1163,28 @@ dummy_func(
11611163
#else
11621164
(void)counter; // Unused.
11631165
#endif /* ENABLE_SPECIALIZATION */
1164-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
1166+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
11651167
int err = PyObject_SetAttr(owner, name, v);
11661168
DECREF_INPUTS();
11671169
ERROR_IF(err, error);
11681170
}
11691171

11701172
inst(DELETE_ATTR, (owner --)) {
1171-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
1173+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
11721174
int err = PyObject_SetAttr(owner, name, (PyObject *)NULL);
11731175
DECREF_INPUTS();
11741176
ERROR_IF(err, error);
11751177
}
11761178

11771179
inst(STORE_GLOBAL, (v --)) {
1178-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
1180+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
11791181
int err = PyDict_SetItem(GLOBALS(), name, v);
11801182
DECREF_INPUTS();
11811183
ERROR_IF(err, error);
11821184
}
11831185

11841186
inst(DELETE_GLOBAL, (--)) {
1185-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
1187+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
11861188
int err;
11871189
err = PyDict_DelItem(GLOBALS(), name);
11881190
// Can't use ERROR_IF here.
@@ -1208,7 +1210,7 @@ dummy_func(
12081210
macro(LOAD_LOCALS) = _LOAD_LOCALS;
12091211

12101212
op(_LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) {
1211-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
1213+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
12121214
if (PyDict_CheckExact(mod_or_class_dict)) {
12131215
v = PyDict_GetItemWithError(mod_or_class_dict, name);
12141216
if (v != NULL) {
@@ -1280,15 +1282,15 @@ dummy_func(
12801282
#if ENABLE_SPECIALIZATION
12811283
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
12821284
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
1283-
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
1285+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
12841286
next_instr--;
12851287
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
12861288
DISPATCH_SAME_OPARG();
12871289
}
12881290
STAT_INC(LOAD_GLOBAL, deferred);
12891291
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
12901292
#endif /* ENABLE_SPECIALIZATION */
1291-
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
1293+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
12921294
if (PyDict_CheckExact(GLOBALS())
12931295
&& PyDict_CheckExact(BUILTINS()))
12941296
{
@@ -1630,7 +1632,7 @@ dummy_func(
16301632
};
16311633

16321634
inst(LOAD_SUPER_ATTR, (unused/1, global_super, class, self -- res2 if (oparg & 1), res)) {
1633-
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
1635+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
16341636
int load_method = oparg & 1;
16351637
#if ENABLE_SPECIALIZATION
16361638
_PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr;
@@ -1695,7 +1697,7 @@ dummy_func(
16951697
DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR);
16961698
DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
16971699
STAT_INC(LOAD_SUPER_ATTR, hit);
1698-
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
1700+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
16991701
res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL);
17001702
DECREF_INPUTS();
17011703
ERROR_IF(res == NULL, error);
@@ -1706,7 +1708,7 @@ dummy_func(
17061708
DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR);
17071709
DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
17081710
STAT_INC(LOAD_SUPER_ATTR, hit);
1709-
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
1711+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
17101712
PyTypeObject *cls = (PyTypeObject *)class;
17111713
int method_found = 0;
17121714
res2 = _PySuper_Lookup(cls, self, name,
@@ -1744,15 +1746,15 @@ dummy_func(
17441746
#if ENABLE_SPECIALIZATION
17451747
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
17461748
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
1747-
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
1749+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
17481750
next_instr--;
17491751
_Py_Specialize_LoadAttr(owner, next_instr, name);
17501752
DISPATCH_SAME_OPARG();
17511753
}
17521754
STAT_INC(LOAD_ATTR, deferred);
17531755
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
17541756
#endif /* ENABLE_SPECIALIZATION */
1755-
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1);
1757+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
17561758
if (oparg & 1) {
17571759
/* Designed to work in tandem with CALL, pushes two values. */
17581760
PyObject* meth = NULL;
@@ -1834,7 +1836,7 @@ dummy_func(
18341836
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
18351837
DEOPT_IF(dict == NULL, LOAD_ATTR);
18361838
assert(PyDict_CheckExact((PyObject *)dict));
1837-
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
1839+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
18381840
uint16_t hint = index;
18391841
DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR);
18401842
if (DK_IS_UNICODE(dict->ma_keys)) {
@@ -1922,7 +1924,7 @@ dummy_func(
19221924
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR);
19231925
STAT_INC(LOAD_ATTR, hit);
19241926

1925-
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1);
1927+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
19261928
Py_INCREF(f);
19271929
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2);
19281930
// Manipulate stack directly because we exit with DISPATCH_INLINED().
@@ -1966,7 +1968,7 @@ dummy_func(
19661968
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
19671969
DEOPT_IF(dict == NULL, STORE_ATTR);
19681970
assert(PyDict_CheckExact((PyObject *)dict));
1969-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
1971+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
19701972
DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR);
19711973
PyObject *old_value;
19721974
uint64_t new_version;
@@ -2126,14 +2128,14 @@ dummy_func(
21262128
}
21272129

21282130
inst(IMPORT_NAME, (level, fromlist -- res)) {
2129-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
2131+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
21302132
res = import_name(tstate, frame, name, fromlist, level);
21312133
DECREF_INPUTS();
21322134
ERROR_IF(res == NULL, error);
21332135
}
21342136

21352137
inst(IMPORT_FROM, (from -- from, res)) {
2136-
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
2138+
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
21372139
res = import_from(tstate, from, name);
21382140
ERROR_IF(res == NULL, error);
21392141
}
@@ -2637,8 +2639,8 @@ dummy_func(
26372639

26382640
inst(KW_NAMES, (--)) {
26392641
assert(kwnames == NULL);
2640-
assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts));
2641-
kwnames = GETITEM(frame->f_code->co_consts, oparg);
2642+
assert(oparg < PyTuple_GET_SIZE(FRAME_CO_CONSTS));
2643+
kwnames = GETITEM(FRAME_CO_CONSTS, oparg);
26422644
}
26432645

26442646
inst(INSTRUMENTED_CALL, ( -- )) {

Python/ceval_macros.h

+5
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,11 @@ GETITEM(PyObject *v, Py_ssize_t i) {
219219
#define STACK_SHRINK(n) BASIC_STACKADJ(-(n))
220220
#endif
221221

222+
223+
/* Data access macros */
224+
#define FRAME_CO_CONSTS (frame->f_code->co_consts)
225+
#define FRAME_CO_NAMES (frame->f_code->co_names)
226+
222227
/* Local variable macros */
223228

224229
#define GETLOCAL(i) (frame->localsplus[i])

Python/compile.c

+2
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ instr_sequence_use_label(instr_sequence *seq, int lbl) {
248248
static int
249249
instr_sequence_addop(instr_sequence *seq, int opcode, int oparg, location loc)
250250
{
251+
assert(!HAS_ARG(opcode) == !OPCODE_HAS_ARG(opcode));
252+
assert(!HAS_CONST(opcode) == !OPCODE_HAS_CONST(opcode));
251253
assert(0 <= opcode && opcode <= MAX_OPCODE);
252254
assert(IS_PSEUDO_OPCODE(opcode) == IS_PSEUDO_INSTR(opcode));
253255
assert(IS_WITHIN_OPCODE_RANGE(opcode));

0 commit comments

Comments
 (0)