Skip to content

Commit b432958

Browse files
committed
gh-101799: implement PREP_RERAISE_STAR as an intrinsic function
1 parent e1aaded commit b432958

File tree

14 files changed

+108
-87
lines changed

14 files changed

+108
-87
lines changed

Doc/library/dis.rst

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,12 +1512,17 @@ iterations of the loop.
15121512
they use their arg.
15131513

15141514

1515-
.. opcode:: CALL_INTRINSIC_1
1515+
.. opcode:: CALL_INTRINSIC
15161516

1517-
Calls an intrinsic function with one argument. Passes ``STACK[-1]`` as the
1518-
argument and sets ``STACK[-1]`` to the result. Used to implement functionality that is necessary but not performance critical.
1517+
Calls an intrinsic function with one or two arguments, depending on the oparg.
1518+
If the oparg corresponds to a unary function, it is called with arg ``STACK[-1]``.
1519+
If the oparg corresponds to a binary function, it is called with args
1520+
``STACK[-2]``, ``STACK[-1]``. In both cases the arg(s) are popped and the
1521+
result of the function is pushed to the stack.
15191522

1520-
The operand determines which intrinsic function is called:
1523+
Used to implement functionality that is necessary but not performance critical.
1524+
1525+
The operand determines which intrinsic function is called:
15211526

15221527
* ``0`` Not valid
15231528
* ``1`` Prints the argument to standard out. Used in the REPL.
@@ -1527,6 +1532,8 @@ iterations of the loop.
15271532
* ``5`` Performs the unary ``+`` operation
15281533
* ``6`` Converts a list to a tuple
15291534

1535+
* ``100`` Calculates the ExceptionGroup to raise from a ``try-except*``.
1536+
15301537
.. versionadded:: 3.12
15311538

15321539

Include/internal/pycore_intrinsics.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
/* Unary Functions: */
3+
24
#define INTRINSIC_PRINT 1
35
#define INTRINSIC_IMPORT_STAR 2
46
#define INTRINSIC_STOPITERATION_ERROR 3
@@ -8,6 +10,18 @@
810

911
#define MAX_INTRINSIC_1 6
1012

13+
14+
/* Binary Functions: */
15+
16+
#define MIN_INTRINSIC_2 100
17+
#define INTRINSIC_PREP_RERAISE_STAR 100
18+
19+
#define MAX_INTRINSIC_2 100
20+
21+
1122
typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
23+
typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);
1224

1325
extern instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
26+
extern instrinsic_func2 _PyIntrinsics_BinaryFunctions[];
27+

Include/internal/pycore_opcode.h

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/opcode.h

Lines changed: 9 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/importlib/_bootstrap_external.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ def _write_atomic(path, data, mode=0o666):
432432
# Python 3.12a5 3516 (Add COMPARE_AND_BRANCH instruction)
433433
# Python 3.12a5 3517 (Change YIELD_VALUE oparg to exception block depth)
434434
# Python 3.12a5 3518 (Add RETURN_CONST instruction)
435+
# Python 3.12a5 3519 (Remove PREP_RERAISE_STAR, rename CALL_INTRINSIC1 to CALL_INTRINSIC)
435436

436437
# Python 3.13 will start with 3550
437438

@@ -444,7 +445,7 @@ def _write_atomic(path, data, mode=0o666):
444445
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
445446
# in PC/launcher.c must also be updated.
446447

447-
MAGIC_NUMBER = (3518).to_bytes(2, 'little') + b'\r\n'
448+
MAGIC_NUMBER = (3519).to_bytes(2, 'little') + b'\r\n'
448449

449450
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
450451

Lib/opcode.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ def pseudo_op(name, op, real_ops):
127127

128128
def_op('SETUP_ANNOTATIONS', 85)
129129

130-
def_op('PREP_RERAISE_STAR', 88)
131130
def_op('POP_EXCEPT', 89)
132131

133132
HAVE_ARGUMENT = 90 # real opcodes from here have an argument:
@@ -223,7 +222,7 @@ def pseudo_op(name, op, real_ops):
223222
def_op('CALL', 171)
224223
def_op('KW_NAMES', 172)
225224
hasconst.append(172)
226-
def_op('CALL_INTRINSIC_1', 173)
225+
def_op('CALL_INTRINSIC', 173)
227226

228227
hasarg.extend([op for op in opmap.values() if op >= HAVE_ARGUMENT])
229228

Lib/test/test_dis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ async def _asyncwith(c):
526526
>> COPY 3
527527
POP_EXCEPT
528528
RERAISE 1
529-
>> CALL_INTRINSIC_1 3
529+
>> CALL_INTRINSIC 3
530530
RERAISE 1
531531
ExceptionTable:
532532
12 rows

Lib/test/test_lltrace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def dont_trace_2():
5454
""")
5555
self.assertIn("GET_ITER", stdout)
5656
self.assertIn("FOR_ITER", stdout)
57-
self.assertIn("CALL_INTRINSIC_1", stdout)
57+
self.assertIn("CALL_INTRINSIC", stdout)
5858
self.assertIn("POP_TOP", stdout)
5959
self.assertNotIn("BINARY_OP", stdout)
6060
self.assertNotIn("UNARY_NEGATIVE", stdout)

Python/bytecodes.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,15 @@ dummy_func(
498498
ERROR_IF(err, error);
499499
}
500500

501-
inst(CALL_INTRINSIC_1, (value -- res)) {
502-
assert(oparg <= MAX_INTRINSIC_1);
503-
res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value);
504-
Py_DECREF(value);
501+
inst(CALL_INTRINSIC, (value2 if (oparg >= MIN_INTRINSIC_2), value1 -- res)) {
502+
if (oparg <= MAX_INTRINSIC_1) {
503+
res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value1);
504+
}
505+
else {
506+
assert(oparg >= MIN_INTRINSIC_2 && oparg <= MAX_INTRINSIC_2);
507+
res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1);
508+
}
509+
DECREF_INPUTS();
505510
ERROR_IF(res == NULL, error);
506511
}
507512

@@ -773,15 +778,6 @@ dummy_func(
773778
goto exception_unwind;
774779
}
775780

776-
inst(PREP_RERAISE_STAR, (orig, excs -- val)) {
777-
assert(PyList_Check(excs));
778-
779-
val = _PyExc_PrepReraiseStar(orig, excs);
780-
DECREF_INPUTS();
781-
782-
ERROR_IF(val == NULL, error);
783-
}
784-
785781
inst(END_ASYNC_FOR, (awaitable, exc -- )) {
786782
assert(exc && PyExceptionInstance_Check(exc));
787783
if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) {
@@ -2367,7 +2363,7 @@ dummy_func(
23672363
}
23682364

23692365
// Cache layout: counter/1, func_version/2, min_args/1
2370-
// Neither CALL_INTRINSIC_1 nor CALL_FUNCTION_EX are members!
2366+
// Neither CALL_INTRINSIC nor CALL_FUNCTION_EX are members!
23712367
family(call, INLINE_CACHE_ENTRIES_CALL) = {
23722368
CALL,
23732369
CALL_BOUND_METHOD_EXACT_ARGS,

Python/compile.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,7 +2413,7 @@ wrap_in_stopiteration_handler(struct compiler *c)
24132413
ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
24142414
ADDOP(c, NO_LOCATION, RETURN_VALUE);
24152415
USE_LABEL(c, handler);
2416-
ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR);
2416+
ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC, INTRINSIC_STOPITERATION_ERROR);
24172417
ADDOP_I(c, NO_LOCATION, RERAISE, 1);
24182418
return SUCCESS;
24192419
}
@@ -3429,7 +3429,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
34293429
34303430
[orig, res, rest] Ln+1: LIST_APPEND 1 ) add unhandled exc to res (could be None)
34313431
3432-
[orig, res] PREP_RERAISE_STAR
3432+
[orig, res] CALL_INTRINSIC PREP_RERAISE_STAR
34333433
[exc] COPY 1
34343434
[exc, exc] POP_JUMP_IF_NOT_NONE RER
34353435
[exc] POP_TOP
@@ -3578,7 +3578,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
35783578
NEW_JUMP_TARGET_LABEL(c, reraise);
35793579

35803580
USE_LABEL(c, reraise_star);
3581-
ADDOP(c, NO_LOCATION, PREP_RERAISE_STAR);
3581+
ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC, INTRINSIC_PREP_RERAISE_STAR);
35823582
ADDOP_I(c, NO_LOCATION, COPY, 1);
35833583
ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_NOT_NONE, reraise);
35843584

@@ -3752,7 +3752,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
37523752

37533753
if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
37543754
assert(n == 1);
3755-
ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR);
3755+
ADDOP_I(c, LOC(s), CALL_INTRINSIC, INTRINSIC_IMPORT_STAR);
37563756
ADDOP(c, NO_LOCATION, POP_TOP);
37573757
return SUCCESS;
37583758
}
@@ -3805,7 +3805,7 @@ compiler_stmt_expr(struct compiler *c, location loc, expr_ty value)
38053805
{
38063806
if (c->c_interactive && c->c_nestlevel <= 1) {
38073807
VISIT(c, expr, value);
3808-
ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT);
3808+
ADDOP_I(c, loc, CALL_INTRINSIC, INTRINSIC_PRINT);
38093809
ADDOP(c, NO_LOCATION, POP_TOP);
38103810
return SUCCESS;
38113811
}
@@ -3992,7 +3992,7 @@ addop_binary(struct compiler *c, location loc, operator_ty binop,
39923992
static int
39933993
addop_yield(struct compiler *c, location loc) {
39943994
if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) {
3995-
ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
3995+
ADDOP_I(c, loc, CALL_INTRINSIC, INTRINSIC_ASYNC_GEN_WRAP);
39963996
}
39973997
ADDOP_I(c, loc, YIELD_VALUE, 0);
39983998
ADDOP_I(c, loc, RESUME, 1);
@@ -4159,7 +4159,7 @@ starunpack_helper(struct compiler *c, location loc,
41594159
ADDOP_LOAD_CONST_NEW(c, loc, folded);
41604160
ADDOP_I(c, loc, extend, 1);
41614161
if (tuple) {
4162-
ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
4162+
ADDOP_I(c, loc, CALL_INTRINSIC, INTRINSIC_LIST_TO_TUPLE);
41634163
}
41644164
}
41654165
return SUCCESS;
@@ -4210,7 +4210,7 @@ starunpack_helper(struct compiler *c, location loc,
42104210
}
42114211
assert(sequence_built);
42124212
if (tuple) {
4213-
ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
4213+
ADDOP_I(c, loc, CALL_INTRINSIC, INTRINSIC_LIST_TO_TUPLE);
42144214
}
42154215
return SUCCESS;
42164216
}
@@ -5582,7 +5582,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
55825582
case UnaryOp_kind:
55835583
VISIT(c, expr, e->v.UnaryOp.operand);
55845584
if (e->v.UnaryOp.op == UAdd) {
5585-
ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE);
5585+
ADDOP_I(c, loc, CALL_INTRINSIC, INTRINSIC_UNARY_POSITIVE);
55865586
}
55875587
else {
55885588
ADDOP(c, loc, unaryop(e->v.UnaryOp.op));

0 commit comments

Comments
 (0)