Skip to content

Commit b91b42d

Browse files
authored
gh-98831: rewrite PUSH_EXC_INFO and conditional jumps in the instruction definition DSL (#101481)
1 parent 7840ff3 commit b91b42d

File tree

5 files changed

+98
-99
lines changed

5 files changed

+98
-99
lines changed

Python/bytecodes.c

+28-43
Original file line numberDiff line numberDiff line change
@@ -1898,9 +1898,7 @@ dummy_func(
18981898
CHECK_EVAL_BREAKER();
18991899
}
19001900

1901-
// stack effect: (__0 -- )
1902-
inst(POP_JUMP_IF_FALSE) {
1903-
PyObject *cond = POP();
1901+
inst(POP_JUMP_IF_FALSE, (cond -- )) {
19041902
if (Py_IsTrue(cond)) {
19051903
_Py_DECREF_NO_DEALLOC(cond);
19061904
}
@@ -1911,19 +1909,16 @@ dummy_func(
19111909
else {
19121910
int err = PyObject_IsTrue(cond);
19131911
Py_DECREF(cond);
1914-
if (err > 0)
1915-
;
1916-
else if (err == 0) {
1912+
if (err == 0) {
19171913
JUMPBY(oparg);
19181914
}
1919-
else
1920-
goto error;
1915+
else {
1916+
ERROR_IF(err < 0, error);
1917+
}
19211918
}
19221919
}
19231920

1924-
// stack effect: (__0 -- )
1925-
inst(POP_JUMP_IF_TRUE) {
1926-
PyObject *cond = POP();
1921+
inst(POP_JUMP_IF_TRUE, (cond -- )) {
19271922
if (Py_IsFalse(cond)) {
19281923
_Py_DECREF_NO_DEALLOC(cond);
19291924
}
@@ -1937,25 +1932,23 @@ dummy_func(
19371932
if (err > 0) {
19381933
JUMPBY(oparg);
19391934
}
1940-
else if (err == 0)
1941-
;
1942-
else
1943-
goto error;
1935+
else {
1936+
ERROR_IF(err < 0, error);
1937+
}
19441938
}
19451939
}
19461940

1947-
// stack effect: (__0 -- )
1948-
inst(POP_JUMP_IF_NOT_NONE) {
1949-
PyObject *value = POP();
1941+
inst(POP_JUMP_IF_NOT_NONE, (value -- )) {
19501942
if (!Py_IsNone(value)) {
1943+
Py_DECREF(value);
19511944
JUMPBY(oparg);
19521945
}
1953-
Py_DECREF(value);
1946+
else {
1947+
_Py_DECREF_NO_DEALLOC(value);
1948+
}
19541949
}
19551950

1956-
// stack effect: (__0 -- )
1957-
inst(POP_JUMP_IF_NONE) {
1958-
PyObject *value = POP();
1951+
inst(POP_JUMP_IF_NONE, (value -- )) {
19591952
if (Py_IsNone(value)) {
19601953
_Py_DECREF_NO_DEALLOC(value);
19611954
JUMPBY(oparg);
@@ -1965,50 +1958,48 @@ dummy_func(
19651958
}
19661959
}
19671960

1968-
// error: JUMP_IF_FALSE_OR_POP stack effect depends on jump flag
1969-
inst(JUMP_IF_FALSE_OR_POP) {
1970-
PyObject *cond = TOP();
1961+
inst(JUMP_IF_FALSE_OR_POP, (cond -- cond if (jump))) {
1962+
bool jump = false;
19711963
int err;
19721964
if (Py_IsTrue(cond)) {
1973-
STACK_SHRINK(1);
19741965
_Py_DECREF_NO_DEALLOC(cond);
19751966
}
19761967
else if (Py_IsFalse(cond)) {
19771968
JUMPBY(oparg);
1969+
jump = true;
19781970
}
19791971
else {
19801972
err = PyObject_IsTrue(cond);
19811973
if (err > 0) {
1982-
STACK_SHRINK(1);
19831974
Py_DECREF(cond);
19841975
}
19851976
else if (err == 0) {
19861977
JUMPBY(oparg);
1978+
jump = true;
19871979
}
19881980
else {
19891981
goto error;
19901982
}
19911983
}
19921984
}
19931985

1994-
// error: JUMP_IF_TRUE_OR_POP stack effect depends on jump flag
1995-
inst(JUMP_IF_TRUE_OR_POP) {
1996-
PyObject *cond = TOP();
1986+
inst(JUMP_IF_TRUE_OR_POP, (cond -- cond if (jump))) {
1987+
bool jump = false;
19971988
int err;
19981989
if (Py_IsFalse(cond)) {
1999-
STACK_SHRINK(1);
20001990
_Py_DECREF_NO_DEALLOC(cond);
20011991
}
20021992
else if (Py_IsTrue(cond)) {
20031993
JUMPBY(oparg);
1994+
jump = true;
20041995
}
20051996
else {
20061997
err = PyObject_IsTrue(cond);
20071998
if (err > 0) {
20081999
JUMPBY(oparg);
2000+
jump = true;
20092001
}
20102002
else if (err == 0) {
2011-
STACK_SHRINK(1);
20122003
Py_DECREF(cond);
20132004
}
20142005
else {
@@ -2321,22 +2312,16 @@ dummy_func(
23212312
ERROR_IF(res == NULL, error);
23222313
}
23232314

2324-
// stack effect: ( -- __0)
2325-
inst(PUSH_EXC_INFO) {
2326-
PyObject *value = TOP();
2327-
2315+
inst(PUSH_EXC_INFO, (new_exc -- prev_exc, new_exc)) {
23282316
_PyErr_StackItem *exc_info = tstate->exc_info;
23292317
if (exc_info->exc_value != NULL) {
2330-
SET_TOP(exc_info->exc_value);
2318+
prev_exc = exc_info->exc_value;
23312319
}
23322320
else {
2333-
SET_TOP(Py_NewRef(Py_None));
2321+
prev_exc = Py_NewRef(Py_None);
23342322
}
2335-
2336-
PUSH(Py_NewRef(value));
2337-
assert(PyExceptionInstance_Check(value));
2338-
exc_info->exc_value = value;
2339-
2323+
assert(PyExceptionInstance_Check(new_exc));
2324+
exc_info->exc_value = Py_NewRef(new_exc);
23402325
}
23412326

23422327
inst(LOAD_ATTR_METHOD_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, self -- res2 if (oparg & 1), res)) {

Python/compile.c

+13-11
Original file line numberDiff line numberDiff line change
@@ -8630,17 +8630,19 @@ opcode_metadata_is_sane(cfg_builder *g) {
86308630
int opcode = instr->i_opcode;
86318631
int oparg = instr->i_oparg;
86328632
assert(opcode <= MAX_REAL_OPCODE);
8633-
int popped = _PyOpcode_num_popped(opcode, oparg);
8634-
int pushed = _PyOpcode_num_pushed(opcode, oparg);
8635-
assert((pushed < 0) == (popped < 0));
8636-
if (pushed >= 0) {
8637-
assert(_PyOpcode_opcode_metadata[opcode].valid_entry);
8638-
int effect = stack_effect(opcode, instr->i_oparg, -1);
8639-
if (effect != pushed - popped) {
8640-
fprintf(stderr,
8641-
"op=%d: stack_effect (%d) != pushed (%d) - popped (%d)\n",
8642-
opcode, effect, pushed, popped);
8643-
result = false;
8633+
for (int jump = 0; jump <= 1; jump++) {
8634+
int popped = _PyOpcode_num_popped(opcode, oparg, jump ? true : false);
8635+
int pushed = _PyOpcode_num_pushed(opcode, oparg, jump ? true : false);
8636+
assert((pushed < 0) == (popped < 0));
8637+
if (pushed >= 0) {
8638+
assert(_PyOpcode_opcode_metadata[opcode].valid_entry);
8639+
int effect = stack_effect(opcode, instr->i_oparg, jump);
8640+
if (effect != pushed - popped) {
8641+
fprintf(stderr,
8642+
"op=%d arg=%d jump=%d: stack_effect (%d) != pushed (%d) - popped (%d)\n",
8643+
opcode, oparg, jump, effect, pushed, popped);
8644+
result = false;
8645+
}
86448646
}
86458647
}
86468648
}

Python/generated_cases.c.h

+40-28
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)