Skip to content

Commit ab87400

Browse files
Issue python#27129: Replaced wordcode related magic constants with macros.
1 parent bdb847a commit ab87400

7 files changed

Lines changed: 173 additions & 158 deletions

File tree

Include/code.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@
77
extern "C" {
88
#endif
99

10+
typedef uint16_t _Py_CODEUNIT;
11+
12+
#ifdef WORDS_BIGENDIAN
13+
# define _Py_OPCODE(word) ((word) >> 8)
14+
# define _Py_OPARG(word) ((word) & 255)
15+
#else
16+
# define _Py_OPCODE(word) ((word) & 255)
17+
# define _Py_OPARG(word) ((word) >> 8)
18+
#endif
19+
1020
/* Bytecode object */
1121
typedef struct {
1222
PyObject_HEAD

Objects/frameobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
189189
memset(blockstack, '\0', sizeof(blockstack));
190190
memset(in_finally, '\0', sizeof(in_finally));
191191
blockstack_top = 0;
192-
for (addr = 0; addr < code_len; addr += 2) {
192+
for (addr = 0; addr < code_len; addr += sizeof(_Py_CODEUNIT)) {
193193
unsigned char op = code[addr];
194194
switch (op) {
195195
case SETUP_LOOP:
@@ -273,7 +273,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
273273
* can tell whether the jump goes into any blocks without coming out
274274
* again - in that case we raise an exception below. */
275275
delta_iblock = 0;
276-
for (addr = min_addr; addr < max_addr; addr += 2) {
276+
for (addr = min_addr; addr < max_addr; addr += sizeof(_Py_CODEUNIT)) {
277277
unsigned char op = code[addr];
278278
switch (op) {
279279
case SETUP_LOOP:

Objects/genobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ _PyGen_yf(PyGenObject *gen)
390390
PyObject *bytecode = f->f_code->co_code;
391391
unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
392392

393-
if (code[f->f_lasti + 2] != YIELD_FROM)
393+
if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM)
394394
return NULL;
395395
yf = f->f_stacktop[-1];
396396
Py_INCREF(yf);
@@ -498,7 +498,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
498498
assert(ret == yf);
499499
Py_DECREF(ret);
500500
/* Termination repetition of YIELD_FROM */
501-
gen->gi_frame->f_lasti += 2;
501+
gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT);
502502
if (_PyGen_FetchStopIterationValue(&val) == 0) {
503503
ret = gen_send_ex(gen, val, 0, 0);
504504
Py_DECREF(val);

Python/ceval.c

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static int import_all_from(PyObject *, PyObject *);
6262
static void format_exc_check_arg(PyObject *, const char *, PyObject *);
6363
static void format_exc_unbound(PyCodeObject *co, int oparg);
6464
static PyObject * unicode_concatenate(PyObject *, PyObject *,
65-
PyFrameObject *, const unsigned short *);
65+
PyFrameObject *, const _Py_CODEUNIT *);
6666
static PyObject * special_lookup(PyObject *, _Py_Identifier *);
6767

6868
#define NAME_ERROR_MSG \
@@ -725,7 +725,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
725725
int lastopcode = 0;
726726
#endif
727727
PyObject **stack_pointer; /* Next free slot in value stack */
728-
const unsigned short *next_instr;
728+
const _Py_CODEUNIT *next_instr;
729729
int opcode; /* Current opcode */
730730
int oparg; /* Current opcode argument, if any */
731731
enum why_code why; /* Reason for block stack unwind */
@@ -743,7 +743,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
743743
time it is tested. */
744744
int instr_ub = -1, instr_lb = 0, instr_prev = -1;
745745

746-
const unsigned short *first_instr;
746+
const _Py_CODEUNIT *first_instr;
747747
PyObject *names;
748748
PyObject *consts;
749749

@@ -864,23 +864,16 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
864864

865865
/* Code access macros */
866866

867-
#ifdef WORDS_BIGENDIAN
868-
#define OPCODE(word) ((word) >> 8)
869-
#define OPARG(word) ((word) & 255)
870-
#else
871-
#define OPCODE(word) ((word) & 255)
872-
#define OPARG(word) ((word) >> 8)
873-
#endif
874867
/* The integer overflow is checked by an assertion below. */
875-
#define INSTR_OFFSET() (2*(int)(next_instr - first_instr))
868+
#define INSTR_OFFSET() (sizeof(_Py_CODEUNIT) * (int)(next_instr - first_instr))
876869
#define NEXTOPARG() do { \
877-
unsigned short word = *next_instr; \
878-
opcode = OPCODE(word); \
879-
oparg = OPARG(word); \
870+
_Py_CODEUNIT word = *next_instr; \
871+
opcode = _Py_OPCODE(word); \
872+
oparg = _Py_OPARG(word); \
880873
next_instr++; \
881874
} while (0)
882-
#define JUMPTO(x) (next_instr = first_instr + (x)/2)
883-
#define JUMPBY(x) (next_instr += (x)/2)
875+
#define JUMPTO(x) (next_instr = first_instr + (x) / sizeof(_Py_CODEUNIT))
876+
#define JUMPBY(x) (next_instr += (x) / sizeof(_Py_CODEUNIT))
884877

885878
/* OpCode prediction macros
886879
Some opcodes tend to come in pairs thus making it possible to
@@ -913,10 +906,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
913906
#else
914907
#define PREDICT(op) \
915908
do{ \
916-
unsigned short word = *next_instr; \
917-
opcode = OPCODE(word); \
909+
_Py_CODEUNIT word = *next_instr; \
910+
opcode = _Py_OPCODE(word); \
918911
if (opcode == op){ \
919-
oparg = OPARG(word); \
912+
oparg = _Py_OPARG(word); \
920913
next_instr++; \
921914
goto PRED_##op; \
922915
} \
@@ -1056,9 +1049,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
10561049
freevars = f->f_localsplus + co->co_nlocals;
10571050
assert(PyBytes_Check(co->co_code));
10581051
assert(PyBytes_GET_SIZE(co->co_code) <= INT_MAX);
1059-
assert(PyBytes_GET_SIZE(co->co_code) % 2 == 0);
1060-
assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(co->co_code), 2));
1061-
first_instr = (unsigned short*) PyBytes_AS_STRING(co->co_code);
1052+
assert(PyBytes_GET_SIZE(co->co_code) % sizeof(_Py_CODEUNIT) == 0);
1053+
assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(co->co_code), sizeof(_Py_CODEUNIT)));
1054+
first_instr = (_Py_CODEUNIT *) PyBytes_AS_STRING(co->co_code);
10621055
/*
10631056
f->f_lasti refers to the index of the last instruction,
10641057
unless it's -1 in which case next_instr should be first_instr.
@@ -1074,10 +1067,11 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
10741067
FOR_ITER is effectively a single opcode and f->f_lasti will point
10751068
to the beginning of the combined pair.)
10761069
*/
1070+
assert(f->f_lasti >= -1);
10771071
next_instr = first_instr;
10781072
if (f->f_lasti >= 0) {
1079-
assert(f->f_lasti % 2 == 0);
1080-
next_instr += f->f_lasti/2 + 1;
1073+
assert(f->f_lasti % sizeof(_Py_CODEUNIT) == 0);
1074+
next_instr += f->f_lasti / sizeof(_Py_CODEUNIT) + 1;
10811075
}
10821076
stack_pointer = f->f_stacktop;
10831077
assert(stack_pointer != NULL);
@@ -1125,7 +1119,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
11251119
Py_MakePendingCalls() above. */
11261120

11271121
if (_Py_atomic_load_relaxed(&eval_breaker)) {
1128-
if (OPCODE(*next_instr) == SETUP_FINALLY) {
1122+
if (_Py_OPCODE(*next_instr) == SETUP_FINALLY) {
11291123
/* Make the last opcode before
11301124
a try: finally: block uninterruptible. */
11311125
goto fast_next_opcode;
@@ -2049,7 +2043,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
20492043
f->f_stacktop = stack_pointer;
20502044
why = WHY_YIELD;
20512045
/* and repeat... */
2052-
f->f_lasti -= 2;
2046+
f->f_lasti -= sizeof(_Py_CODEUNIT);
20532047
goto fast_yield;
20542048
}
20552049

@@ -5321,7 +5315,7 @@ format_exc_unbound(PyCodeObject *co, int oparg)
53215315

53225316
static PyObject *
53235317
unicode_concatenate(PyObject *v, PyObject *w,
5324-
PyFrameObject *f, const unsigned short *next_instr)
5318+
PyFrameObject *f, const _Py_CODEUNIT *next_instr)
53255319
{
53265320
PyObject *res;
53275321
if (Py_REFCNT(v) == 2) {

Python/compile.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4948,7 +4948,7 @@ assemble_lnotab(struct assembler *a, struct instr *i)
49484948
Py_ssize_t len;
49494949
unsigned char *lnotab;
49504950

4951-
d_bytecode = a->a_offset - a->a_lineno_off;
4951+
d_bytecode = (a->a_offset - a->a_lineno_off) * sizeof(_Py_CODEUNIT);
49524952
d_lineno = i->i_lineno - a->a_lineno;
49534953

49544954
assert(d_bytecode >= 0);
@@ -5055,21 +5055,21 @@ assemble_emit(struct assembler *a, struct instr *i)
50555055
{
50565056
int size, arg = 0;
50575057
Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
5058-
char *code;
5058+
_Py_CODEUNIT *code;
50595059

50605060
arg = i->i_oparg;
50615061
size = instrsize(arg);
50625062
if (i->i_lineno && !assemble_lnotab(a, i))
50635063
return 0;
5064-
if (a->a_offset + size >= len) {
5064+
if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) {
50655065
if (len > PY_SSIZE_T_MAX / 2)
50665066
return 0;
50675067
if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0)
50685068
return 0;
50695069
}
5070-
code = PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
5070+
code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
50715071
a->a_offset += size;
5072-
write_op_arg((unsigned char*)code, i->i_opcode, arg, size);
5072+
write_op_arg(code, i->i_opcode, arg, size);
50735073
return 1;
50745074
}
50755075

@@ -5106,6 +5106,7 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c)
51065106
if (instr->i_jrel) {
51075107
instr->i_oparg -= bsize;
51085108
}
5109+
instr->i_oparg *= sizeof(_Py_CODEUNIT);
51095110
if (instrsize(instr->i_oparg) != isize) {
51105111
extended_arg_recompile = 1;
51115112
}
@@ -5351,7 +5352,7 @@ assemble(struct compiler *c, int addNone)
53515352

53525353
if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)
53535354
goto error;
5354-
if (_PyBytes_Resize(&a.a_bytecode, a.a_offset) < 0)
5355+
if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0)
53555356
goto error;
53565357

53575358
co = makecode(c, &a);

0 commit comments

Comments
 (0)