From 1f5d7cb24d6d206c13881b48c6479ccffcdb110b Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 14 Feb 2023 15:53:16 +0000 Subject: [PATCH 1/7] gh-101907: Removes use of non-standard C++ extension from Include/cpython/code.h --- Include/cpython/code.h | 8 ++++---- ...-02-14-15-53-01.gh-issue-101907.HgF1N2.rst | 1 + Objects/codeobject.c | 10 +++++----- Objects/genobject.c | 6 +++--- Python/compile.c | 20 +++++++++---------- Python/specialize.c | 16 +++++++-------- 6 files changed, 31 insertions(+), 30 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2023-02-14-15-53-01.gh-issue-101907.HgF1N2.rst diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 0cf49f06c87732..463405b0743d3c 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -21,16 +21,16 @@ typedef union { struct { uint8_t opcode; uint8_t oparg; - }; + } _op; } _Py_CODEUNIT; -#define _Py_OPCODE(word) ((word).opcode) -#define _Py_OPARG(word) ((word).oparg) +#define _Py_OPCODE(word) ((word)._op.opcode) +#define _Py_OPARG(word) ((word)._op.oparg) static inline void _py_set_opcode(_Py_CODEUNIT *word, uint8_t opcode) { - word->opcode = opcode; + word->_op.opcode = opcode; } #define _Py_SET_OPCODE(word, opcode) _py_set_opocde(&(word), opcode) diff --git a/Misc/NEWS.d/next/C API/2023-02-14-15-53-01.gh-issue-101907.HgF1N2.rst b/Misc/NEWS.d/next/C API/2023-02-14-15-53-01.gh-issue-101907.HgF1N2.rst new file mode 100644 index 00000000000000..cfc0d72cdbca00 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-02-14-15-53-01.gh-issue-101907.HgF1N2.rst @@ -0,0 +1 @@ +Removes use of non-standard C++ extension in public header files. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index ab31b6582cdaae..b9fccffe8fc953 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1507,10 +1507,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].opcode = opcode; + _Py_OPCODE(instructions[i]) = opcode; while (caches--) { - instructions[++i].opcode = CACHE; - instructions[i].oparg = 0; + _Py_OPCODE(instructions[++i]) = CACHE; + _Py_OPARG(instructions[i]) = 0; } } } @@ -1763,8 +1763,8 @@ 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]; - co_instr.opcode = _PyOpcode_Deopt[_Py_OPCODE(co_instr)]; - cp_instr.opcode =_PyOpcode_Deopt[_Py_OPCODE(cp_instr)]; + _Py_OPCODE(co_instr) = _PyOpcode_Deopt[_Py_OPCODE(co_instr)]; + _Py_OPCODE(cp_instr) =_PyOpcode_Deopt[_Py_OPCODE(cp_instr)]; eq = co_instr.cache == cp_instr.cache; if (!eq) { goto unequal; diff --git a/Objects/genobject.c b/Objects/genobject.c index 35246653c45348..6979fdce84abe2 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -371,9 +371,9 @@ gen_close(PyGenObject *gen, PyObject *args) _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; /* It is possible for the previous instruction to not be a * YIELD_VALUE if the debugger has changed the lineno. */ - if (err == 0 && frame->prev_instr->opcode == YIELD_VALUE) { - assert(frame->prev_instr[1].opcode == RESUME); - int exception_handler_depth = frame->prev_instr->oparg; + if (err == 0 && _Py_OPCODE(frame->prev_instr[0]) == YIELD_VALUE) { + assert(_Py_OPCODE(frame->prev_instr[1]) == RESUME); + int exception_handler_depth = _Py_OPCODE(frame->prev_instr[0]); assert(exception_handler_depth > 0); /* We can safely ignore the outermost try block * as it automatically generated to handle diff --git a/Python/compile.c b/Python/compile.c index 0534b536e3d12e..2ea6483b46902a 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -274,31 +274,31 @@ write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen) int caches = _PyOpcode_Caches[opcode]; switch (ilen - caches) { case 4: - codestr->opcode = EXTENDED_ARG; - codestr->oparg = (oparg >> 24) & 0xFF; + _Py_OPCODE(*codestr) = EXTENDED_ARG; + _Py_OPARG(*codestr) = (oparg >> 24) & 0xFF; codestr++; /* fall through */ case 3: - codestr->opcode = EXTENDED_ARG; - codestr->oparg = (oparg >> 16) & 0xFF; + _Py_OPCODE(*codestr) = EXTENDED_ARG; + _Py_OPARG(*codestr) = (oparg >> 16) & 0xFF; codestr++; /* fall through */ case 2: - codestr->opcode = EXTENDED_ARG; - codestr->oparg = (oparg >> 8) & 0xFF; + _Py_OPCODE(*codestr) = EXTENDED_ARG; + _Py_OPARG(*codestr) = (oparg >> 8) & 0xFF; codestr++; /* fall through */ case 1: - codestr->opcode = opcode; - codestr->oparg = oparg & 0xFF; + _Py_OPCODE(*codestr) = opcode; + _Py_OPARG(*codestr) = oparg & 0xFF; codestr++; break; default: Py_UNREACHABLE(); } while (caches--) { - codestr->opcode = CACHE; - codestr->oparg = 0; + _Py_OPCODE(*codestr) = CACHE; + _Py_OPARG(*codestr) = 0; codestr++; } } diff --git a/Python/specialize.c b/Python/specialize.c index 4ede3122d38046..a6b63c5b158146 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -291,31 +291,31 @@ _PyCode_Quicken(PyCodeObject *code) } switch (previous_opcode << 8 | opcode) { case LOAD_CONST << 8 | LOAD_FAST: - instructions[i - 1].opcode = LOAD_CONST__LOAD_FAST; + _Py_OPCODE(instructions[i - 1]) = LOAD_CONST__LOAD_FAST; break; case LOAD_FAST << 8 | LOAD_CONST: - instructions[i - 1].opcode = LOAD_FAST__LOAD_CONST; + _Py_OPCODE(instructions[i - 1]) = LOAD_FAST__LOAD_CONST; break; case LOAD_FAST << 8 | LOAD_FAST: - instructions[i - 1].opcode = LOAD_FAST__LOAD_FAST; + _Py_OPCODE(instructions[i - 1]) = LOAD_FAST__LOAD_FAST; break; case STORE_FAST << 8 | LOAD_FAST: - instructions[i - 1].opcode = STORE_FAST__LOAD_FAST; + _Py_OPCODE(instructions[i - 1]) = STORE_FAST__LOAD_FAST; break; case STORE_FAST << 8 | STORE_FAST: - instructions[i - 1].opcode = STORE_FAST__STORE_FAST; + _Py_OPCODE(instructions[i - 1]) = STORE_FAST__STORE_FAST; break; case COMPARE_OP << 8 | POP_JUMP_IF_TRUE: case COMPARE_OP << 8 | POP_JUMP_IF_FALSE: { - int oparg = instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].oparg; + int oparg = _Py_OPARG(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP]); assert((oparg >> 4) <= Py_GE); int mask = compare_masks[oparg >> 4]; if (opcode == POP_JUMP_IF_FALSE) { mask = mask ^ 0xf; } - instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].opcode = COMPARE_AND_BRANCH; - instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].oparg = (oparg & 0xf0) | mask; + _Py_OPCODE(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP]) = COMPARE_AND_BRANCH; + _Py_OPARG(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP]) = (oparg & 0xf0) | mask; break; } } From 5005130274d1132c6644a087ace40f0c9a8be8bc Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 14 Feb 2023 17:00:39 +0000 Subject: [PATCH 2/7] Use SET macros instead --- Include/cpython/code.h | 10 +++++++++- Objects/codeobject.c | 10 +++++----- Python/compile.c | 20 ++++++++++---------- Python/specialize.c | 14 +++++++------- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 463405b0743d3c..6de9e492a20f1a 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -33,7 +33,15 @@ _py_set_opcode(_Py_CODEUNIT *word, uint8_t opcode) word->_op.opcode = opcode; } -#define _Py_SET_OPCODE(word, opcode) _py_set_opocde(&(word), opcode) +#define _Py_SET_OPCODE(word, opcode) _py_set_opcode(&(word), opcode) + +static inline void +_py_set_oparg(_Py_CODEUNIT *word, uint8_t oparg) +{ + word->_op.oparg = oparg; +} + +#define _Py_SET_OPARG(word, opcode) _py_set_oparg(&(word), opcode) typedef struct { PyObject *_co_code; diff --git a/Objects/codeobject.c b/Objects/codeobject.c index b9fccffe8fc953..9270150e4a9ae2 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1507,10 +1507,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]; - _Py_OPCODE(instructions[i]) = opcode; + _Py_SET_OPCODE(instructions[i], opcode); while (caches--) { - _Py_OPCODE(instructions[++i]) = CACHE; - _Py_OPARG(instructions[i]) = 0; + _Py_SET_OPCODE(instructions[++i], CACHE); + _Py_SET_OPARG(instructions[i], 0); } } } @@ -1763,8 +1763,8 @@ 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_OPCODE(co_instr) = _PyOpcode_Deopt[_Py_OPCODE(co_instr)]; - _Py_OPCODE(cp_instr) =_PyOpcode_Deopt[_Py_OPCODE(cp_instr)]; + _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.cache == cp_instr.cache; if (!eq) { goto unequal; diff --git a/Python/compile.c b/Python/compile.c index 2ea6483b46902a..7ad62e254ab934 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -274,31 +274,31 @@ write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen) int caches = _PyOpcode_Caches[opcode]; switch (ilen - caches) { case 4: - _Py_OPCODE(*codestr) = EXTENDED_ARG; - _Py_OPARG(*codestr) = (oparg >> 24) & 0xFF; + _Py_SET_OPCODE(*codestr, EXTENDED_ARG); + _Py_SET_OPARG(*codestr, (oparg >> 24) & 0xFF); codestr++; /* fall through */ case 3: - _Py_OPCODE(*codestr) = EXTENDED_ARG; - _Py_OPARG(*codestr) = (oparg >> 16) & 0xFF; + _Py_SET_OPCODE(*codestr, EXTENDED_ARG); + _Py_SET_OPARG(*codestr, (oparg >> 16) & 0xFF); codestr++; /* fall through */ case 2: - _Py_OPCODE(*codestr) = EXTENDED_ARG; - _Py_OPARG(*codestr) = (oparg >> 8) & 0xFF; + _Py_SET_OPCODE(*codestr, EXTENDED_ARG); + _Py_SET_OPARG(*codestr, (oparg >> 8) & 0xFF); codestr++; /* fall through */ case 1: - _Py_OPCODE(*codestr) = opcode; - _Py_OPARG(*codestr) = oparg & 0xFF; + _Py_SET_OPCODE(*codestr, opcode); + _Py_SET_OPARG(*codestr, oparg & 0xFF); codestr++; break; default: Py_UNREACHABLE(); } while (caches--) { - _Py_OPCODE(*codestr) = CACHE; - _Py_OPARG(*codestr) = 0; + _Py_SET_OPCODE(*codestr, CACHE); + _Py_SET_OPARG(*codestr, 0); codestr++; } } diff --git a/Python/specialize.c b/Python/specialize.c index a6b63c5b158146..8bbf8fe9e19249 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -291,19 +291,19 @@ _PyCode_Quicken(PyCodeObject *code) } switch (previous_opcode << 8 | opcode) { case LOAD_CONST << 8 | LOAD_FAST: - _Py_OPCODE(instructions[i - 1]) = LOAD_CONST__LOAD_FAST; + _Py_SET_OPCODE(instructions[i - 1], LOAD_CONST__LOAD_FAST); break; case LOAD_FAST << 8 | LOAD_CONST: - _Py_OPCODE(instructions[i - 1]) = LOAD_FAST__LOAD_CONST; + _Py_SET_OPCODE(instructions[i - 1], LOAD_FAST__LOAD_CONST); break; case LOAD_FAST << 8 | LOAD_FAST: - _Py_OPCODE(instructions[i - 1]) = LOAD_FAST__LOAD_FAST; + _Py_SET_OPCODE(instructions[i - 1], LOAD_FAST__LOAD_FAST); break; case STORE_FAST << 8 | LOAD_FAST: - _Py_OPCODE(instructions[i - 1]) = STORE_FAST__LOAD_FAST; + _Py_SET_OPCODE(instructions[i - 1], STORE_FAST__LOAD_FAST); break; case STORE_FAST << 8 | STORE_FAST: - _Py_OPCODE(instructions[i - 1]) = STORE_FAST__STORE_FAST; + _Py_SET_OPCODE(instructions[i - 1], STORE_FAST__STORE_FAST); break; case COMPARE_OP << 8 | POP_JUMP_IF_TRUE: case COMPARE_OP << 8 | POP_JUMP_IF_FALSE: @@ -314,8 +314,8 @@ _PyCode_Quicken(PyCodeObject *code) if (opcode == POP_JUMP_IF_FALSE) { mask = mask ^ 0xf; } - _Py_OPCODE(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP]) = COMPARE_AND_BRANCH; - _Py_OPARG(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP]) = (oparg & 0xf0) | mask; + _Py_SET_OPCODE(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP], COMPARE_AND_BRANCH); + _Py_SET_OPARG(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP], (oparg & 0xf0) | mask); break; } } From b4fd83d8b7ef4079bd252c09b70ea1c79b8fd474 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 14 Feb 2023 18:04:22 +0000 Subject: [PATCH 3/7] Remove macros from internal use instead --- Include/cpython/code.h | 32 ++++--- Objects/codeobject.c | 20 ++--- Objects/frameobject.c | 24 +++--- Objects/genobject.c | 10 +-- Objects/typeobject.c | 4 +- Python/bytecodes.c | 34 ++++---- Python/ceval.c | 12 +-- Python/ceval_macros.h | 10 +-- Python/compile.c | 20 ++--- Python/generated_cases.c.h | 34 ++++---- Python/opcode_metadata.h | 4 +- Python/specialize.c | 172 ++++++++++++++++++------------------- 12 files changed, 191 insertions(+), 185 deletions(-) diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 6de9e492a20f1a..c2064d301bd2e2 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -19,29 +19,35 @@ extern "C" { typedef union { uint16_t cache; struct { - uint8_t opcode; - uint8_t oparg; - } _op; + uint8_t code; + uint8_t arg; + } op; } _Py_CODEUNIT; -#define _Py_OPCODE(word) ((word)._op.opcode) -#define _Py_OPARG(word) ((word)._op.oparg) -static inline void -_py_set_opcode(_Py_CODEUNIT *word, uint8_t opcode) +/* These macros only remain defined for compatibility. */ +#define _Py_OPCODE(word) ((word).op.code) +#define _Py_OPARG(word) ((word).op.arg) + +static inline uint16_t +_py_make_codeunit(uint8_t opcode, uint8_t oparg) { - word->_op.opcode = opcode; + // No designated initialisers because of C++ compat + _Py_CODEUNIT word; + word.op.code = opcode; + word.op.arg = oparg; + return word.cache; } -#define _Py_SET_OPCODE(word, opcode) _py_set_opcode(&(word), opcode) - static inline void -_py_set_oparg(_Py_CODEUNIT *word, uint8_t oparg) +_py_set_opcode(_Py_CODEUNIT *word, uint16_t packed_opcode) { - word->_op.oparg = oparg; + word->cache = packed_opcode; } -#define _Py_SET_OPARG(word, opcode) _py_set_oparg(&(word), opcode) +#define _Py_MAKE_CODEUNIT(opcode, oparg) _py_make_codeunit((opcode), (oparg)) +#define _Py_SET_OPCODE(word, opcode) _py_set_opcode(&(word), opcode) + typedef struct { PyObject *_co_code; diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 9270150e4a9ae2..11bbaa7744e6b7 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -413,7 +413,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) PyBytes_GET_SIZE(con->code)); int entry_point = 0; while (entry_point < Py_SIZE(co) && - _Py_OPCODE(_PyCode_CODE(co)[entry_point]) != RESUME) { + _PyCode_CODE(co)[entry_point].op.code != RESUME) { entry_point++; } co->_co_firsttraceable = entry_point; @@ -1505,12 +1505,12 @@ deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len) { for (int i = 0; i < len; i++) { _Py_CODEUNIT instruction = instructions[i]; - int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)]; + int opcode = _PyOpcode_Deopt[instruction.op.code]; int caches = _PyOpcode_Caches[opcode]; - _Py_SET_OPCODE(instructions[i], opcode); + instructions[i].op.code = opcode; while (caches--) { - _Py_SET_OPCODE(instructions[++i], CACHE); - _Py_SET_OPARG(instructions[i], 0); + instructions[++i].op.code = CACHE; + instructions[i].op.arg = 0; } } } @@ -1763,13 +1763,13 @@ 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)]); + co_instr.op.code = _PyOpcode_Deopt[co_instr.op.code]; + cp_instr.op.code = _PyOpcode_Deopt[cp_instr.op.code]; eq = co_instr.cache == cp_instr.cache; if (!eq) { goto unequal; } - i += _PyOpcode_Caches[_Py_OPCODE(co_instr)]; + i += _PyOpcode_Caches[co_instr.op.code]; } /* compare constants */ @@ -1848,9 +1848,9 @@ code_hash(PyCodeObject *co) SCRAMBLE_IN(co->co_firstlineno); SCRAMBLE_IN(Py_SIZE(co)); for (int i = 0; i < Py_SIZE(co); i++) { - int deop = _PyOpcode_Deopt[_Py_OPCODE(_PyCode_CODE(co)[i])]; + int deop = _PyOpcode_Deopt[_PyCode_CODE(co)[i].op.code]; SCRAMBLE_IN(deop); - SCRAMBLE_IN(_Py_OPARG(_PyCode_CODE(co)[i])); + SCRAMBLE_IN(_PyCode_CODE(co)[i].op.code); i += _PyOpcode_Caches[deop]; } if ((Py_hash_t)uhash == -1) { diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 581ed2d214c4d9..34143c9a40b293 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -111,13 +111,13 @@ static unsigned int get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) { _Py_CODEUNIT word; - unsigned int oparg = _Py_OPARG(codestr[i]); - if (i >= 1 && _Py_OPCODE(word = codestr[i-1]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 8; - if (i >= 2 && _Py_OPCODE(word = codestr[i-2]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 16; - if (i >= 3 && _Py_OPCODE(word = codestr[i-3]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 24; + unsigned int oparg = codestr[i].op.arg; + if (i >= 1 && (word = codestr[i-1]).op.code == EXTENDED_ARG) { + oparg |= word.op.arg << 8; + if (i >= 2 && (word = codestr[i-2]).op.code == EXTENDED_ARG) { + oparg |= word.op.arg << 16; + if (i >= 3 && (word = codestr[i-3]).op.code == EXTENDED_ARG) { + oparg |= word.op.arg << 24; } } } @@ -304,7 +304,7 @@ mark_stacks(PyCodeObject *code_obj, int len) if (next_stack == UNINITIALIZED) { continue; } - opcode = _Py_OPCODE(code[i]); + opcode = code[i].op.code; switch (opcode) { case JUMP_IF_FALSE_OR_POP: case JUMP_IF_TRUE_OR_POP: @@ -610,7 +610,7 @@ _PyFrame_GetState(PyFrameObject *frame) if (_PyInterpreterFrame_LASTI(frame->f_frame) < 0) { return FRAME_CREATED; } - switch (_Py_OPCODE(*frame->f_frame->prev_instr)) + switch (frame->f_frame->prev_instr->op.code) { case COPY_FREE_VARS: case MAKE_CELL: @@ -1092,8 +1092,8 @@ _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) for (_Py_CODEUNIT *instruction = _PyCode_CODE(frame->f_code); instruction < frame->prev_instr; instruction++) { - int check_opcode = _PyOpcode_Deopt[_Py_OPCODE(*instruction)]; - check_oparg |= _Py_OPARG(*instruction); + int check_opcode = _PyOpcode_Deopt[instruction->op.code]; + check_oparg |= instruction->op.arg; if (check_opcode == opcode && check_oparg == oparg) { return 1; } @@ -1117,7 +1117,7 @@ frame_init_get_vars(_PyInterpreterFrame *frame) // here: PyCodeObject *co = frame->f_code; int lasti = _PyInterpreterFrame_LASTI(frame); - if (!(lasti < 0 && _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS + if (!(lasti < 0 && _PyCode_CODE(co)->op.code == COPY_FREE_VARS && PyFunction_Check(frame->f_funcobj))) { /* Free vars are initialized */ diff --git a/Objects/genobject.c b/Objects/genobject.c index 6979fdce84abe2..aec64ca7004e11 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -332,11 +332,11 @@ _PyGen_yf(PyGenObject *gen) /* Return immediately if the frame didn't start yet. SEND always come after LOAD_CONST: a code object should not start with SEND */ - assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND); + assert(_PyCode_CODE(gen->gi_code)[0].op.code != SEND); return NULL; } _Py_CODEUNIT next = frame->prev_instr[1]; - if (_Py_OPCODE(next) != RESUME || _Py_OPARG(next) < 2) + if (next.op.code != RESUME || next.op.arg < 2) { /* Not in a yield from */ return NULL; @@ -371,9 +371,9 @@ gen_close(PyGenObject *gen, PyObject *args) _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; /* It is possible for the previous instruction to not be a * YIELD_VALUE if the debugger has changed the lineno. */ - if (err == 0 && _Py_OPCODE(frame->prev_instr[0]) == YIELD_VALUE) { - assert(_Py_OPCODE(frame->prev_instr[1]) == RESUME); - int exception_handler_depth = _Py_OPCODE(frame->prev_instr[0]); + if (err == 0 && frame->prev_instr[0].op.code == YIELD_VALUE) { + assert(frame->prev_instr[1].op.code == RESUME); + int exception_handler_depth = frame->prev_instr[0].op.code; assert(exception_handler_depth > 0); /* We can safely ignore the outermost try block * as it automatically generated to handle diff --git a/Objects/typeobject.c b/Objects/typeobject.c index bf6ccdb77a90f0..b3f1429debc58b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -9507,8 +9507,8 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, if (_PyInterpreterFrame_LASTI(cframe) >= 0) { // MAKE_CELL and COPY_FREE_VARS have no quickened forms, so no need // to use _PyOpcode_Deopt here: - assert(_Py_OPCODE(_PyCode_CODE(co)[0]) == MAKE_CELL || - _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS); + assert(_PyCode_CODE(co)[0].op.code == MAKE_CELL || + _PyCode_CODE(co)[0].op.code == COPY_FREE_VARS); assert(PyCell_Check(firstarg)); firstarg = PyCell_GET(firstarg); } diff --git a/Python/bytecodes.c b/Python/bytecodes.c index be54e5f6f589eb..f899f60612e555 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -246,9 +246,9 @@ dummy_func( DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; - assert(_Py_OPCODE(true_next) == STORE_FAST || - _Py_OPCODE(true_next) == STORE_FAST__LOAD_FAST); - PyObject **target_local = &GETLOCAL(_Py_OPARG(true_next)); + assert(true_next.op.code == STORE_FAST || + true_next.op.code == STORE_FAST__LOAD_FAST); + PyObject **target_local = &GETLOCAL(true_next.op.arg); DEOPT_IF(*target_local != left, BINARY_OP); STAT_INC(BINARY_OP, hit); /* Handle `left = left + right` or `left += right` for str. @@ -1745,10 +1745,10 @@ dummy_func( Py_DECREF(left); Py_DECREF(right); ERROR_IF(cond == NULL, error); - assert(_Py_OPCODE(next_instr[1]) == POP_JUMP_IF_FALSE || - _Py_OPCODE(next_instr[1]) == POP_JUMP_IF_TRUE); - bool jump_on_true = _Py_OPCODE(next_instr[1]) == POP_JUMP_IF_TRUE; - int offset = _Py_OPARG(next_instr[1]); + assert(next_instr[1].op.code == POP_JUMP_IF_FALSE || + next_instr[1].op.code == POP_JUMP_IF_TRUE); + bool jump_on_true = next_instr[1].op.code == POP_JUMP_IF_TRUE; + int offset = next_instr[1].op.arg; int err = PyObject_IsTrue(cond); Py_DECREF(cond); if (err < 0) { @@ -1771,7 +1771,7 @@ dummy_func( _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); if (sign_ish & oparg) { - int offset = _Py_OPARG(next_instr[1]); + int offset = next_instr[1].op.arg; JUMPBY(offset); } } @@ -1792,7 +1792,7 @@ dummy_func( _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); if (sign_ish & oparg) { - int offset = _Py_OPARG(next_instr[1]); + int offset = next_instr[1].op.arg; JUMPBY(offset); } } @@ -1811,7 +1811,7 @@ dummy_func( assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); if ((res + COMPARISON_NOT_EQUALS) & oparg) { - int offset = _Py_OPARG(next_instr[1]); + int offset = next_instr[1].op.arg; JUMPBY(offset); } } @@ -2119,7 +2119,7 @@ dummy_func( _PyErr_Clear(tstate); } /* iterator ended normally */ - assert(_Py_OPCODE(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg]) == END_FOR); + assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR); Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ @@ -2183,7 +2183,7 @@ dummy_func( DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); _Py_CODEUNIT next = next_instr[INLINE_CACHE_ENTRIES_FOR_ITER]; - assert(_PyOpcode_Deopt[_Py_OPCODE(next)] == STORE_FAST); + assert(_PyOpcode_Deopt[next.op.code] == STORE_FAST); if (r->len <= 0) { STACK_SHRINK(1); Py_DECREF(r); @@ -2194,7 +2194,7 @@ dummy_func( long value = r->start; r->start = value + r->step; r->len--; - if (_PyLong_AssignValue(&GETLOCAL(_Py_OPARG(next)), value) < 0) { + if (_PyLong_AssignValue(&GETLOCAL(next.op.arg), value) < 0) { goto error; } // The STORE_FAST is already done. @@ -2217,7 +2217,7 @@ dummy_func( gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg); - assert(_Py_OPCODE(*next_instr) == END_FOR); + assert(next_instr->op.code == END_FOR); DISPATCH_INLINED(gen_frame); } @@ -2806,7 +2806,7 @@ dummy_func( STACK_SHRINK(3); // CALL + POP_TOP JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); - assert(_Py_OPCODE(next_instr[-1]) == POP_TOP); + assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); } @@ -3115,8 +3115,8 @@ dummy_func( inst(EXTENDED_ARG, (--)) { assert(oparg); assert(cframe.use_tracing == 0); - opcode = _Py_OPCODE(*next_instr); - oparg = oparg << 8 | _Py_OPARG(*next_instr); + opcode = next_instr->op.code; + oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); } diff --git a/Python/ceval.c b/Python/ceval.c index 611d62b0eba9af..e6fed8f4980027 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -132,8 +132,8 @@ lltrace_instruction(_PyInterpreterFrame *frame, objects enters the interpreter recursively. It is also slow. So you might want to comment it out. */ dump_stack(frame, stack_pointer); - int oparg = _Py_OPARG(*next_instr); - int opcode = _Py_OPCODE(*next_instr); + int oparg = next_instr->op.arg; + int opcode = next_instr->op.code; const char *opname = _PyOpcode_OpName[opcode]; assert(opname != NULL); int offset = (int)(next_instr - _PyCode_CODE(frame->f_code)); @@ -920,8 +920,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int // CPython hasn't ever traced the instruction after an EXTENDED_ARG. // Inline the EXTENDED_ARG here, so we can avoid branching there: INSTRUCTION_START(EXTENDED_ARG); - opcode = _Py_OPCODE(*next_instr); - oparg = oparg << 8 | _Py_OPARG(*next_instr); + opcode = next_instr->op.code; + oparg = oparg << 8 | next_instr->op.arg; // Make sure the next instruction isn't a RESUME, since that needs // to trace properly (and shouldn't have an EXTENDED_ARG, anyways): assert(opcode != RESUME); @@ -946,7 +946,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int #endif /* Tell C compilers not to hold the opcode variable in the loop. next_instr points the current instruction without TARGET(). */ - opcode = _Py_OPCODE(*next_instr); + opcode = next_instr->op.code; _PyErr_Format(tstate, PyExc_SystemError, "%U:%d: unknown opcode %d", frame->f_code->co_filename, @@ -2194,7 +2194,7 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, (_PyInterpreterFrame_LASTI(frame) < instr_prev && // SEND has no quickened forms, so no need to use _PyOpcode_Deopt // here: - _Py_OPCODE(*frame->prev_instr) != SEND); + frame->prev_instr->op.code != SEND); if (trace) { result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); } diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 691bf8e1caae95..ce1a71ec92bf36 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -100,7 +100,7 @@ #define DISPATCH_SAME_OPARG() \ { \ - opcode = _Py_OPCODE(*next_instr); \ + opcode = next_instr->op.code; \ PRE_DISPATCH_GOTO(); \ opcode |= cframe.use_tracing OR_DTRACE_LINE; \ DISPATCH_GOTO(); \ @@ -143,8 +143,8 @@ GETITEM(PyObject *v, Py_ssize_t i) { #define INSTR_OFFSET() ((int)(next_instr - _PyCode_CODE(frame->f_code))) #define NEXTOPARG() do { \ _Py_CODEUNIT word = *next_instr; \ - opcode = _Py_OPCODE(word); \ - oparg = _Py_OPARG(word); \ + opcode = word.op.code; \ + oparg = word.op.arg; \ } while (0) #define JUMPTO(x) (next_instr = _PyCode_CODE(frame->f_code) + (x)) #define JUMPBY(x) (next_instr += (x)) @@ -183,9 +183,9 @@ GETITEM(PyObject *v, Py_ssize_t i) { #define PREDICT(op) \ do { \ _Py_CODEUNIT word = *next_instr; \ - opcode = _Py_OPCODE(word) | cframe.use_tracing OR_DTRACE_LINE; \ + opcode = word.op.code | cframe.use_tracing OR_DTRACE_LINE; \ if (opcode == op) { \ - oparg = _Py_OPARG(word); \ + oparg = word.op.arg; \ INSTRUCTION_START(op); \ goto PREDICT_ID(op); \ } \ diff --git a/Python/compile.c b/Python/compile.c index 7ad62e254ab934..ed31805a73f995 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -274,31 +274,31 @@ write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen) int caches = _PyOpcode_Caches[opcode]; switch (ilen - caches) { case 4: - _Py_SET_OPCODE(*codestr, EXTENDED_ARG); - _Py_SET_OPARG(*codestr, (oparg >> 24) & 0xFF); + codestr->op.code = EXTENDED_ARG; + codestr->op.arg = (oparg >> 24) & 0xFF; codestr++; /* fall through */ case 3: - _Py_SET_OPCODE(*codestr, EXTENDED_ARG); - _Py_SET_OPARG(*codestr, (oparg >> 16) & 0xFF); + codestr->op.code = EXTENDED_ARG; + codestr->op.arg = (oparg >> 16) & 0xFF; codestr++; /* fall through */ case 2: - _Py_SET_OPCODE(*codestr, EXTENDED_ARG); - _Py_SET_OPARG(*codestr, (oparg >> 8) & 0xFF); + codestr->op.code = EXTENDED_ARG; + codestr->op.arg = (oparg >> 8) & 0xFF; codestr++; /* fall through */ case 1: - _Py_SET_OPCODE(*codestr, opcode); - _Py_SET_OPARG(*codestr, oparg & 0xFF); + codestr->op.code = opcode; + codestr->op.arg = oparg & 0xFF; codestr++; break; default: Py_UNREACHABLE(); } while (caches--) { - _Py_SET_OPCODE(*codestr, CACHE); - _Py_SET_OPARG(*codestr, 0); + codestr->op.code = CACHE; + codestr->op.arg = 0; codestr++; } } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index beb797cbd233d7..01413d2a8c1f22 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -339,9 +339,9 @@ DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; - assert(_Py_OPCODE(true_next) == STORE_FAST || - _Py_OPCODE(true_next) == STORE_FAST__LOAD_FAST); - PyObject **target_local = &GETLOCAL(_Py_OPARG(true_next)); + assert(true_next.op.code == STORE_FAST || + true_next.op.code == STORE_FAST__LOAD_FAST); + PyObject **target_local = &GETLOCAL(true_next.op.arg); DEOPT_IF(*target_local != left, BINARY_OP); STAT_INC(BINARY_OP, hit); /* Handle `left = left + right` or `left += right` for str. @@ -2196,10 +2196,10 @@ Py_DECREF(left); Py_DECREF(right); if (cond == NULL) goto pop_2_error; - assert(_Py_OPCODE(next_instr[1]) == POP_JUMP_IF_FALSE || - _Py_OPCODE(next_instr[1]) == POP_JUMP_IF_TRUE); - bool jump_on_true = _Py_OPCODE(next_instr[1]) == POP_JUMP_IF_TRUE; - int offset = _Py_OPARG(next_instr[1]); + assert(next_instr[1].op.code == POP_JUMP_IF_FALSE || + next_instr[1].op.code == POP_JUMP_IF_TRUE); + bool jump_on_true = next_instr[1].op.code == POP_JUMP_IF_TRUE; + int offset = next_instr[1].op.arg; int err = PyObject_IsTrue(cond); Py_DECREF(cond); if (err < 0) { @@ -2227,7 +2227,7 @@ _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); if (sign_ish & oparg) { - int offset = _Py_OPARG(next_instr[1]); + int offset = next_instr[1].op.arg; JUMPBY(offset); } STACK_SHRINK(2); @@ -2252,7 +2252,7 @@ _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); if (sign_ish & oparg) { - int offset = _Py_OPARG(next_instr[1]); + int offset = next_instr[1].op.arg; JUMPBY(offset); } STACK_SHRINK(2); @@ -2275,7 +2275,7 @@ assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); if ((res + COMPARISON_NOT_EQUALS) & oparg) { - int offset = _Py_OPARG(next_instr[1]); + int offset = next_instr[1].op.arg; JUMPBY(offset); } STACK_SHRINK(2); @@ -2679,7 +2679,7 @@ _PyErr_Clear(tstate); } /* iterator ended normally */ - assert(_Py_OPCODE(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg]) == END_FOR); + assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR); Py_DECREF(iter); STACK_SHRINK(1); /* Jump forward oparg, then skip following END_FOR instruction */ @@ -2758,7 +2758,7 @@ DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); _Py_CODEUNIT next = next_instr[INLINE_CACHE_ENTRIES_FOR_ITER]; - assert(_PyOpcode_Deopt[_Py_OPCODE(next)] == STORE_FAST); + assert(_PyOpcode_Deopt[next.op.code] == STORE_FAST); if (r->len <= 0) { STACK_SHRINK(1); Py_DECREF(r); @@ -2769,7 +2769,7 @@ long value = r->start; r->start = value + r->step; r->len--; - if (_PyLong_AssignValue(&GETLOCAL(_Py_OPARG(next)), value) < 0) { + if (_PyLong_AssignValue(&GETLOCAL(next.op.arg), value) < 0) { goto error; } // The STORE_FAST is already done. @@ -2792,7 +2792,7 @@ gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg); - assert(_Py_OPCODE(*next_instr) == END_FOR); + assert(next_instr->op.code == END_FOR); DISPATCH_INLINED(gen_frame); } @@ -3513,7 +3513,7 @@ STACK_SHRINK(3); // CALL + POP_TOP JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); - assert(_Py_OPCODE(next_instr[-1]) == POP_TOP); + assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); } @@ -3900,8 +3900,8 @@ TARGET(EXTENDED_ARG) { assert(oparg); assert(cframe.use_tracing == 0); - opcode = _Py_OPCODE(*next_instr); - oparg = oparg << 8 | _Py_OPARG(*next_instr); + opcode = next_instr->op.code; + oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index f27906a3e349eb..60eafe8ddb5a84 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -1,5 +1,5 @@ -// This file is generated by Tools/cases_generator/generate_cases.py --metadata -// from Python/bytecodes.c +// This file is generated by Tools\cases_generator\generate_cases.py --metadata +// from Python\bytecodes.c // Do not edit! #ifndef NEED_OPCODE_TABLES diff --git a/Python/specialize.c b/Python/specialize.c index 8bbf8fe9e19249..c9555f8ad4dccb 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -282,7 +282,7 @@ _PyCode_Quicken(PyCodeObject *code) _Py_CODEUNIT *instructions = _PyCode_CODE(code); for (int i = 0; i < Py_SIZE(code); i++) { int previous_opcode = opcode; - opcode = _PyOpcode_Deopt[_Py_OPCODE(instructions[i])]; + opcode = _PyOpcode_Deopt[instructions[i].op.code]; int caches = _PyOpcode_Caches[opcode]; if (caches) { instructions[i + 1].cache = adaptive_counter_warmup(); @@ -291,31 +291,31 @@ _PyCode_Quicken(PyCodeObject *code) } switch (previous_opcode << 8 | opcode) { case LOAD_CONST << 8 | LOAD_FAST: - _Py_SET_OPCODE(instructions[i - 1], LOAD_CONST__LOAD_FAST); + instructions[i - 1].op.code = LOAD_CONST__LOAD_FAST; break; case LOAD_FAST << 8 | LOAD_CONST: - _Py_SET_OPCODE(instructions[i - 1], LOAD_FAST__LOAD_CONST); + instructions[i - 1].op.code = LOAD_FAST__LOAD_CONST; break; case LOAD_FAST << 8 | LOAD_FAST: - _Py_SET_OPCODE(instructions[i - 1], LOAD_FAST__LOAD_FAST); + instructions[i - 1].op.code = LOAD_FAST__LOAD_FAST; break; case STORE_FAST << 8 | LOAD_FAST: - _Py_SET_OPCODE(instructions[i - 1], STORE_FAST__LOAD_FAST); + instructions[i - 1].op.code = STORE_FAST__LOAD_FAST; break; case STORE_FAST << 8 | STORE_FAST: - _Py_SET_OPCODE(instructions[i - 1], STORE_FAST__STORE_FAST); + instructions[i - 1].op.code = STORE_FAST__STORE_FAST; break; case COMPARE_OP << 8 | POP_JUMP_IF_TRUE: case COMPARE_OP << 8 | POP_JUMP_IF_FALSE: { - int oparg = _Py_OPARG(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP]); + int oparg = instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].op.arg; assert((oparg >> 4) <= Py_GE); int mask = compare_masks[oparg >> 4]; if (opcode == POP_JUMP_IF_FALSE) { mask = mask ^ 0xf; } - _Py_SET_OPCODE(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP], COMPARE_AND_BRANCH); - _Py_SET_OPARG(instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP], (oparg & 0xf0) | mask); + instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].op.code = COMPARE_AND_BRANCH; + instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].op.arg = (oparg & 0xf0) | mask; break; } } @@ -519,7 +519,7 @@ specialize_module_load_attr( } write_u32(cache->version, keys_version); cache->index = (uint16_t)index; - _py_set_opcode(instr, LOAD_ATTR_MODULE); + instr->op.code = LOAD_ATTR_MODULE; return 0; } @@ -674,7 +674,7 @@ specialize_dict_access( } write_u32(cache->version, type->tp_version_tag); cache->index = (uint16_t)index; - _py_set_opcode(instr, values_op); + instr->op.code = values_op; } else { PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); @@ -694,7 +694,7 @@ specialize_dict_access( } cache->index = (uint16_t)index; write_u32(cache->version, type->tp_version_tag); - _py_set_opcode(instr, hint_op); + instr->op.code = hint_op; } return 1; } @@ -739,7 +739,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) goto fail; case METHOD: { - int oparg = _Py_OPARG(*instr); + int oparg = instr->op.arg; if (oparg & 1) { if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { goto success; @@ -775,7 +775,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); + instr->op.code = LOAD_ATTR_PROPERTY; goto success; } case OBJECT_SLOT: @@ -799,7 +799,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); + instr->op.code = LOAD_ATTR_SLOT; goto success; } case DUNDER_CLASS: @@ -808,7 +808,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); + instr->op.code = LOAD_ATTR_SLOT; goto success; } case OTHER_SLOT: @@ -836,7 +836,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); + instr->op.code = LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN; goto success; } case BUILTIN_CLASSMETHOD: @@ -867,7 +867,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); + instr->op.code = LOAD_ATTR; cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -927,7 +927,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); + instr->op.code = STORE_ATTR_SLOT; goto success; } case DUNDER_CLASS: @@ -963,7 +963,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); + instr->op.code = STORE_ATTR; cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -1027,7 +1027,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); + instr->op.code = LOAD_ATTR_CLASS; return 0; #ifdef Py_STATS case ABSENT: @@ -1069,7 +1069,7 @@ PyObject *descr, DescriptorClassification kind) return 0; } write_u32(cache->keys_version, keys_version); - _py_set_opcode(instr, LOAD_ATTR_METHOD_WITH_VALUES); + instr->op.code = LOAD_ATTR_METHOD_WITH_VALUES; } else { Py_ssize_t dictoffset = owner_cls->tp_dictoffset; @@ -1078,7 +1078,7 @@ PyObject *descr, DescriptorClassification kind) return 0; } if (dictoffset == 0) { - _py_set_opcode(instr, LOAD_ATTR_METHOD_NO_DICT); + instr->op.code = LOAD_ATTR_METHOD_NO_DICT; } else { PyObject *dict = *(PyObject **) ((char *)owner + dictoffset); @@ -1088,7 +1088,7 @@ PyObject *descr, DescriptorClassification kind) } assert(owner_cls->tp_dictoffset > 0); assert(owner_cls->tp_dictoffset <= INT16_MAX); - _py_set_opcode(instr, LOAD_ATTR_METHOD_LAZY_DICT); + instr->op.code = LOAD_ATTR_METHOD_LAZY_DICT; } } /* `descr` is borrowed. This is safe for methods (even inherited ones from @@ -1146,7 +1146,7 @@ _Py_Specialize_LoadGlobal( } cache->index = (uint16_t)index; write_u32(cache->module_keys_version, keys_version); - _py_set_opcode(instr, LOAD_GLOBAL_MODULE); + instr->op.code = LOAD_GLOBAL_MODULE; goto success; } if (!PyDict_CheckExact(builtins)) { @@ -1184,12 +1184,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); + instr->op.code = LOAD_GLOBAL_BUILTIN; goto success; fail: STAT_INC(LOAD_GLOBAL, failure); assert(!PyErr_Occurred()); - _py_set_opcode(instr, LOAD_GLOBAL); + instr->op.code = LOAD_GLOBAL; cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -1295,7 +1295,7 @@ _Py_Specialize_BinarySubscr( if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { if (Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) { - _py_set_opcode(instr, BINARY_SUBSCR_LIST_INT); + instr->op.code = BINARY_SUBSCR_LIST_INT; goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE); @@ -1308,7 +1308,7 @@ _Py_Specialize_BinarySubscr( if (container_type == &PyTuple_Type) { if (PyLong_CheckExact(sub)) { if (Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) { - _py_set_opcode(instr, BINARY_SUBSCR_TUPLE_INT); + instr->op.code = BINARY_SUBSCR_TUPLE_INT; goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE); @@ -1319,7 +1319,7 @@ _Py_Specialize_BinarySubscr( goto fail; } if (container_type == &PyDict_Type) { - _py_set_opcode(instr, BINARY_SUBSCR_DICT); + instr->op.code = BINARY_SUBSCR_DICT; goto success; } PyTypeObject *cls = Py_TYPE(container); @@ -1350,7 +1350,7 @@ _Py_Specialize_BinarySubscr( } cache->func_version = version; ((PyHeapTypeObject *)container_type)->_spec_cache.getitem = descriptor; - _py_set_opcode(instr, BINARY_SUBSCR_GETITEM); + instr->op.code = BINARY_SUBSCR_GETITEM; goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, @@ -1358,7 +1358,7 @@ _Py_Specialize_BinarySubscr( fail: STAT_INC(BINARY_SUBSCR, failure); assert(!PyErr_Occurred()); - _py_set_opcode(instr, BINARY_SUBSCR); + instr->op.code = BINARY_SUBSCR; cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -1378,7 +1378,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins if ((Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) && ((PyLongObject *)sub)->long_value.ob_digit[0] < (size_t)PyList_GET_SIZE(container)) { - _py_set_opcode(instr, STORE_SUBSCR_LIST_INT); + instr->op.code = STORE_SUBSCR_LIST_INT; goto success; } else { @@ -1396,8 +1396,8 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins } } if (container_type == &PyDict_Type) { - _py_set_opcode(instr, STORE_SUBSCR_DICT); - goto success; + instr->op.code = STORE_SUBSCR_DICT; + goto success; } #ifdef Py_STATS PyMappingMethods *as_mapping = container_type->tp_as_mapping; @@ -1463,7 +1463,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); + instr->op.code = STORE_SUBSCR; cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -1482,23 +1482,23 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, return -1; } if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { - int oparg = _Py_OPARG(*instr); + int oparg = instr->op.arg; if (nargs == 1 && kwnames == NULL && oparg == 1) { if (tp == &PyUnicode_Type) { - _py_set_opcode(instr, CALL_NO_KW_STR_1); + instr->op.code = CALL_NO_KW_STR_1; return 0; } else if (tp == &PyType_Type) { - _py_set_opcode(instr, CALL_NO_KW_TYPE_1); + instr->op.code = CALL_NO_KW_TYPE_1; return 0; } else if (tp == &PyTuple_Type) { - _py_set_opcode(instr, CALL_NO_KW_TUPLE_1); + instr->op.code = CALL_NO_KW_TUPLE_1; return 0; } } if (tp->tp_vectorcall != NULL) { - _py_set_opcode(instr, CALL_BUILTIN_CLASS); + instr->op.code = CALL_BUILTIN_CLASS; return 0; } SPECIALIZATION_FAIL(CALL, tp == &PyUnicode_Type ? @@ -1573,7 +1573,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); + instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS; return 0; } case METH_O: { @@ -1584,21 +1584,21 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, PyInterpreterState *interp = _PyInterpreterState_GET(); PyObject *list_append = interp->callable_cache.list_append; _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_CALL + 1]; - bool pop = (_Py_OPCODE(next) == POP_TOP); - int oparg = _Py_OPARG(*instr); + bool pop = (next.op.code == POP_TOP); + int oparg = instr->op.arg; if ((PyObject *)descr == list_append && oparg == 1 && pop) { - _py_set_opcode(instr, CALL_NO_KW_LIST_APPEND); + instr->op.code = CALL_NO_KW_LIST_APPEND; return 0; } - _py_set_opcode(instr, CALL_NO_KW_METHOD_DESCRIPTOR_O); + instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_O; return 0; } case METH_FASTCALL: { - _py_set_opcode(instr, CALL_NO_KW_METHOD_DESCRIPTOR_FAST); + instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_FAST; return 0; } case METH_FASTCALL | METH_KEYWORDS: { - _py_set_opcode(instr, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS); + instr->op.code = CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS; return 0; } } @@ -1649,14 +1649,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); + instr->op.code = 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); + instr->op.code = CALL_PY_WITH_DEFAULTS; } return 0; } @@ -1683,10 +1683,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); + instr->op.code = CALL_NO_KW_LEN; return 0; } - _py_set_opcode(instr, CALL_NO_KW_BUILTIN_O); + instr->op.code = CALL_NO_KW_BUILTIN_O; return 0; } case METH_FASTCALL: { @@ -1698,15 +1698,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); + instr->op.code = CALL_NO_KW_ISINSTANCE; return 0; } } - _py_set_opcode(instr, CALL_NO_KW_BUILTIN_FAST); + instr->op.code = CALL_NO_KW_BUILTIN_FAST; return 0; } case METH_FASTCALL | METH_KEYWORDS: { - _py_set_opcode(instr, CALL_BUILTIN_FAST_WITH_KEYWORDS); + instr->op.code = CALL_BUILTIN_FAST_WITH_KEYWORDS; return 0; } default: @@ -1785,7 +1785,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); + instr->op.code = CALL; cache->counter = adaptive_counter_backoff(cache->counter); } else { @@ -1880,21 +1880,21 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, } if (PyUnicode_CheckExact(lhs)) { _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_BINARY_OP + 1]; - 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); + bool to_store = (next.op.code == STORE_FAST || + next.op.code == STORE_FAST__LOAD_FAST); + if (to_store && locals[next.op.arg] == lhs) { + instr->op.code = BINARY_OP_INPLACE_ADD_UNICODE; goto success; } - _py_set_opcode(instr, BINARY_OP_ADD_UNICODE); + instr->op.code = BINARY_OP_ADD_UNICODE; goto success; } if (PyLong_CheckExact(lhs)) { - _py_set_opcode(instr, BINARY_OP_ADD_INT); + instr->op.code = BINARY_OP_ADD_INT; goto success; } if (PyFloat_CheckExact(lhs)) { - _py_set_opcode(instr, BINARY_OP_ADD_FLOAT); + instr->op.code = BINARY_OP_ADD_FLOAT; goto success; } break; @@ -1904,11 +1904,11 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, break; } if (PyLong_CheckExact(lhs)) { - _py_set_opcode(instr, BINARY_OP_MULTIPLY_INT); + instr->op.code = BINARY_OP_MULTIPLY_INT; goto success; } if (PyFloat_CheckExact(lhs)) { - _py_set_opcode(instr, BINARY_OP_MULTIPLY_FLOAT); + instr->op.code = BINARY_OP_MULTIPLY_FLOAT; goto success; } break; @@ -1918,18 +1918,18 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, break; } if (PyLong_CheckExact(lhs)) { - _py_set_opcode(instr, BINARY_OP_SUBTRACT_INT); + instr->op.code = BINARY_OP_SUBTRACT_INT; goto success; } if (PyFloat_CheckExact(lhs)) { - _py_set_opcode(instr, BINARY_OP_SUBTRACT_FLOAT); + instr->op.code = 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); + instr->op.code = BINARY_OP; cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -1981,7 +1981,7 @@ _Py_Specialize_CompareAndBranch(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *inst assert(_PyOpcode_Caches[COMPARE_AND_BRANCH] == INLINE_CACHE_ENTRIES_COMPARE_OP); _PyCompareOpCache *cache = (_PyCompareOpCache *)(instr + 1); #ifndef NDEBUG - int next_opcode = _Py_OPCODE(instr[INLINE_CACHE_ENTRIES_COMPARE_OP + 1]); + int next_opcode = instr[INLINE_CACHE_ENTRIES_COMPARE_OP + 1].op.code; assert(next_opcode == POP_JUMP_IF_FALSE || next_opcode == POP_JUMP_IF_TRUE); #endif if (Py_TYPE(lhs) != Py_TYPE(rhs)) { @@ -1989,12 +1989,12 @@ _Py_Specialize_CompareAndBranch(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *inst goto failure; } if (PyFloat_CheckExact(lhs)) { - _py_set_opcode(instr, COMPARE_AND_BRANCH_FLOAT); + instr->op.code = COMPARE_AND_BRANCH_FLOAT; goto success; } if (PyLong_CheckExact(lhs)) { if (Py_ABS(Py_SIZE(lhs)) <= 1 && Py_ABS(Py_SIZE(rhs)) <= 1) { - _py_set_opcode(instr, COMPARE_AND_BRANCH_INT); + instr->op.code = COMPARE_AND_BRANCH_INT; goto success; } else { @@ -2009,14 +2009,14 @@ _Py_Specialize_CompareAndBranch(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *inst goto failure; } else { - _py_set_opcode(instr, COMPARE_AND_BRANCH_STR); + instr->op.code = COMPARE_AND_BRANCH_STR; goto success; } } SPECIALIZATION_FAIL(COMPARE_AND_BRANCH, compare_op_fail_kind(lhs, rhs)); failure: STAT_INC(COMPARE_AND_BRANCH, failure); - _py_set_opcode(instr, COMPARE_AND_BRANCH); + instr->op.code = COMPARE_AND_BRANCH; cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -2051,10 +2051,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); + instr->op.code = UNPACK_SEQUENCE_TWO_TUPLE; goto success; } - _py_set_opcode(instr, UNPACK_SEQUENCE_TUPLE); + instr->op.code = UNPACK_SEQUENCE_TUPLE; goto success; } if (PyList_CheckExact(seq)) { @@ -2062,13 +2062,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); + instr->op.code = 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); + instr->op.code = UNPACK_SEQUENCE; cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -2156,28 +2156,28 @@ _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg) _PyForIterCache *cache = (_PyForIterCache *)(instr + 1); PyTypeObject *tp = Py_TYPE(iter); _Py_CODEUNIT next = instr[1+INLINE_CACHE_ENTRIES_FOR_ITER]; - int next_op = _PyOpcode_Deopt[_Py_OPCODE(next)]; + int next_op = _PyOpcode_Deopt[next.op.code]; if (tp == &PyListIter_Type) { - _py_set_opcode(instr, FOR_ITER_LIST); + instr->op.code = FOR_ITER_LIST; goto success; } else if (tp == &PyTupleIter_Type) { - _py_set_opcode(instr, FOR_ITER_TUPLE); + instr->op.code = FOR_ITER_TUPLE; goto success; } else if (tp == &PyRangeIter_Type && next_op == STORE_FAST) { - _py_set_opcode(instr, FOR_ITER_RANGE); + instr->op.code = 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); + assert(instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1].op.code == END_FOR); + instr->op.code = FOR_ITER_GEN; goto success; } SPECIALIZATION_FAIL(FOR_ITER, _PySpecialization_ClassifyIterator(iter)); STAT_INC(FOR_ITER, failure); - _py_set_opcode(instr, FOR_ITER); + instr->op.code = FOR_ITER; cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -2193,13 +2193,13 @@ _Py_Specialize_Send(PyObject *receiver, _Py_CODEUNIT *instr) _PySendCache *cache = (_PySendCache *)(instr + 1); PyTypeObject *tp = Py_TYPE(receiver); if (tp == &PyGen_Type || tp == &PyCoro_Type) { - _py_set_opcode(instr, SEND_GEN); + instr->op.code = SEND_GEN; goto success; } SPECIALIZATION_FAIL(SEND, _PySpecialization_ClassifyIterator(receiver)); STAT_INC(SEND, failure); - _py_set_opcode(instr, SEND); + instr->op.code = SEND; cache->counter = adaptive_counter_backoff(cache->counter); return; success: From a5174637c56d8b437fb328e9fbed5571fbc8fe03 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 14 Feb 2023 20:40:55 +0000 Subject: [PATCH 4/7] Rename macro parameter --- Python/ceval_macros.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index ce1a71ec92bf36..ac1fec77daca8a 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -180,14 +180,14 @@ GETITEM(PyObject *v, Py_ssize_t i) { #if USE_COMPUTED_GOTOS #define PREDICT(op) if (0) goto PREDICT_ID(op) #else -#define PREDICT(op) \ +#define PREDICT(next_op) \ do { \ _Py_CODEUNIT word = *next_instr; \ opcode = word.op.code | cframe.use_tracing OR_DTRACE_LINE; \ - if (opcode == op) { \ + if (opcode == next_op) { \ oparg = word.op.arg; \ - INSTRUCTION_START(op); \ - goto PREDICT_ID(op); \ + INSTRUCTION_START(next_op); \ + goto PREDICT_ID(next_op); \ } \ } while(0) #endif From 2bcfd8d41cd6e2170314a065652939461ecdb38f Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 14 Feb 2023 20:56:23 +0000 Subject: [PATCH 5/7] Make cases_generator correct on Windows --- Python/generated_cases.c.h | 2 +- Python/opcode_metadata.h | 4 ++-- Tools/cases_generator/generate_cases.py | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 01413d2a8c1f22..4cd1b0656f8ec3 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1,5 +1,5 @@ // This file is generated by Tools/cases_generator/generate_cases.py -// from Python/bytecodes.c +// from Python\bytecodes.c // Do not edit! TARGET(NOP) { diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index 60eafe8ddb5a84..f27906a3e349eb 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -1,5 +1,5 @@ -// This file is generated by Tools\cases_generator\generate_cases.py --metadata -// from Python\bytecodes.c +// This file is generated by Tools/cases_generator/generate_cases.py --metadata +// from Python/bytecodes.c // Do not edit! #ifndef NEED_OPCODE_TABLES diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py index aa8e14075c8738..6aae8c310f804c 100644 --- a/Tools/cases_generator/generate_cases.py +++ b/Tools/cases_generator/generate_cases.py @@ -8,6 +8,7 @@ import contextlib import dataclasses import os +import posixpath import re import sys import typing @@ -17,7 +18,7 @@ HERE = os.path.dirname(__file__) ROOT = os.path.join(HERE, "../..") -THIS = os.path.relpath(__file__, ROOT) +THIS = os.path.relpath(__file__, ROOT).replace(os.path.sep, posixpath.sep) DEFAULT_INPUT = os.path.relpath(os.path.join(ROOT, "Python/bytecodes.c")) DEFAULT_OUTPUT = os.path.relpath(os.path.join(ROOT, "Python/generated_cases.c.h")) @@ -930,7 +931,7 @@ def write_metadata(self) -> None: with open(self.metadata_filename, "w") as f: # Write provenance header f.write(f"// This file is generated by {THIS} --metadata\n") - f.write(f"// from {os.path.relpath(self.filename, ROOT)}\n") + f.write(f"// from {os.path.relpath(self.filename, ROOT).replace(os.path.sep, posixpath.sep)}\n") f.write(f"// Do not edit!\n") # Create formatter; the rest of the code uses this From c654b35821dfcca476f3e86456c60109f2f7b54c Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 14 Feb 2023 21:52:41 +0000 Subject: [PATCH 6/7] Fix hash func --- Objects/codeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 11bbaa7744e6b7..a03b14edea8d4c 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1850,7 +1850,7 @@ code_hash(PyCodeObject *co) for (int i = 0; i < Py_SIZE(co); i++) { int deop = _PyOpcode_Deopt[_PyCode_CODE(co)[i].op.code]; SCRAMBLE_IN(deop); - SCRAMBLE_IN(_PyCode_CODE(co)[i].op.code); + SCRAMBLE_IN(_PyCode_CODE(co)[i].op.arg); i += _PyOpcode_Caches[deop]; } if ((Py_hash_t)uhash == -1) { From 5d401ede1568e0837789e86f32e6a9ff705c33f5 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Wed, 15 Feb 2023 20:49:30 +0000 Subject: [PATCH 7/7] Fix set_opcode and generated file --- Include/cpython/code.h | 10 +++++----- Python/generated_cases.c.h | 2 +- Tools/cases_generator/generate_cases.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Include/cpython/code.h b/Include/cpython/code.h index c2064d301bd2e2..fba9296aedc99d 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -29,24 +29,24 @@ typedef union { #define _Py_OPCODE(word) ((word).op.code) #define _Py_OPARG(word) ((word).op.arg) -static inline uint16_t +static inline _Py_CODEUNIT _py_make_codeunit(uint8_t opcode, uint8_t oparg) { // No designated initialisers because of C++ compat _Py_CODEUNIT word; word.op.code = opcode; word.op.arg = oparg; - return word.cache; + return word; } static inline void -_py_set_opcode(_Py_CODEUNIT *word, uint16_t packed_opcode) +_py_set_opcode(_Py_CODEUNIT *word, uint8_t opcode) { - word->cache = packed_opcode; + word->op.code = opcode; } #define _Py_MAKE_CODEUNIT(opcode, oparg) _py_make_codeunit((opcode), (oparg)) -#define _Py_SET_OPCODE(word, opcode) _py_set_opcode(&(word), opcode) +#define _Py_SET_OPCODE(word, opcode) _py_set_opcode(&(word), (opcode)) typedef struct { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 4cd1b0656f8ec3..01413d2a8c1f22 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1,5 +1,5 @@ // This file is generated by Tools/cases_generator/generate_cases.py -// from Python\bytecodes.c +// from Python/bytecodes.c // Do not edit! TARGET(NOP) { diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py index 6aae8c310f804c..c7f52b55a5eb99 100644 --- a/Tools/cases_generator/generate_cases.py +++ b/Tools/cases_generator/generate_cases.py @@ -1010,7 +1010,7 @@ def write_instructions(self) -> None: with open(self.output_filename, "w") as f: # Write provenance header f.write(f"// This file is generated by {THIS}\n") - f.write(f"// from {os.path.relpath(self.filename, ROOT)}\n") + f.write(f"// from {os.path.relpath(self.filename, ROOT).replace(os.path.sep, posixpath.sep)}\n") f.write(f"// Do not edit!\n") # Create formatter; the rest of the code uses this