mirror of https://github.com/python/cpython
bpo-45152: Add HAS_CONST macro and get_const_value() function and use… (#28262)
This commit is contained in:
parent
9f93018b69
commit
c2f1e95337
|
@ -190,6 +190,10 @@ static uint32_t _PyOpcode_Jump[8] = {
|
|||
};
|
||||
#endif /* OPCODE_TABLES */
|
||||
|
||||
#define HAS_CONST(op) (false\
|
||||
|| ((op) == 100) \
|
||||
)
|
||||
|
||||
#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT)
|
||||
|
||||
/* Reserve some bytecodes for internal use in the compiler.
|
||||
|
|
|
@ -1638,14 +1638,14 @@ compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b)
|
|||
}
|
||||
|
||||
#define ADDOP_O(C, OP, O, TYPE) { \
|
||||
assert((OP) != LOAD_CONST); /* use ADDOP_LOAD_CONST */ \
|
||||
assert(!HAS_CONST(OP)); /* use ADDOP_LOAD_CONST */ \
|
||||
if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
/* Same as ADDOP_O, but steals a reference. */
|
||||
#define ADDOP_N(C, OP, O, TYPE) { \
|
||||
assert((OP) != LOAD_CONST); /* use ADDOP_LOAD_CONST_NEW */ \
|
||||
assert(!HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */ \
|
||||
if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \
|
||||
Py_DECREF((O)); \
|
||||
return 0; \
|
||||
|
@ -7951,6 +7951,24 @@ assemble(struct compiler *c, int addNone)
|
|||
return co;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
get_const_value(int opcode, int oparg, PyObject *co_consts)
|
||||
{
|
||||
PyObject *constant = NULL;
|
||||
assert(HAS_CONST(opcode));
|
||||
if (opcode == LOAD_CONST) {
|
||||
constant = PyList_GET_ITEM(co_consts, oparg);
|
||||
}
|
||||
|
||||
if (constant == NULL) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"Internal error: failed to get value of a constant");
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(constant);
|
||||
return constant;
|
||||
}
|
||||
|
||||
/* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n
|
||||
with LOAD_CONST (c1, c2, ... cn).
|
||||
The consts table must still be in list form so that the
|
||||
|
@ -7968,7 +7986,7 @@ fold_tuple_on_constants(struct compiler *c,
|
|||
assert(inst[n].i_oparg == n);
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (inst[i].i_opcode != LOAD_CONST) {
|
||||
if (!HAS_CONST(inst[i].i_opcode)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -7979,9 +7997,12 @@ fold_tuple_on_constants(struct compiler *c,
|
|||
return -1;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
int op = inst[i].i_opcode;
|
||||
int arg = inst[i].i_oparg;
|
||||
PyObject *constant = PyList_GET_ITEM(consts, arg);
|
||||
Py_INCREF(constant);
|
||||
PyObject *constant = get_const_value(op, arg, consts);
|
||||
if (constant == NULL) {
|
||||
return -1;
|
||||
}
|
||||
PyTuple_SET_ITEM(newconst, i, constant);
|
||||
}
|
||||
if (merge_const_one(c, &newconst) == 0) {
|
||||
|
@ -8107,8 +8128,12 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
|
|||
switch(nextop) {
|
||||
case POP_JUMP_IF_FALSE:
|
||||
case POP_JUMP_IF_TRUE:
|
||||
cnt = PyList_GET_ITEM(consts, oparg);
|
||||
cnt = get_const_value(inst->i_opcode, oparg, consts);
|
||||
if (cnt == NULL) {
|
||||
goto error;
|
||||
}
|
||||
is_true = PyObject_IsTrue(cnt);
|
||||
Py_DECREF(cnt);
|
||||
if (is_true == -1) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -8124,8 +8149,12 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
|
|||
break;
|
||||
case JUMP_IF_FALSE_OR_POP:
|
||||
case JUMP_IF_TRUE_OR_POP:
|
||||
cnt = PyList_GET_ITEM(consts, oparg);
|
||||
cnt = get_const_value(inst->i_opcode, oparg, consts);
|
||||
if (cnt == NULL) {
|
||||
goto error;
|
||||
}
|
||||
is_true = PyObject_IsTrue(cnt);
|
||||
Py_DECREF(cnt);
|
||||
if (is_true == -1) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -8310,6 +8339,9 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
|
|||
fold_rotations(inst - oparg + 1, oparg);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* All HAS_CONST opcodes should be handled with LOAD_CONST */
|
||||
assert (!HAS_CONST(inst->i_opcode));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -51,6 +51,7 @@ def main(opcode_py, outfile='Include/opcode.h'):
|
|||
code = fp.read()
|
||||
exec(code, opcode)
|
||||
opmap = opcode['opmap']
|
||||
hasconst = opcode['hasconst']
|
||||
hasjrel = opcode['hasjrel']
|
||||
hasjabs = opcode['hasjabs']
|
||||
used = [ False ] * 256
|
||||
|
@ -65,15 +66,24 @@ def main(opcode_py, outfile='Include/opcode.h'):
|
|||
if name == 'POP_EXCEPT': # Special entry for HAVE_ARGUMENT
|
||||
fobj.write("#define %-23s %3d\n" %
|
||||
('HAVE_ARGUMENT', opcode['HAVE_ARGUMENT']))
|
||||
|
||||
for name in opcode['_specialized_instructions']:
|
||||
while used[next_op]:
|
||||
next_op += 1
|
||||
fobj.write("#define %-23s %3s\n" % (name, next_op))
|
||||
used[next_op] = True
|
||||
|
||||
fobj.write("#ifdef NEED_OPCODE_JUMP_TABLES\n")
|
||||
write_int_array_from_ops("_PyOpcode_RelativeJump", opcode['hasjrel'], fobj)
|
||||
write_int_array_from_ops("_PyOpcode_Jump", opcode['hasjrel'] + opcode['hasjabs'], fobj)
|
||||
fobj.write("#endif /* OPCODE_TABLES */\n")
|
||||
|
||||
fobj.write("\n")
|
||||
fobj.write("#define HAS_CONST(op) (false\\")
|
||||
for op in hasconst:
|
||||
fobj.write(f"\n || ((op) == {op}) \\")
|
||||
fobj.write("\n )\n")
|
||||
|
||||
fobj.write(footer)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue