summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/bytecodes.c17
-rw-r--r--Python/compile.c17
-rw-r--r--Python/generated_cases.c.h17
-rw-r--r--Python/opcode_metadata.h5
-rw-r--r--Python/opcode_targets.h8
5 files changed, 53 insertions, 11 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index b43625f..0d7d922 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -555,6 +555,23 @@ dummy_func(
goto resume_frame;
}
+ inst(RETURN_CONST, (--)) {
+ PyObject *retval = GETITEM(consts, oparg);
+ Py_INCREF(retval);
+ assert(EMPTY());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ TRACE_FUNCTION_EXIT();
+ DTRACE_FUNCTION_EXIT();
+ _Py_LeaveRecursiveCallPy(tstate);
+ assert(frame != &entry_frame);
+ // GH-99729: We need to unlink the frame *before* clearing it:
+ _PyInterpreterFrame *dying = frame;
+ frame = cframe.current_frame = dying->previous;
+ _PyEvalFrameClearAndPop(tstate, dying);
+ _PyFrame_StackPush(frame, retval);
+ goto resume_frame;
+ }
+
inst(GET_AITER, (obj -- iter)) {
unaryfunc getter = NULL;
PyTypeObject *type = Py_TYPE(obj);
diff --git a/Python/compile.c b/Python/compile.c
index d9ec689..df2dffb 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -124,6 +124,7 @@
#define IS_SCOPE_EXIT_OPCODE(opcode) \
((opcode) == RETURN_VALUE || \
+ (opcode) == RETURN_CONST || \
(opcode) == RAISE_VARARGS || \
(opcode) == RERAISE)
@@ -354,7 +355,7 @@ basicblock_last_instr(const basicblock *b) {
static inline int
basicblock_returns(const basicblock *b) {
struct instr *last = basicblock_last_instr(b);
- return last && last->i_opcode == RETURN_VALUE;
+ return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST);
}
static inline int
@@ -1119,6 +1120,8 @@ stack_effect(int opcode, int oparg, int jump)
case RETURN_VALUE:
return -1;
+ case RETURN_CONST:
+ return 0;
case SETUP_ANNOTATIONS:
return 0;
case YIELD_VALUE:
@@ -9261,6 +9264,10 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
}
Py_DECREF(cnt);
break;
+ case RETURN_VALUE:
+ INSTR_SET_OP1(inst, RETURN_CONST, oparg);
+ INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
+ break;
}
break;
}
@@ -9723,9 +9730,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
/* mark used consts */
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
- if (b->b_instr[i].i_opcode == LOAD_CONST ||
- b->b_instr[i].i_opcode == KW_NAMES) {
-
+ if (HAS_CONST(b->b_instr[i].i_opcode)) {
int index = b->b_instr[i].i_oparg;
index_map[index] = index;
}
@@ -9780,9 +9785,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
- if (b->b_instr[i].i_opcode == LOAD_CONST ||
- b->b_instr[i].i_opcode == KW_NAMES) {
-
+ if (HAS_CONST(b->b_instr[i].i_opcode)) {
int index = b->b_instr[i].i_oparg;
assert(reverse_index_map[index] >= 0);
assert(reverse_index_map[index] < n_used_consts);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index ab19f43..de98b1a 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -742,6 +742,23 @@
goto resume_frame;
}
+ TARGET(RETURN_CONST) {
+ PyObject *retval = GETITEM(consts, oparg);
+ Py_INCREF(retval);
+ assert(EMPTY());
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ TRACE_FUNCTION_EXIT();
+ DTRACE_FUNCTION_EXIT();
+ _Py_LeaveRecursiveCallPy(tstate);
+ assert(frame != &entry_frame);
+ // GH-99729: We need to unlink the frame *before* clearing it:
+ _PyInterpreterFrame *dying = frame;
+ frame = cframe.current_frame = dying->previous;
+ _PyEvalFrameClearAndPop(tstate, dying);
+ _PyFrame_StackPush(frame, retval);
+ goto resume_frame;
+ }
+
TARGET(GET_AITER) {
PyObject *obj = PEEK(1);
PyObject *iter;
diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h
index d258535..bae5492 100644
--- a/Python/opcode_metadata.h
+++ b/Python/opcode_metadata.h
@@ -92,6 +92,8 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 1;
case RETURN_VALUE:
return 1;
+ case RETURN_CONST:
+ return 0;
case GET_AITER:
return 1;
case GET_ANEXT:
@@ -438,6 +440,8 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 0;
case RETURN_VALUE:
return 0;
+ case RETURN_CONST:
+ return 0;
case GET_AITER:
return 1;
case GET_ANEXT:
@@ -745,6 +749,7 @@ struct opcode_metadata {
[RAISE_VARARGS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[INTERPRETER_EXIT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
[RETURN_VALUE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
+ [RETURN_CONST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[GET_AITER] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
[GET_ANEXT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
[GET_AWAITABLE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index f1c3f3e..eceb246 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -120,7 +120,7 @@ static void *opcode_targets[256] = {
&&TARGET_CONTAINS_OP,
&&TARGET_RERAISE,
&&TARGET_COPY,
- &&TARGET_STORE_FAST__LOAD_FAST,
+ &&TARGET_RETURN_CONST,
&&TARGET_BINARY_OP,
&&TARGET_SEND,
&&TARGET_LOAD_FAST,
@@ -142,7 +142,7 @@ static void *opcode_targets[256] = {
&&TARGET_JUMP_BACKWARD,
&&TARGET_COMPARE_AND_BRANCH,
&&TARGET_CALL_FUNCTION_EX,
- &&TARGET_STORE_FAST__STORE_FAST,
+ &&TARGET_STORE_FAST__LOAD_FAST,
&&TARGET_EXTENDED_ARG,
&&TARGET_LIST_APPEND,
&&TARGET_SET_ADD,
@@ -152,15 +152,15 @@ static void *opcode_targets[256] = {
&&TARGET_YIELD_VALUE,
&&TARGET_RESUME,
&&TARGET_MATCH_CLASS,
+ &&TARGET_STORE_FAST__STORE_FAST,
&&TARGET_STORE_SUBSCR_DICT,
- &&TARGET_STORE_SUBSCR_LIST_INT,
&&TARGET_FORMAT_VALUE,
&&TARGET_BUILD_CONST_KEY_MAP,
&&TARGET_BUILD_STRING,
+ &&TARGET_STORE_SUBSCR_LIST_INT,
&&TARGET_UNPACK_SEQUENCE_LIST,
&&TARGET_UNPACK_SEQUENCE_TUPLE,
&&TARGET_UNPACK_SEQUENCE_TWO_TUPLE,
- &&_unknown_opcode,
&&TARGET_LIST_EXTEND,
&&TARGET_SET_UPDATE,
&&TARGET_DICT_MERGE,