Skip to content

Commit

Permalink
pythongh-98831: rewrite PUSH_EXC_INFO and conditional jumps in the in…
Browse files Browse the repository at this point in the history
…struction definition DSL (python#101481)
  • Loading branch information
iritkatriel authored Feb 1, 2023
1 parent 7840ff3 commit b91b42d
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 99 deletions.
71 changes: 28 additions & 43 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1898,9 +1898,7 @@ dummy_func(
CHECK_EVAL_BREAKER();
}

// stack effect: (__0 -- )
inst(POP_JUMP_IF_FALSE) {
PyObject *cond = POP();
inst(POP_JUMP_IF_FALSE, (cond -- )) {
if (Py_IsTrue(cond)) {
_Py_DECREF_NO_DEALLOC(cond);
}
Expand All @@ -1911,19 +1909,16 @@ dummy_func(
else {
int err = PyObject_IsTrue(cond);
Py_DECREF(cond);
if (err > 0)
;
else if (err == 0) {
if (err == 0) {
JUMPBY(oparg);
}
else
goto error;
else {
ERROR_IF(err < 0, error);
}
}
}

// stack effect: (__0 -- )
inst(POP_JUMP_IF_TRUE) {
PyObject *cond = POP();
inst(POP_JUMP_IF_TRUE, (cond -- )) {
if (Py_IsFalse(cond)) {
_Py_DECREF_NO_DEALLOC(cond);
}
Expand All @@ -1937,25 +1932,23 @@ dummy_func(
if (err > 0) {
JUMPBY(oparg);
}
else if (err == 0)
;
else
goto error;
else {
ERROR_IF(err < 0, error);
}
}
}

// stack effect: (__0 -- )
inst(POP_JUMP_IF_NOT_NONE) {
PyObject *value = POP();
inst(POP_JUMP_IF_NOT_NONE, (value -- )) {
if (!Py_IsNone(value)) {
Py_DECREF(value);
JUMPBY(oparg);
}
Py_DECREF(value);
else {
_Py_DECREF_NO_DEALLOC(value);
}
}

// stack effect: (__0 -- )
inst(POP_JUMP_IF_NONE) {
PyObject *value = POP();
inst(POP_JUMP_IF_NONE, (value -- )) {
if (Py_IsNone(value)) {
_Py_DECREF_NO_DEALLOC(value);
JUMPBY(oparg);
Expand All @@ -1965,50 +1958,48 @@ dummy_func(
}
}

// error: JUMP_IF_FALSE_OR_POP stack effect depends on jump flag
inst(JUMP_IF_FALSE_OR_POP) {
PyObject *cond = TOP();
inst(JUMP_IF_FALSE_OR_POP, (cond -- cond if (jump))) {
bool jump = false;
int err;
if (Py_IsTrue(cond)) {
STACK_SHRINK(1);
_Py_DECREF_NO_DEALLOC(cond);
}
else if (Py_IsFalse(cond)) {
JUMPBY(oparg);
jump = true;
}
else {
err = PyObject_IsTrue(cond);
if (err > 0) {
STACK_SHRINK(1);
Py_DECREF(cond);
}
else if (err == 0) {
JUMPBY(oparg);
jump = true;
}
else {
goto error;
}
}
}

// error: JUMP_IF_TRUE_OR_POP stack effect depends on jump flag
inst(JUMP_IF_TRUE_OR_POP) {
PyObject *cond = TOP();
inst(JUMP_IF_TRUE_OR_POP, (cond -- cond if (jump))) {
bool jump = false;
int err;
if (Py_IsFalse(cond)) {
STACK_SHRINK(1);
_Py_DECREF_NO_DEALLOC(cond);
}
else if (Py_IsTrue(cond)) {
JUMPBY(oparg);
jump = true;
}
else {
err = PyObject_IsTrue(cond);
if (err > 0) {
JUMPBY(oparg);
jump = true;
}
else if (err == 0) {
STACK_SHRINK(1);
Py_DECREF(cond);
}
else {
Expand Down Expand Up @@ -2321,22 +2312,16 @@ dummy_func(
ERROR_IF(res == NULL, error);
}

// stack effect: ( -- __0)
inst(PUSH_EXC_INFO) {
PyObject *value = TOP();

inst(PUSH_EXC_INFO, (new_exc -- prev_exc, new_exc)) {
_PyErr_StackItem *exc_info = tstate->exc_info;
if (exc_info->exc_value != NULL) {
SET_TOP(exc_info->exc_value);
prev_exc = exc_info->exc_value;
}
else {
SET_TOP(Py_NewRef(Py_None));
prev_exc = Py_NewRef(Py_None);
}

PUSH(Py_NewRef(value));
assert(PyExceptionInstance_Check(value));
exc_info->exc_value = value;

assert(PyExceptionInstance_Check(new_exc));
exc_info->exc_value = Py_NewRef(new_exc);
}

inst(LOAD_ATTR_METHOD_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, self -- res2 if (oparg & 1), res)) {
Expand Down
24 changes: 13 additions & 11 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -8630,17 +8630,19 @@ opcode_metadata_is_sane(cfg_builder *g) {
int opcode = instr->i_opcode;
int oparg = instr->i_oparg;
assert(opcode <= MAX_REAL_OPCODE);
int popped = _PyOpcode_num_popped(opcode, oparg);
int pushed = _PyOpcode_num_pushed(opcode, oparg);
assert((pushed < 0) == (popped < 0));
if (pushed >= 0) {
assert(_PyOpcode_opcode_metadata[opcode].valid_entry);
int effect = stack_effect(opcode, instr->i_oparg, -1);
if (effect != pushed - popped) {
fprintf(stderr,
"op=%d: stack_effect (%d) != pushed (%d) - popped (%d)\n",
opcode, effect, pushed, popped);
result = false;
for (int jump = 0; jump <= 1; jump++) {
int popped = _PyOpcode_num_popped(opcode, oparg, jump ? true : false);
int pushed = _PyOpcode_num_pushed(opcode, oparg, jump ? true : false);
assert((pushed < 0) == (popped < 0));
if (pushed >= 0) {
assert(_PyOpcode_opcode_metadata[opcode].valid_entry);
int effect = stack_effect(opcode, instr->i_oparg, jump);
if (effect != pushed - popped) {
fprintf(stderr,
"op=%d arg=%d jump=%d: stack_effect (%d) != pushed (%d) - popped (%d)\n",
opcode, oparg, jump, effect, pushed, popped);
result = false;
}
}
}
}
Expand Down
68 changes: 40 additions & 28 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b91b42d

Please sign in to comment.