Skip to content

bpo-47186: Replace JUMP_IF_NOT_EG_MATCH by CHECK_EG_MATCH + jump #32309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 22 additions & 23 deletions Doc/library/dis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,28 @@ iterations of the loop.

.. versionadded:: 3.11

.. opcode:: CHECK_EG_MATCH

Performs exception matching for ``except*``. Applies ``split(TOS)`` on
the exception group representing TOS1.

In case of a match, pops two items from the stack and pushes the
non-matching subgroup (``None`` in case of full match) followed by the
matching subgroup. When there is no match, pops one item (the match
type) and pushes ``None``.

.. versionadded:: 3.11

.. opcode:: PREP_RERAISE_STAR

Combines the raised and reraised exceptions list from TOS, into an exception
group to propagate from a try-except* block. Uses the original exception
group from TOS1 to reconstruct the structure of reraised exceptions. Pops
two items from the stack and pushes the exception to reraise or ``None``
if there isn't one.

.. versionadded:: 3.11

.. opcode:: WITH_EXCEPT_START

Calls the function in position 4 on the stack with arguments (type, val, tb)
Expand Down Expand Up @@ -922,18 +944,6 @@ iterations of the loop.
.. versionadded:: 3.1


.. opcode:: JUMP_IF_NOT_EG_MATCH (target)

Performs exception matching for ``except*``. Applies ``split(TOS)`` on
the exception group representing TOS1. Jumps if no match is found.

Pops one item from the stack (the match type). If a match was found,
next item (the exception) and pushes the non-matching part of the
exception group followed by the matching part.

.. versionadded:: 3.11


.. opcode:: POP_JUMP_IF_NOT_NONE (target)

If TOS is not none, sets the bytecode counter to *target*. TOS is popped.
Expand All @@ -948,17 +958,6 @@ iterations of the loop.
.. versionadded:: 3.11


.. opcode:: PREP_RERAISE_STAR

Combines the raised and reraised exceptions list from TOS, into an exception
group to propagate from a try-except* block. Uses the original exception
group from TOS1 to reconstruct the structure of reraised exceptions. Pops
two items from the stack and pushes the exception to reraise or ``None``
if there isn't one.

.. versionadded:: 3.11


.. opcode:: JUMP_IF_TRUE_OR_POP (target)

If TOS is true, sets the bytecode counter to *target* and leaves TOS on the
Expand Down
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,9 @@ CPython bytecode changes
* Replaced :opcode:`JUMP_IF_NOT_EXC_MATCH` by :opcode:`CHECK_EXC_MATCH` which
performs the check but does not jump.

* Replaced :opcode:`JUMP_IF_NOT_EG_MATCH` by :opcode:`CHECK_EG_MATCH` which
performs the check but does not jump.

* Replaced :opcode:`JUMP_ABSOLUTE` by the relative :opcode:`JUMP_BACKWARD`.

Deprecated
Expand Down
72 changes: 36 additions & 36 deletions Include/opcode.h

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

3 changes: 2 additions & 1 deletion Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ def _write_atomic(path, data, mode=0o666):
# Python 3.11a6 3488 (LOAD_GLOBAL can push additional NULL)
# Python 3.11a6 3489 (Add JUMP_BACKWARD, remove JUMP_ABSOLUTE)
# Python 3.11a6 3490 (remove JUMP_IF_NOT_EXC_MATCH, add CHECK_EXC_MATCH)
# Python 3.11a6 3491 (remove JUMP_IF_NOT_EG_MATCH, add CHECK_EG_MATCH)

# Python 3.12 will start with magic number 3500

Expand All @@ -412,7 +413,7 @@ def _write_atomic(path, data, mode=0o666):
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.

MAGIC_NUMBER = (3490).to_bytes(2, 'little') + b'\r\n'
MAGIC_NUMBER = (3491).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c

_PYCACHE = '__pycache__'
Expand Down
2 changes: 1 addition & 1 deletion Lib/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def jabs_op(name, op, entries=0):

def_op('PUSH_EXC_INFO', 35)
def_op('CHECK_EXC_MATCH', 36)
def_op('CHECK_EG_MATCH', 37)

def_op('WITH_EXCEPT_START', 49)
def_op('GET_AITER', 50)
Expand Down Expand Up @@ -147,7 +148,6 @@ def jabs_op(name, op, entries=0):
haslocal.append(125)
def_op('DELETE_FAST', 126) # Local variable number
haslocal.append(126)
jabs_op('JUMP_IF_NOT_EG_MATCH', 127)
jabs_op('POP_JUMP_IF_NOT_NONE', 128)
jabs_op('POP_JUMP_IF_NONE', 129)
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Replace :opcode:`JUMP_IF_NOT_EG_MATCH` by :opcode:`CHECK_EG_MATCH` + jump.
10 changes: 2 additions & 8 deletions Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,21 +207,15 @@ mark_stacks(PyCodeObject *code_obj, int len)
case JUMP_IF_TRUE_OR_POP:
case POP_JUMP_IF_FALSE:
case POP_JUMP_IF_TRUE:
case JUMP_IF_NOT_EG_MATCH:
{
int64_t target_stack;
int j = get_arg(code, i);
assert(j < len);
if (stacks[j] == UNINITIALIZED && j < i) {
todo = 1;
}
if (opcode == JUMP_IF_NOT_EG_MATCH)
{
next_stack = pop_value(pop_value(next_stack));
target_stack = next_stack;
}
else if (opcode == JUMP_IF_FALSE_OR_POP ||
opcode == JUMP_IF_TRUE_OR_POP)
if (opcode == JUMP_IF_FALSE_OR_POP ||
opcode == JUMP_IF_TRUE_OR_POP)
{
target_stack = next_stack;
next_stack = pop_value(next_stack);
Expand Down
16 changes: 3 additions & 13 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -3804,7 +3804,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
DISPATCH();
}

TARGET(JUMP_IF_NOT_EG_MATCH) {
TARGET(CHECK_EG_MATCH) {
PyObject *match_type = POP();
if (check_except_star_type_valid(tstate, match_type) < 0) {
Py_DECREF(match_type);
Expand All @@ -3825,33 +3825,23 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
assert(rest == NULL);
goto error;
}

if (Py_IsNone(match)) {
Py_DECREF(match);
PUSH(match);
Py_XDECREF(rest);
/* no match - jump to target */
JUMPTO(oparg);
}
else {

/* Total or partial match - update the stack from
* [val]
* to
* [rest, match]
* (rest can be Py_None)
*/

PyObject *exc = TOP();

SET_TOP(rest);
PUSH(match);

PyErr_SetExcInfo(NULL, Py_NewRef(match), NULL);

Py_DECREF(exc);

Py_DECREF(exc_value);
}

DISPATCH();
}

Expand Down
28 changes: 21 additions & 7 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1000,8 +1000,8 @@ stack_effect(int opcode, int oparg, int jump)
return -1;
case CHECK_EXC_MATCH:
return 0;
case JUMP_IF_NOT_EG_MATCH:
return jump > 0 ? -1 : 0;
case CHECK_EG_MATCH:
return 0;
case IMPORT_NAME:
return -1;
case IMPORT_FROM:
Expand Down Expand Up @@ -3533,14 +3533,18 @@ compiler_try_except(struct compiler *c, stmt_ty s)
[] POP_BLOCK
[] JUMP L0

[exc] L1: COPY 1 ) save copy of the original exception
[exc] L1: COPY 1 ) save copy of the original exception
[orig, exc] BUILD_LIST ) list for raised/reraised excs ("result")
[orig, exc, res] SWAP 2

[orig, res, exc] <evaluate E1>
[orig, res, exc, E1] JUMP_IF_NOT_EG_MATCH L2
[orig, res, exc, E1] CHECK_EG_MATCH
[orig, red, rest/exc, match?] COPY 1
[orig, red, rest/exc, match?, match?] POP_JUMP_IF_NOT_NONE H1
[orig, red, exc, None] POP_TOP
[orig, red, exc] JUMP L2

[orig, res, rest, match] <assign to V1> (or POP if no V1)
[orig, res, rest, match] H1: <assign to V1> (or POP if no V1)

[orig, res, rest] SETUP_FINALLY R1
[orig, res, rest] <code for S1>
Expand Down Expand Up @@ -3622,6 +3626,10 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
if (except == NULL) {
return 0;
}
basicblock *handle_match = compiler_new_block(c);
if (handle_match == NULL) {
return 0;
}
if (i == 0) {
/* Push the original EG into the stack */
/*
Expand All @@ -3641,9 +3649,15 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
}
if (handler->v.ExceptHandler.type) {
VISIT(c, expr, handler->v.ExceptHandler.type);
ADDOP_JUMP(c, JUMP_IF_NOT_EG_MATCH, except);
ADDOP(c, CHECK_EG_MATCH);
ADDOP_I(c, COPY, 1);
ADDOP_JUMP(c, POP_JUMP_IF_NOT_NONE, handle_match);
ADDOP(c, POP_TOP); // match
ADDOP_JUMP(c, JUMP, except);
}

compiler_use_next_block(c, handle_match);

basicblock *cleanup_end = compiler_new_block(c);
if (cleanup_end == NULL) {
return 0;
Expand All @@ -3657,7 +3671,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
compiler_nameop(c, handler->v.ExceptHandler.name, Store);
}
else {
ADDOP(c, POP_TOP); // exc
ADDOP(c, POP_TOP); // match
}

/*
Expand Down
Loading