[Python-checkins] GH-100222: Redefine _Py_CODEUNIT as a union to clarify structure of code unit. (GH-100223)

markshannon webhook-mailer at python.org
Wed Dec 14 06:12:59 EST 2022


https://github.com/python/cpython/commit/6997e77bdf2297375962aaf82876da4e7ecdd61a
commit: 6997e77bdf2297375962aaf82876da4e7ecdd61a
branch: main
author: Mark Shannon <mark at hotpy.org>
committer: markshannon <mark at hotpy.org>
date: 2022-12-14T11:12:53Z
summary:

GH-100222: Redefine _Py_CODEUNIT as a union to clarify structure of code unit. (GH-100223)

files:
A Misc/NEWS.d/next/Core and Builtins/2022-12-13-16-05-18.gh-issue-100222.OVVvYe.rst
M Include/cpython/code.h
M Include/internal/pycore_code.h
M Objects/codeobject.c
M Python/ceval.c
M Python/compile.c
M Python/generated_cases.c.h
M Python/specialize.c
M Tools/cases_generator/generate_cases.py

diff --git a/Include/cpython/code.h b/Include/cpython/code.h
index fc7c5ed70243..6a13ff2dfd9f 100644
--- a/Include/cpython/code.h
+++ b/Include/cpython/code.h
@@ -16,21 +16,24 @@ extern "C" {
  * 2**32 - 1, rather than INT_MAX.
  */
 
-typedef uint16_t _Py_CODEUNIT;
-
-#ifdef WORDS_BIGENDIAN
-#  define _Py_OPCODE(word) ((word) >> 8)
-#  define _Py_OPARG(word) ((word) & 255)
-#  define _Py_MAKECODEUNIT(opcode, oparg) (((opcode)<<8)|(oparg))
-#else
-#  define _Py_OPCODE(word) ((word) & 255)
-#  define _Py_OPARG(word) ((word) >> 8)
-#  define _Py_MAKECODEUNIT(opcode, oparg) ((opcode)|((oparg)<<8))
-#endif
+typedef union {
+    uint16_t cache;
+    struct {
+        uint8_t opcode;
+        uint8_t oparg;
+    };
+} _Py_CODEUNIT;
+
+#define _Py_OPCODE(word) ((word).opcode)
+#define _Py_OPARG(word) ((word).oparg)
+
+static inline void
+_py_set_opocde(_Py_CODEUNIT *word, uint8_t opcode)
+{
+    word->opcode = opcode;
+}
 
-// Use "unsigned char" instead of "uint8_t" here to avoid illegal aliasing:
-#define _Py_SET_OPCODE(word, opcode) \
-    do { ((unsigned char *)&(word))[0] = (opcode); } while (0)
+#define _Py_SET_OPCODE(word, opcode) _py_set_opocde(&(word), opcode)
 
 typedef struct {
     PyObject *_co_code;
diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h
index f22fd45f8319..9e59fc98bf3d 100644
--- a/Include/internal/pycore_code.h
+++ b/Include/internal/pycore_code.h
@@ -18,53 +18,53 @@ extern "C" {
 #define CACHE_ENTRIES(cache) (sizeof(cache)/sizeof(_Py_CODEUNIT))
 
 typedef struct {
-    _Py_CODEUNIT counter;
-    _Py_CODEUNIT index;
-    _Py_CODEUNIT module_keys_version[2];
-    _Py_CODEUNIT builtin_keys_version;
+    uint16_t counter;
+    uint16_t index;
+    uint16_t module_keys_version[2];
+    uint16_t builtin_keys_version;
 } _PyLoadGlobalCache;
 
 #define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache)
 
 typedef struct {
-    _Py_CODEUNIT counter;
+    uint16_t counter;
 } _PyBinaryOpCache;
 
 #define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache)
 
 typedef struct {
-    _Py_CODEUNIT counter;
+    uint16_t counter;
 } _PyUnpackSequenceCache;
 
 #define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \
     CACHE_ENTRIES(_PyUnpackSequenceCache)
 
 typedef struct {
-    _Py_CODEUNIT counter;
-    _Py_CODEUNIT mask;
+    uint16_t counter;
+    uint16_t mask;
 } _PyCompareOpCache;
 
 #define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache)
 
 typedef struct {
-    _Py_CODEUNIT counter;
-    _Py_CODEUNIT type_version[2];
-    _Py_CODEUNIT func_version;
+    uint16_t counter;
+    uint16_t type_version[2];
+    uint16_t func_version;
 } _PyBinarySubscrCache;
 
 #define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache)
 
 typedef struct {
-    _Py_CODEUNIT counter;
-    _Py_CODEUNIT version[2];
-    _Py_CODEUNIT index;
+    uint16_t counter;
+    uint16_t version[2];
+    uint16_t index;
 } _PyAttrCache;
 
 typedef struct {
-    _Py_CODEUNIT counter;
-    _Py_CODEUNIT type_version[2];
-    _Py_CODEUNIT keys_version[2];
-    _Py_CODEUNIT descr[4];
+    uint16_t counter;
+    uint16_t type_version[2];
+    uint16_t keys_version[2];
+    uint16_t descr[4];
 } _PyLoadMethodCache;
 
 
@@ -74,21 +74,21 @@ typedef struct {
 #define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache)
 
 typedef struct {
-    _Py_CODEUNIT counter;
-    _Py_CODEUNIT func_version[2];
-    _Py_CODEUNIT min_args;
+    uint16_t counter;
+    uint16_t func_version[2];
+    uint16_t min_args;
 } _PyCallCache;
 
 #define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache)
 
 typedef struct {
-    _Py_CODEUNIT counter;
+    uint16_t counter;
 } _PyStoreSubscrCache;
 
 #define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache)
 
 typedef struct {
-    _Py_CODEUNIT counter;
+    uint16_t counter;
 } _PyForIterCache;
 
 #define INLINE_CACHE_ENTRIES_FOR_ITER CACHE_ENTRIES(_PyForIterCache)
@@ -409,7 +409,7 @@ write_location_entry_start(uint8_t *ptr, int code, int length)
 static inline uint16_t
 adaptive_counter_bits(int value, int backoff) {
     return (value << ADAPTIVE_BACKOFF_BITS) |
-           (backoff & ((1<<ADAPTIVE_BACKOFF_BITS)-1));
+        (backoff & ((1<<ADAPTIVE_BACKOFF_BITS)-1));
 }
 
 static inline uint16_t
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-12-13-16-05-18.gh-issue-100222.OVVvYe.rst b/Misc/NEWS.d/next/Core and Builtins/2022-12-13-16-05-18.gh-issue-100222.OVVvYe.rst
new file mode 100644
index 000000000000..032b49420d8b
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-12-13-16-05-18.gh-issue-100222.OVVvYe.rst	
@@ -0,0 +1,2 @@
+Redefine the ``_Py_CODEUNIT`` typedef as a union to describe its layout to
+the C compiler, avoiding type punning and improving clarity.
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index c92c7deaf808..f455cc603aae 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -1520,9 +1520,10 @@ deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
         _Py_CODEUNIT instruction = instructions[i];
         int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)];
         int caches = _PyOpcode_Caches[opcode];
-        instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction));
+        instructions[i].opcode = opcode;
         while (caches--) {
-            instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0);
+            instructions[++i].opcode = CACHE;
+            instructions[i].oparg = 0;
         }
     }
 }
@@ -1775,9 +1776,9 @@ code_richcompare(PyObject *self, PyObject *other, int op)
     for (int i = 0; i < Py_SIZE(co); i++) {
         _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i];
         _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i];
-        _Py_SET_OPCODE(co_instr, _PyOpcode_Deopt[_Py_OPCODE(co_instr)]);
-        _Py_SET_OPCODE(cp_instr, _PyOpcode_Deopt[_Py_OPCODE(cp_instr)]);
-        eq = co_instr == cp_instr;
+        co_instr.opcode = _PyOpcode_Deopt[_Py_OPCODE(co_instr)];
+        cp_instr.opcode =_PyOpcode_Deopt[_Py_OPCODE(cp_instr)];
+        eq = co_instr.cache == cp_instr.cache;
         if (!eq) {
             goto unequal;
         }
diff --git a/Python/ceval.c b/Python/ceval.c
index 9e4179e56071..45f42800d7ce 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -864,7 +864,7 @@ GETITEM(PyObject *v, Py_ssize_t i) {
         STAT_INC(opcode, miss);                                  \
         STAT_INC((INSTNAME), miss);                              \
         /* The counter is always the first cache entry: */       \
-        if (ADAPTIVE_COUNTER_IS_ZERO(*next_instr)) {             \
+        if (ADAPTIVE_COUNTER_IS_ZERO(next_instr->cache)) {       \
             STAT_INC((INSTNAME), deopt);                         \
         }                                                        \
         else {                                                   \
@@ -1289,7 +1289,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
         }
         opcode = _PyOpcode_Deopt[opcode];
         if (_PyOpcode_Caches[opcode]) {
-            _Py_CODEUNIT *counter = &next_instr[1];
+            uint16_t *counter = &next_instr[1].cache;
             // The instruction is going to decrement the counter, so we need to
             // increment it here to make sure it doesn't try to specialize:
             if (!ADAPTIVE_COUNTER_IS_MAX(*counter)) {
diff --git a/Python/compile.c b/Python/compile.c
index 813e0d5503b4..09eb4016940d 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -263,22 +263,32 @@ write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen)
     int caches = _PyOpcode_Caches[opcode];
     switch (ilen - caches) {
         case 4:
-            *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 24) & 0xFF);
+            codestr->opcode = EXTENDED_ARG;
+            codestr->oparg = (oparg >> 24) & 0xFF;
+            codestr++;
             /* fall through */
         case 3:
-            *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 16) & 0xFF);
+            codestr->opcode = EXTENDED_ARG;
+            codestr->oparg = (oparg >> 16) & 0xFF;
+            codestr++;
             /* fall through */
         case 2:
-            *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 8) & 0xFF);
+            codestr->opcode = EXTENDED_ARG;
+            codestr->oparg = (oparg >> 8) & 0xFF;
+            codestr++;
             /* fall through */
         case 1:
-            *codestr++ = _Py_MAKECODEUNIT(opcode, oparg & 0xFF);
+            codestr->opcode = opcode;
+            codestr->oparg = oparg & 0xFF;
+            codestr++;
             break;
         default:
             Py_UNREACHABLE();
     }
     while (caches--) {
-        *codestr++ = _Py_MAKECODEUNIT(CACHE, 0);
+        codestr->opcode = CACHE;
+        codestr->oparg = 0;
+        codestr++;
     }
 }
 
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 45382a466b1c..63635fbfc2f4 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -562,8 +562,8 @@
         TARGET(BINARY_SUBSCR_GETITEM) {
             PyObject *sub = PEEK(1);
             PyObject *container = PEEK(2);
-            uint32_t type_version = read_u32(next_instr + 1);
-            uint16_t func_version = read_u16(next_instr + 3);
+            uint32_t type_version = read_u32(&next_instr[1].cache);
+            uint16_t func_version = read_u16(&next_instr[3].cache);
             PyTypeObject *tp = Py_TYPE(container);
             DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR);
             assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE);
@@ -612,7 +612,7 @@
             PyObject *sub = PEEK(1);
             PyObject *container = PEEK(2);
             PyObject *v = PEEK(3);
-            uint16_t counter = read_u16(next_instr + 0);
+            uint16_t counter = read_u16(&next_instr[0].cache);
             if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
                 assert(cframe.use_tracing == 0);
                 next_instr--;
@@ -1249,7 +1249,7 @@
             PREDICTED(STORE_ATTR);
             PyObject *owner = PEEK(1);
             PyObject *v = PEEK(2);
-            uint16_t counter = read_u16(next_instr + 0);
+            uint16_t counter = read_u16(&next_instr[0].cache);
             if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
                 assert(cframe.use_tracing == 0);
                 PyObject *name = GETITEM(names, oparg);
@@ -2083,8 +2083,8 @@
         TARGET(STORE_ATTR_INSTANCE_VALUE) {
             PyObject *owner = PEEK(1);
             PyObject *value = PEEK(2);
-            uint32_t type_version = read_u32(next_instr + 1);
-            uint16_t index = read_u16(next_instr + 3);
+            uint32_t type_version = read_u32(&next_instr[1].cache);
+            uint16_t index = read_u16(&next_instr[3].cache);
             assert(cframe.use_tracing == 0);
             PyTypeObject *tp = Py_TYPE(owner);
             assert(type_version != 0);
@@ -2111,8 +2111,8 @@
         TARGET(STORE_ATTR_WITH_HINT) {
             PyObject *owner = PEEK(1);
             PyObject *value = PEEK(2);
-            uint32_t type_version = read_u32(next_instr + 1);
-            uint16_t hint = read_u16(next_instr + 3);
+            uint32_t type_version = read_u32(&next_instr[1].cache);
+            uint16_t hint = read_u16(&next_instr[3].cache);
             assert(cframe.use_tracing == 0);
             PyTypeObject *tp = Py_TYPE(owner);
             assert(type_version != 0);
@@ -2160,8 +2160,8 @@
         TARGET(STORE_ATTR_SLOT) {
             PyObject *owner = PEEK(1);
             PyObject *value = PEEK(2);
-            uint32_t type_version = read_u32(next_instr + 1);
-            uint16_t index = read_u16(next_instr + 3);
+            uint32_t type_version = read_u32(&next_instr[1].cache);
+            uint16_t index = read_u16(&next_instr[3].cache);
             assert(cframe.use_tracing == 0);
             PyTypeObject *tp = Py_TYPE(owner);
             assert(type_version != 0);
@@ -2209,7 +2209,7 @@
                 PyObject *right = _tmp_1;
                 PyObject *left = _tmp_2;
                 size_t jump;
-                uint16_t when_to_jump_mask = read_u16(next_instr + 1);
+                uint16_t when_to_jump_mask = read_u16(&next_instr[1].cache);
                 assert(cframe.use_tracing == 0);
                 // Combined: COMPARE_OP (float ? float) + POP_JUMP_IF_(true/false)
                 DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP);
@@ -2247,7 +2247,7 @@
                 PyObject *right = _tmp_1;
                 PyObject *left = _tmp_2;
                 size_t jump;
-                uint16_t when_to_jump_mask = read_u16(next_instr + 1);
+                uint16_t when_to_jump_mask = read_u16(&next_instr[1].cache);
                 assert(cframe.use_tracing == 0);
                 // Combined: COMPARE_OP (int ? int) + POP_JUMP_IF_(true/false)
                 DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP);
@@ -2286,7 +2286,7 @@
                 PyObject *right = _tmp_1;
                 PyObject *left = _tmp_2;
                 size_t jump;
-                uint16_t invert = read_u16(next_instr + 1);
+                uint16_t invert = read_u16(&next_instr[1].cache);
                 assert(cframe.use_tracing == 0);
                 // Combined: COMPARE_OP (str == str or str != str) + POP_JUMP_IF_(true/false)
                 DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP);
diff --git a/Python/specialize.c b/Python/specialize.c
index 785088eac8c5..678c5d66b660 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -267,26 +267,26 @@ _PyCode_Quicken(PyCodeObject *code)
         int opcode = _PyOpcode_Deopt[_Py_OPCODE(instructions[i])];
         int caches = _PyOpcode_Caches[opcode];
         if (caches) {
-            instructions[i + 1] = adaptive_counter_warmup();
+            instructions[i + 1].cache = adaptive_counter_warmup();
             previous_opcode = 0;
             i += caches;
             continue;
         }
         switch (previous_opcode << 8 | opcode) {
             case LOAD_CONST << 8 | LOAD_FAST:
-                _Py_SET_OPCODE(instructions[i - 1], LOAD_CONST__LOAD_FAST);
+                instructions[i - 1].opcode = LOAD_CONST__LOAD_FAST;
                 break;
             case LOAD_FAST << 8 | LOAD_CONST:
-                _Py_SET_OPCODE(instructions[i - 1], LOAD_FAST__LOAD_CONST);
+                instructions[i - 1].opcode = LOAD_FAST__LOAD_CONST;
                 break;
             case LOAD_FAST << 8 | LOAD_FAST:
-                _Py_SET_OPCODE(instructions[i - 1], LOAD_FAST__LOAD_FAST);
+                instructions[i - 1].opcode = LOAD_FAST__LOAD_FAST;
                 break;
             case STORE_FAST << 8 | LOAD_FAST:
-                _Py_SET_OPCODE(instructions[i - 1], STORE_FAST__LOAD_FAST);
+                instructions[i - 1].opcode = STORE_FAST__LOAD_FAST;
                 break;
             case STORE_FAST << 8 | STORE_FAST:
-                _Py_SET_OPCODE(instructions[i - 1], STORE_FAST__STORE_FAST);
+                instructions[i - 1].opcode = STORE_FAST__STORE_FAST;
                 break;
         }
         previous_opcode = opcode;
@@ -482,7 +482,7 @@ specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
     }
     write_u32(cache->version, keys_version);
     cache->index = (uint16_t)index;
-    _Py_SET_OPCODE(*instr, opcode_module);
+    _py_set_opocde(instr, opcode_module);
     return 0;
 }
 
@@ -634,7 +634,7 @@ specialize_dict_access(
         }
         write_u32(cache->version, type->tp_version_tag);
         cache->index = (uint16_t)index;
-        _Py_SET_OPCODE(*instr, values_op);
+        _py_set_opocde(instr, values_op);
     }
     else {
         PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
@@ -651,7 +651,7 @@ specialize_dict_access(
         }
         cache->index = (uint16_t)index;
         write_u32(cache->version, type->tp_version_tag);
-        _Py_SET_OPCODE(*instr, hint_op);
+        _py_set_opocde(instr, hint_op);
     }
     return 1;
 }
@@ -730,7 +730,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
             write_u32(lm_cache->type_version, type->tp_version_tag);
             /* borrowed */
             write_obj(lm_cache->descr, fget);
-            _Py_SET_OPCODE(*instr, LOAD_ATTR_PROPERTY);
+            _py_set_opocde(instr, LOAD_ATTR_PROPERTY);
             goto success;
         }
         case OBJECT_SLOT:
@@ -754,7 +754,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
             assert(offset > 0);
             cache->index = (uint16_t)offset;
             write_u32(cache->version, type->tp_version_tag);
-            _Py_SET_OPCODE(*instr, LOAD_ATTR_SLOT);
+            _py_set_opocde(instr, LOAD_ATTR_SLOT);
             goto success;
         }
         case DUNDER_CLASS:
@@ -763,7 +763,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
             assert(offset == (uint16_t)offset);
             cache->index = (uint16_t)offset;
             write_u32(cache->version, type->tp_version_tag);
-            _Py_SET_OPCODE(*instr, LOAD_ATTR_SLOT);
+            _py_set_opocde(instr, LOAD_ATTR_SLOT);
             goto success;
         }
         case OTHER_SLOT:
@@ -791,7 +791,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
             /* borrowed */
             write_obj(lm_cache->descr, descr);
             write_u32(lm_cache->type_version, type->tp_version_tag);
-            _Py_SET_OPCODE(*instr, LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN);
+            _py_set_opocde(instr, LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN);
             goto success;
         }
         case BUILTIN_CLASSMETHOD:
@@ -809,7 +809,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
 fail:
     STAT_INC(LOAD_ATTR, failure);
     assert(!PyErr_Occurred());
-    _Py_SET_OPCODE(*instr, LOAD_ATTR);
+    _py_set_opocde(instr, LOAD_ATTR);
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
@@ -868,7 +868,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
             assert(offset > 0);
             cache->index = (uint16_t)offset;
             write_u32(cache->version, type->tp_version_tag);
-            _Py_SET_OPCODE(*instr, STORE_ATTR_SLOT);
+            _py_set_opocde(instr, STORE_ATTR_SLOT);
             goto success;
         }
         case DUNDER_CLASS:
@@ -897,7 +897,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
 fail:
     STAT_INC(STORE_ATTR, failure);
     assert(!PyErr_Occurred());
-    _Py_SET_OPCODE(*instr, STORE_ATTR);
+    _py_set_opocde(instr, STORE_ATTR);
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
@@ -961,7 +961,7 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
         case NON_DESCRIPTOR:
             write_u32(cache->type_version, ((PyTypeObject *)owner)->tp_version_tag);
             write_obj(cache->descr, descr);
-            _Py_SET_OPCODE(*instr, LOAD_ATTR_CLASS);
+            _py_set_opocde(instr, LOAD_ATTR_CLASS);
             return 0;
 #ifdef Py_STATS
         case ABSENT:
@@ -1043,21 +1043,21 @@ PyObject *descr, DescriptorClassification kind)
     }
     switch(dictkind) {
         case NO_DICT:
-            _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_NO_DICT);
+            _py_set_opocde(instr, LOAD_ATTR_METHOD_NO_DICT);
             break;
         case MANAGED_VALUES:
-            _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_WITH_VALUES);
+            _py_set_opocde(instr, LOAD_ATTR_METHOD_WITH_VALUES);
             break;
         case MANAGED_DICT:
             SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_HAS_MANAGED_DICT);
             goto fail;
         case OFFSET_DICT:
             assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX);
-            _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_WITH_DICT);
+            _py_set_opocde(instr, LOAD_ATTR_METHOD_WITH_DICT);
             break;
         case LAZY_DICT:
             assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX);
-            _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_LAZY_DICT);
+            _py_set_opocde(instr, LOAD_ATTR_METHOD_LAZY_DICT);
             break;
     }
     /* `descr` is borrowed. This is safe for methods (even inherited ones from
@@ -1114,7 +1114,7 @@ _Py_Specialize_LoadGlobal(
         }
         cache->index = (uint16_t)index;
         write_u32(cache->module_keys_version, keys_version);
-        _Py_SET_OPCODE(*instr, LOAD_GLOBAL_MODULE);
+        _py_set_opocde(instr, LOAD_GLOBAL_MODULE);
         goto success;
     }
     if (!PyDict_CheckExact(builtins)) {
@@ -1150,12 +1150,12 @@ _Py_Specialize_LoadGlobal(
     cache->index = (uint16_t)index;
     write_u32(cache->module_keys_version, globals_version);
     cache->builtin_keys_version = (uint16_t)builtins_version;
-    _Py_SET_OPCODE(*instr, LOAD_GLOBAL_BUILTIN);
+    _py_set_opocde(instr, LOAD_GLOBAL_BUILTIN);
     goto success;
 fail:
     STAT_INC(LOAD_GLOBAL, failure);
     assert(!PyErr_Occurred());
-    _Py_SET_OPCODE(*instr, LOAD_GLOBAL);
+    _py_set_opocde(instr, LOAD_GLOBAL);
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
@@ -1259,7 +1259,7 @@ _Py_Specialize_BinarySubscr(
     PyTypeObject *container_type = Py_TYPE(container);
     if (container_type == &PyList_Type) {
         if (PyLong_CheckExact(sub)) {
-            _Py_SET_OPCODE(*instr, BINARY_SUBSCR_LIST_INT);
+            _py_set_opocde(instr, BINARY_SUBSCR_LIST_INT);
             goto success;
         }
         SPECIALIZATION_FAIL(BINARY_SUBSCR,
@@ -1268,7 +1268,7 @@ _Py_Specialize_BinarySubscr(
     }
     if (container_type == &PyTuple_Type) {
         if (PyLong_CheckExact(sub)) {
-            _Py_SET_OPCODE(*instr, BINARY_SUBSCR_TUPLE_INT);
+            _py_set_opocde(instr, BINARY_SUBSCR_TUPLE_INT);
             goto success;
         }
         SPECIALIZATION_FAIL(BINARY_SUBSCR,
@@ -1276,7 +1276,7 @@ _Py_Specialize_BinarySubscr(
         goto fail;
     }
     if (container_type == &PyDict_Type) {
-        _Py_SET_OPCODE(*instr, BINARY_SUBSCR_DICT);
+        _py_set_opocde(instr, BINARY_SUBSCR_DICT);
         goto success;
     }
     PyTypeObject *cls = Py_TYPE(container);
@@ -1307,7 +1307,7 @@ _Py_Specialize_BinarySubscr(
         }
         cache->func_version = version;
         ((PyHeapTypeObject *)container_type)->_spec_cache.getitem = descriptor;
-        _Py_SET_OPCODE(*instr, BINARY_SUBSCR_GETITEM);
+        _py_set_opocde(instr, BINARY_SUBSCR_GETITEM);
         goto success;
     }
     SPECIALIZATION_FAIL(BINARY_SUBSCR,
@@ -1315,7 +1315,7 @@ _Py_Specialize_BinarySubscr(
 fail:
     STAT_INC(BINARY_SUBSCR, failure);
     assert(!PyErr_Occurred());
-    _Py_SET_OPCODE(*instr, BINARY_SUBSCR);
+    _py_set_opocde(instr, BINARY_SUBSCR);
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
@@ -1334,7 +1334,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins
             if ((Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1)
                 && ((PyLongObject *)sub)->ob_digit[0] < (size_t)PyList_GET_SIZE(container))
             {
-                _Py_SET_OPCODE(*instr, STORE_SUBSCR_LIST_INT);
+                _py_set_opocde(instr, STORE_SUBSCR_LIST_INT);
                 goto success;
             }
             else {
@@ -1352,7 +1352,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins
         }
     }
     if (container_type == &PyDict_Type) {
-        _Py_SET_OPCODE(*instr, STORE_SUBSCR_DICT);
+        _py_set_opocde(instr, STORE_SUBSCR_DICT);
          goto success;
     }
 #ifdef Py_STATS
@@ -1419,7 +1419,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins
 fail:
     STAT_INC(STORE_SUBSCR, failure);
     assert(!PyErr_Occurred());
-    _Py_SET_OPCODE(*instr, STORE_SUBSCR);
+    _py_set_opocde(instr, STORE_SUBSCR);
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
@@ -1441,20 +1441,20 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
         int oparg = _Py_OPARG(*instr);
         if (nargs == 1 && kwnames == NULL && oparg == 1) {
             if (tp == &PyUnicode_Type) {
-                _Py_SET_OPCODE(*instr, CALL_NO_KW_STR_1);
+                _py_set_opocde(instr, CALL_NO_KW_STR_1);
                 return 0;
             }
             else if (tp == &PyType_Type) {
-                _Py_SET_OPCODE(*instr, CALL_NO_KW_TYPE_1);
+                _py_set_opocde(instr, CALL_NO_KW_TYPE_1);
                 return 0;
             }
             else if (tp == &PyTuple_Type) {
-                _Py_SET_OPCODE(*instr, CALL_NO_KW_TUPLE_1);
+                _py_set_opocde(instr, CALL_NO_KW_TUPLE_1);
                 return 0;
             }
         }
         if (tp->tp_vectorcall != NULL) {
-            _Py_SET_OPCODE(*instr, CALL_BUILTIN_CLASS);
+            _py_set_opocde(instr, CALL_BUILTIN_CLASS);
             return 0;
         }
         SPECIALIZATION_FAIL(CALL, tp == &PyUnicode_Type ?
@@ -1506,7 +1506,7 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
                 SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
                 return -1;
             }
-            _Py_SET_OPCODE(*instr, CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS);
+            _py_set_opocde(instr, CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS);
             return 0;
         }
         case METH_O: {
@@ -1520,18 +1520,18 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
             bool pop = (_Py_OPCODE(next) == POP_TOP);
             int oparg = _Py_OPARG(*instr);
             if ((PyObject *)descr == list_append && oparg == 1 && pop) {
-                _Py_SET_OPCODE(*instr, CALL_NO_KW_LIST_APPEND);
+                _py_set_opocde(instr, CALL_NO_KW_LIST_APPEND);
                 return 0;
             }
-            _Py_SET_OPCODE(*instr, CALL_NO_KW_METHOD_DESCRIPTOR_O);
+            _py_set_opocde(instr, CALL_NO_KW_METHOD_DESCRIPTOR_O);
             return 0;
         }
         case METH_FASTCALL: {
-            _Py_SET_OPCODE(*instr, CALL_NO_KW_METHOD_DESCRIPTOR_FAST);
+            _py_set_opocde(instr, CALL_NO_KW_METHOD_DESCRIPTOR_FAST);
             return 0;
         }
         case METH_FASTCALL|METH_KEYWORDS: {
-            _Py_SET_OPCODE(*instr, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS);
+            _py_set_opocde(instr, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS);
             return 0;
         }
     }
@@ -1582,14 +1582,14 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
     write_u32(cache->func_version, version);
     cache->min_args = min_args;
     if (argcount == nargs) {
-        _Py_SET_OPCODE(*instr, bound_method ? CALL_BOUND_METHOD_EXACT_ARGS : CALL_PY_EXACT_ARGS);
+        _py_set_opocde(instr, bound_method ? CALL_BOUND_METHOD_EXACT_ARGS : CALL_PY_EXACT_ARGS);
     }
     else if (bound_method) {
         SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD);
         return -1;
     }
     else {
-        _Py_SET_OPCODE(*instr, CALL_PY_WITH_DEFAULTS);
+        _py_set_opocde(instr, CALL_PY_WITH_DEFAULTS);
     }
     return 0;
 }
@@ -1616,10 +1616,10 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
             /* len(o) */
             PyInterpreterState *interp = _PyInterpreterState_GET();
             if (callable == interp->callable_cache.len) {
-                _Py_SET_OPCODE(*instr, CALL_NO_KW_LEN);
+                _py_set_opocde(instr, CALL_NO_KW_LEN);
                 return 0;
             }
-            _Py_SET_OPCODE(*instr, CALL_NO_KW_BUILTIN_O);
+            _py_set_opocde(instr, CALL_NO_KW_BUILTIN_O);
             return 0;
         }
         case METH_FASTCALL: {
@@ -1631,15 +1631,15 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
                 /* isinstance(o1, o2) */
                 PyInterpreterState *interp = _PyInterpreterState_GET();
                 if (callable == interp->callable_cache.isinstance) {
-                    _Py_SET_OPCODE(*instr, CALL_NO_KW_ISINSTANCE);
+                    _py_set_opocde(instr, CALL_NO_KW_ISINSTANCE);
                     return 0;
                 }
             }
-            _Py_SET_OPCODE(*instr, CALL_NO_KW_BUILTIN_FAST);
+            _py_set_opocde(instr, CALL_NO_KW_BUILTIN_FAST);
             return 0;
         }
         case METH_FASTCALL | METH_KEYWORDS: {
-            _Py_SET_OPCODE(*instr, CALL_BUILTIN_FAST_WITH_KEYWORDS);
+            _py_set_opocde(instr, CALL_BUILTIN_FAST_WITH_KEYWORDS);
             return 0;
         }
         default:
@@ -1732,7 +1732,7 @@ _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
     if (fail) {
         STAT_INC(CALL, failure);
         assert(!PyErr_Occurred());
-        _Py_SET_OPCODE(*instr, CALL);
+        _py_set_opocde(instr, CALL);
         cache->counter = adaptive_counter_backoff(cache->counter);
     }
     else {
@@ -1829,18 +1829,18 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
                 bool to_store = (_Py_OPCODE(next) == STORE_FAST ||
                                  _Py_OPCODE(next) == STORE_FAST__LOAD_FAST);
                 if (to_store && locals[_Py_OPARG(next)] == lhs) {
-                    _Py_SET_OPCODE(*instr, BINARY_OP_INPLACE_ADD_UNICODE);
+                    _py_set_opocde(instr, BINARY_OP_INPLACE_ADD_UNICODE);
                     goto success;
                 }
-                _Py_SET_OPCODE(*instr, BINARY_OP_ADD_UNICODE);
+                _py_set_opocde(instr, BINARY_OP_ADD_UNICODE);
                 goto success;
             }
             if (PyLong_CheckExact(lhs)) {
-                _Py_SET_OPCODE(*instr, BINARY_OP_ADD_INT);
+                _py_set_opocde(instr, BINARY_OP_ADD_INT);
                 goto success;
             }
             if (PyFloat_CheckExact(lhs)) {
-                _Py_SET_OPCODE(*instr, BINARY_OP_ADD_FLOAT);
+                _py_set_opocde(instr, BINARY_OP_ADD_FLOAT);
                 goto success;
             }
             break;
@@ -1850,11 +1850,11 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
                 break;
             }
             if (PyLong_CheckExact(lhs)) {
-                _Py_SET_OPCODE(*instr, BINARY_OP_MULTIPLY_INT);
+                _py_set_opocde(instr, BINARY_OP_MULTIPLY_INT);
                 goto success;
             }
             if (PyFloat_CheckExact(lhs)) {
-                _Py_SET_OPCODE(*instr, BINARY_OP_MULTIPLY_FLOAT);
+                _py_set_opocde(instr, BINARY_OP_MULTIPLY_FLOAT);
                 goto success;
             }
             break;
@@ -1864,18 +1864,18 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
                 break;
             }
             if (PyLong_CheckExact(lhs)) {
-                _Py_SET_OPCODE(*instr, BINARY_OP_SUBTRACT_INT);
+                _py_set_opocde(instr, BINARY_OP_SUBTRACT_INT);
                 goto success;
             }
             if (PyFloat_CheckExact(lhs)) {
-                _Py_SET_OPCODE(*instr, BINARY_OP_SUBTRACT_FLOAT);
+                _py_set_opocde(instr, BINARY_OP_SUBTRACT_FLOAT);
                 goto success;
             }
             break;
     }
     SPECIALIZATION_FAIL(BINARY_OP, binary_op_fail_kind(oparg, lhs, rhs));
     STAT_INC(BINARY_OP, failure);
-    _Py_SET_OPCODE(*instr, BINARY_OP);
+    _py_set_opocde(instr, BINARY_OP);
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
@@ -1957,13 +1957,13 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
         goto failure;
     }
     if (PyFloat_CheckExact(lhs)) {
-        _Py_SET_OPCODE(*instr, COMPARE_OP_FLOAT_JUMP);
+        _py_set_opocde(instr, COMPARE_OP_FLOAT_JUMP);
         cache->mask = when_to_jump_mask;
         goto success;
     }
     if (PyLong_CheckExact(lhs)) {
         if (Py_ABS(Py_SIZE(lhs)) <= 1 && Py_ABS(Py_SIZE(rhs)) <= 1) {
-            _Py_SET_OPCODE(*instr, COMPARE_OP_INT_JUMP);
+            _py_set_opocde(instr, COMPARE_OP_INT_JUMP);
             cache->mask = when_to_jump_mask;
             goto success;
         }
@@ -1978,7 +1978,7 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
             goto failure;
         }
         else {
-            _Py_SET_OPCODE(*instr, COMPARE_OP_STR_JUMP);
+            _py_set_opocde(instr, COMPARE_OP_STR_JUMP);
             cache->mask = (when_to_jump_mask & 2) == 0;
             goto success;
         }
@@ -1986,7 +1986,7 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
     SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
 failure:
     STAT_INC(COMPARE_OP, failure);
-    _Py_SET_OPCODE(*instr, COMPARE_OP);
+    _py_set_opocde(instr, COMPARE_OP);
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
@@ -2020,10 +2020,10 @@ _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg)
             goto failure;
         }
         if (PyTuple_GET_SIZE(seq) == 2) {
-            _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_TWO_TUPLE);
+            _py_set_opocde(instr, UNPACK_SEQUENCE_TWO_TUPLE);
             goto success;
         }
-        _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_TUPLE);
+        _py_set_opocde(instr, UNPACK_SEQUENCE_TUPLE);
         goto success;
     }
     if (PyList_CheckExact(seq)) {
@@ -2031,13 +2031,13 @@ _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg)
             SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR);
             goto failure;
         }
-        _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_LIST);
+        _py_set_opocde(instr, UNPACK_SEQUENCE_LIST);
         goto success;
     }
     SPECIALIZATION_FAIL(UNPACK_SEQUENCE, unpack_sequence_fail_kind(seq));
 failure:
     STAT_INC(UNPACK_SEQUENCE, failure);
-    _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE);
+    _py_set_opocde(instr, UNPACK_SEQUENCE);
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
@@ -2126,26 +2126,26 @@ _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg)
     _Py_CODEUNIT next = instr[1+INLINE_CACHE_ENTRIES_FOR_ITER];
     int next_op = _PyOpcode_Deopt[_Py_OPCODE(next)];
     if (tp == &PyListIter_Type) {
-        _Py_SET_OPCODE(*instr, FOR_ITER_LIST);
+        _py_set_opocde(instr, FOR_ITER_LIST);
         goto success;
     }
     else if (tp == &PyTupleIter_Type) {
-        _Py_SET_OPCODE(*instr, FOR_ITER_TUPLE);
+        _py_set_opocde(instr, FOR_ITER_TUPLE);
         goto success;
     }
     else if (tp == &PyRangeIter_Type && next_op == STORE_FAST) {
-        _Py_SET_OPCODE(*instr, FOR_ITER_RANGE);
+        _py_set_opocde(instr, FOR_ITER_RANGE);
         goto success;
     }
     else if (tp == &PyGen_Type && oparg <= SHRT_MAX) {
         assert(_Py_OPCODE(instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1]) == END_FOR);
-        _Py_SET_OPCODE(*instr, FOR_ITER_GEN);
+        _py_set_opocde(instr, FOR_ITER_GEN);
         goto success;
     }
     SPECIALIZATION_FAIL(FOR_ITER,
                         _PySpecialization_ClassifyIterator(iter));
     STAT_INC(FOR_ITER, failure);
-    _Py_SET_OPCODE(*instr, FOR_ITER);
+    _py_set_opocde(instr, FOR_ITER);
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py
index 5930c797b8a4..2dfc76f2560e 100644
--- a/Tools/cases_generator/generate_cases.py
+++ b/Tools/cases_generator/generate_cases.py
@@ -205,7 +205,7 @@ def write_body(self, out: Formatter, dedent: int, cache_adjust: int = 0) -> None
                 else:
                     typ = f"uint{bits}_t "
                     func = f"read_u{bits}"
-                out.emit(f"{typ}{ceffect.name} = {func}(next_instr + {cache_offset});")
+                out.emit(f"{typ}{ceffect.name} = {func}(&next_instr[{cache_offset}].cache);")
             cache_offset += ceffect.size
         assert cache_offset == self.cache_offset + cache_adjust
 



More information about the Python-checkins mailing list