[Python-checkins] GH-99005: Add `CALL_INTRINSIC_1` instruction (GH-100771)

markshannon webhook-mailer at python.org
Thu Jan 5 11:06:26 EST 2023


https://github.com/python/cpython/commit/28187141cc34063ef857976ddbca87ba09a882c2
commit: 28187141cc34063ef857976ddbca87ba09a882c2
branch: main
author: Mark Shannon <mark at hotpy.org>
committer: markshannon <mark at hotpy.org>
date: 2023-01-05T16:05:51Z
summary:

GH-99005: Add `CALL_INTRINSIC_1` instruction (GH-100771)

* Remove PRINT_EXPR instruction

* Remove STOPITERATION_ERROR instruction

* Remove IMPORT_STAR instruction

files:
A Include/internal/pycore_intrinsics.h
A Misc/NEWS.d/next/Core and Builtins/2023-01-05-13-54-00.gh-issue-99005.D7H6j4.rst
A Python/intrinsics.c
M Doc/library/dis.rst
M Include/internal/pycore_opcode.h
M Include/opcode.h
M Lib/importlib/_bootstrap_external.py
M Lib/opcode.py
M Lib/test/test_dis.py
M Makefile.pre.in
M PCbuild/_freeze_module.vcxproj
M PCbuild/_freeze_module.vcxproj.filters
M PCbuild/pythoncore.vcxproj
M PCbuild/pythoncore.vcxproj.filters
M Python/bytecodes.c
M Python/ceval.c
M Python/compile.c
M Python/generated_cases.c.h
M Python/opcode_targets.h

diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index 30bbf95be634..33ef6d7ed495 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -607,15 +607,6 @@ the original TOS1.
    .. versionadded:: 3.12
 
 
-.. opcode:: STOPITERATION_ERROR
-
-   Handles a StopIteration raised in a generator or coroutine.
-   If TOS is an instance of :exc:`StopIteration`, or :exc:`StopAsyncIteration`
-   replace it with a :exc:`RuntimeError`.
-
-   .. versionadded:: 3.12
-
-
 .. opcode:: BEFORE_ASYNC_WITH
 
    Resolves ``__aenter__`` and ``__aexit__`` from the object on top of the
@@ -627,13 +618,6 @@ the original TOS1.
 
 **Miscellaneous opcodes**
 
-.. opcode:: PRINT_EXPR
-
-   Implements the expression statement for the interactive mode.  TOS is removed
-   from the stack and printed.  In non-interactive mode, an expression statement
-   is terminated with :opcode:`POP_TOP`.
-
-
 .. opcode:: SET_ADD (i)
 
    Calls ``set.add(TOS1[-i], TOS)``.  Used to implement set comprehensions.
@@ -682,13 +666,6 @@ iterations of the loop.
    .. versionadded:: 3.6
 
 
-.. opcode:: IMPORT_STAR
-
-   Loads all symbols not starting with ``'_'`` directly from the module TOS to
-   the local namespace. The module is popped after loading all names. This
-   opcode implements ``from module import *``.
-
-
 .. opcode:: POP_EXCEPT
 
    Pops a value from the stack, which is used to restore the exception state.
@@ -1422,6 +1399,22 @@ iterations of the loop.
       they use their arg.
 
 
+.. opcode:: CALL_INTRINSIC_1
+
+   Calls an intrinsic function with one argument. Passes the TOS as the argument
+   and sets TOS to the result. Used to implement functionality that is necessary
+   but not performance critical.
+
+    The operand determines which intrinsic function is called:
+
+    * ``0`` Not valid
+    * ``1`` Prints the argument to standard out. Used in the REPL.
+    * ``2`` Performs ``import *`` for the named module.
+    * ``3`` Extracts the return value from a ``StopIteration`` exception.
+
+   .. versionadded:: 3.12
+
+
 **Pseudo-instructions**
 
 These opcodes do not appear in python bytecode, they are used by the compiler
diff --git a/Include/internal/pycore_intrinsics.h b/Include/internal/pycore_intrinsics.h
new file mode 100644
index 000000000000..92f06c736267
--- /dev/null
+++ b/Include/internal/pycore_intrinsics.h
@@ -0,0 +1,10 @@
+
+#define INTRINSIC_PRINT 1
+#define INTRINSIC_IMPORT_STAR 2
+#define INTRINSIC_STOPITERATION_ERROR 3
+
+#define MAX_INTRINSIC_1 3
+
+typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
+
+extern instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h
index 685ad53c7b16..e952690cba3a 100644
--- a/Include/internal/pycore_opcode.h
+++ b/Include/internal/pycore_opcode.h
@@ -85,6 +85,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [CALL_BUILTIN_CLASS] = CALL,
     [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
     [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
+    [CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
     [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL,
     [CALL_NO_KW_BUILTIN_FAST] = CALL,
     [CALL_NO_KW_BUILTIN_O] = CALL,
@@ -134,7 +135,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER,
     [IMPORT_FROM] = IMPORT_FROM,
     [IMPORT_NAME] = IMPORT_NAME,
-    [IMPORT_STAR] = IMPORT_STAR,
     [INTERPRETER_EXIT] = INTERPRETER_EXIT,
     [IS_OP] = IS_OP,
     [JUMP_BACKWARD] = JUMP_BACKWARD,
@@ -187,7 +187,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
     [POP_TOP] = POP_TOP,
     [PREP_RERAISE_STAR] = PREP_RERAISE_STAR,
-    [PRINT_EXPR] = PRINT_EXPR,
     [PUSH_EXC_INFO] = PUSH_EXC_INFO,
     [PUSH_NULL] = PUSH_NULL,
     [RAISE_VARARGS] = RAISE_VARARGS,
@@ -199,7 +198,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS,
     [SET_ADD] = SET_ADD,
     [SET_UPDATE] = SET_UPDATE,
-    [STOPITERATION_ERROR] = STOPITERATION_ERROR,
     [STORE_ATTR] = STORE_ATTR,
     [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR,
     [STORE_ATTR_SLOT] = STORE_ATTR,
@@ -294,30 +292,30 @@ static const char *const _PyOpcode_OpName[263] = {
     [STORE_SUBSCR] = "STORE_SUBSCR",
     [DELETE_SUBSCR] = "DELETE_SUBSCR",
     [FOR_ITER_TUPLE] = "FOR_ITER_TUPLE",
-    [STOPITERATION_ERROR] = "STOPITERATION_ERROR",
     [FOR_ITER_RANGE] = "FOR_ITER_RANGE",
     [FOR_ITER_GEN] = "FOR_ITER_GEN",
     [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS",
     [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
+    [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
     [GET_ITER] = "GET_ITER",
     [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER",
-    [PRINT_EXPR] = "PRINT_EXPR",
-    [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS",
-    [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
     [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE",
-    [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR",
-    [RETURN_GENERATOR] = "RETURN_GENERATOR",
+    [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS",
     [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY",
     [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT",
+    [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR",
+    [RETURN_GENERATOR] = "RETURN_GENERATOR",
     [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT",
     [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT",
     [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT",
     [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
+    [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST",
+    [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST",
     [LIST_TO_TUPLE] = "LIST_TO_TUPLE",
     [RETURN_VALUE] = "RETURN_VALUE",
-    [IMPORT_STAR] = "IMPORT_STAR",
+    [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST",
     [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS",
-    [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST",
+    [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
     [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP",
     [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR",
     [POP_EXCEPT] = "POP_EXCEPT",
@@ -344,7 +342,7 @@ static const char *const _PyOpcode_OpName[263] = {
     [JUMP_FORWARD] = "JUMP_FORWARD",
     [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP",
     [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP",
-    [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST",
+    [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
     [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
     [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE",
     [LOAD_GLOBAL] = "LOAD_GLOBAL",
@@ -352,7 +350,7 @@ static const char *const _PyOpcode_OpName[263] = {
     [CONTAINS_OP] = "CONTAINS_OP",
     [RERAISE] = "RERAISE",
     [COPY] = "COPY",
-    [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST",
+    [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
     [BINARY_OP] = "BINARY_OP",
     [SEND] = "SEND",
     [LOAD_FAST] = "LOAD_FAST",
@@ -372,9 +370,9 @@ static const char *const _PyOpcode_OpName[263] = {
     [STORE_DEREF] = "STORE_DEREF",
     [DELETE_DEREF] = "DELETE_DEREF",
     [JUMP_BACKWARD] = "JUMP_BACKWARD",
-    [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
+    [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
     [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
-    [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
+    [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT",
     [EXTENDED_ARG] = "EXTENDED_ARG",
     [LIST_APPEND] = "LIST_APPEND",
     [SET_ADD] = "SET_ADD",
@@ -384,27 +382,27 @@ static const char *const _PyOpcode_OpName[263] = {
     [YIELD_VALUE] = "YIELD_VALUE",
     [RESUME] = "RESUME",
     [MATCH_CLASS] = "MATCH_CLASS",
-    [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
-    [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
+    [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST",
+    [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST",
     [FORMAT_VALUE] = "FORMAT_VALUE",
     [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP",
     [BUILD_STRING] = "BUILD_STRING",
-    [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT",
-    [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST",
-    [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST",
     [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
+    [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
+    [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
+    [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
     [LIST_EXTEND] = "LIST_EXTEND",
     [SET_UPDATE] = "SET_UPDATE",
     [DICT_MERGE] = "DICT_MERGE",
     [DICT_UPDATE] = "DICT_UPDATE",
-    [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
-    [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
-    [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
     [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
+    [167] = "<167>",
+    [168] = "<168>",
+    [169] = "<169>",
     [170] = "<170>",
     [CALL] = "CALL",
     [KW_NAMES] = "KW_NAMES",
-    [173] = "<173>",
+    [CALL_INTRINSIC_1] = "CALL_INTRINSIC_1",
     [174] = "<174>",
     [175] = "<175>",
     [176] = "<176>",
@@ -498,8 +496,10 @@ static const char *const _PyOpcode_OpName[263] = {
 #endif
 
 #define EXTRA_CASES \
+    case 167: \
+    case 168: \
+    case 169: \
     case 170: \
-    case 173: \
     case 174: \
     case 175: \
     case 176: \
diff --git a/Include/opcode.h b/Include/opcode.h
index 246a463be5e0..44b77250ad68 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -37,16 +37,13 @@ extern "C" {
 #define CLEANUP_THROW                           55
 #define STORE_SUBSCR                            60
 #define DELETE_SUBSCR                           61
-#define STOPITERATION_ERROR                     63
 #define GET_ITER                                68
 #define GET_YIELD_FROM_ITER                     69
-#define PRINT_EXPR                              70
 #define LOAD_BUILD_CLASS                        71
 #define LOAD_ASSERTION_ERROR                    74
 #define RETURN_GENERATOR                        75
 #define LIST_TO_TUPLE                           82
 #define RETURN_VALUE                            83
-#define IMPORT_STAR                             84
 #define SETUP_ANNOTATIONS                       85
 #define ASYNC_GEN_WRAP                          87
 #define PREP_RERAISE_STAR                       88
@@ -120,6 +117,7 @@ extern "C" {
 #define DICT_UPDATE                            165
 #define CALL                                   171
 #define KW_NAMES                               172
+#define CALL_INTRINSIC_1                       173
 #define MIN_PSEUDO_OPCODE                      256
 #define SETUP_FINALLY                          256
 #define SETUP_CLEANUP                          257
@@ -163,33 +161,33 @@ extern "C" {
 #define COMPARE_OP_STR_JUMP                     58
 #define FOR_ITER_LIST                           59
 #define FOR_ITER_TUPLE                          62
-#define FOR_ITER_RANGE                          64
-#define FOR_ITER_GEN                            65
-#define LOAD_ATTR_CLASS                         66
-#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN       67
-#define LOAD_ATTR_INSTANCE_VALUE                72
-#define LOAD_ATTR_MODULE                        73
-#define LOAD_ATTR_PROPERTY                      76
-#define LOAD_ATTR_SLOT                          77
-#define LOAD_ATTR_WITH_HINT                     78
-#define LOAD_ATTR_METHOD_LAZY_DICT              79
-#define LOAD_ATTR_METHOD_NO_DICT                80
-#define LOAD_ATTR_METHOD_WITH_VALUES            81
-#define LOAD_CONST__LOAD_FAST                   86
-#define LOAD_FAST__LOAD_CONST                  113
-#define LOAD_FAST__LOAD_FAST                   121
-#define LOAD_GLOBAL_BUILTIN                    141
-#define LOAD_GLOBAL_MODULE                     143
-#define STORE_ATTR_INSTANCE_VALUE              153
-#define STORE_ATTR_SLOT                        154
-#define STORE_ATTR_WITH_HINT                   158
-#define STORE_FAST__LOAD_FAST                  159
-#define STORE_FAST__STORE_FAST                 160
-#define STORE_SUBSCR_DICT                      161
-#define STORE_SUBSCR_LIST_INT                  166
-#define UNPACK_SEQUENCE_LIST                   167
-#define UNPACK_SEQUENCE_TUPLE                  168
-#define UNPACK_SEQUENCE_TWO_TUPLE              169
+#define FOR_ITER_RANGE                          63
+#define FOR_ITER_GEN                            64
+#define LOAD_ATTR_CLASS                         65
+#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN       66
+#define LOAD_ATTR_INSTANCE_VALUE                67
+#define LOAD_ATTR_MODULE                        70
+#define LOAD_ATTR_PROPERTY                      72
+#define LOAD_ATTR_SLOT                          73
+#define LOAD_ATTR_WITH_HINT                     76
+#define LOAD_ATTR_METHOD_LAZY_DICT              77
+#define LOAD_ATTR_METHOD_NO_DICT                78
+#define LOAD_ATTR_METHOD_WITH_VALUES            79
+#define LOAD_CONST__LOAD_FAST                   80
+#define LOAD_FAST__LOAD_CONST                   81
+#define LOAD_FAST__LOAD_FAST                    84
+#define LOAD_GLOBAL_BUILTIN                     86
+#define LOAD_GLOBAL_MODULE                     113
+#define STORE_ATTR_INSTANCE_VALUE              121
+#define STORE_ATTR_SLOT                        141
+#define STORE_ATTR_WITH_HINT                   143
+#define STORE_FAST__LOAD_FAST                  153
+#define STORE_FAST__STORE_FAST                 154
+#define STORE_SUBSCR_DICT                      158
+#define STORE_SUBSCR_LIST_INT                  159
+#define UNPACK_SEQUENCE_LIST                   160
+#define UNPACK_SEQUENCE_TUPLE                  161
+#define UNPACK_SEQUENCE_TWO_TUPLE              166
 #define DO_TRACING                             255
 
 #define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index 71a16064b8ec..e700ce634aca 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -426,6 +426,7 @@ def _write_atomic(path, data, mode=0o666):
 #     Python 3.12a1 3510 (FOR_ITER leaves iterator on the stack)
 #     Python 3.12a1 3511 (Add STOPITERATION_ERROR instruction)
 #     Python 3.12a1 3512 (Remove all unused consts from code objects)
+#     Python 3.12a1 3513 (Add CALL_INTRINSIC_1 instruction, removed STOPITERATION_ERROR, PRINT_EXPR, IMPORT_STAR)
 
 #     Python 3.13 will start with 3550
 
@@ -438,7 +439,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 = (3512).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3513).to_bytes(2, 'little') + b'\r\n'
 
 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c
 
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 9271eb47e3a4..a5dea8c6fd24 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -112,11 +112,9 @@ def pseudo_op(name, op, real_ops):
 def_op('STORE_SUBSCR', 60)
 def_op('DELETE_SUBSCR', 61)
 
-def_op('STOPITERATION_ERROR', 63)
-
 def_op('GET_ITER', 68)
 def_op('GET_YIELD_FROM_ITER', 69)
-def_op('PRINT_EXPR', 70)
+
 def_op('LOAD_BUILD_CLASS', 71)
 
 def_op('LOAD_ASSERTION_ERROR', 74)
@@ -124,7 +122,7 @@ def pseudo_op(name, op, real_ops):
 
 def_op('LIST_TO_TUPLE', 82)
 def_op('RETURN_VALUE', 83)
-def_op('IMPORT_STAR', 84)
+
 def_op('SETUP_ANNOTATIONS', 85)
 
 def_op('ASYNC_GEN_WRAP', 87)
@@ -220,7 +218,7 @@ def pseudo_op(name, op, real_ops):
 def_op('CALL', 171)
 def_op('KW_NAMES', 172)
 hasconst.append(172)
-
+def_op('CALL_INTRINSIC_1', 173)
 
 hasarg.extend([op for op in opmap.values() if op >= HAVE_ARGUMENT])
 
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index 950af3ceb24f..c2a339ac7cba 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -543,7 +543,7 @@ async def _asyncwith(c):
         >> COPY                     3
            POP_EXCEPT
            RERAISE                  1
-        >> STOPITERATION_ERROR
+        >> CALL_INTRINSIC_1         3
            RERAISE                  1
 ExceptionTable:
 12 rows
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 1f8bd561f61d..397fc996192d 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -395,6 +395,7 @@ PYTHON_OBJS=	\
 		Python/import.o \
 		Python/importdl.o \
 		Python/initconfig.o \
+		Python/intrinsics.o \
 		Python/marshal.o \
 		Python/modsupport.o \
 		Python/mysnprintf.o \
@@ -1650,6 +1651,7 @@ PYTHON_HEADERS= \
 		$(srcdir)/Include/internal/pycore_initconfig.h \
 		$(srcdir)/Include/internal/pycore_interp.h \
 		$(srcdir)/Include/internal/pycore_interpreteridobject.h \
+		$(srcdir)/Include/internal/pycore_intrinsics.h \
 		$(srcdir)/Include/internal/pycore_list.h \
 		$(srcdir)/Include/internal/pycore_long.h \
 		$(srcdir)/Include/internal/pycore_moduleobject.h \
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-05-13-54-00.gh-issue-99005.D7H6j4.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-05-13-54-00.gh-issue-99005.D7H6j4.rst
new file mode 100644
index 000000000000..bd81cde45bc9
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-05-13-54-00.gh-issue-99005.D7H6j4.rst	
@@ -0,0 +1,4 @@
+Add new :opcode:`CALL_INSTRINSIC_1` instruction. Remove
+:opcode:`IMPORT_STAR`, :opcode:`PRINT_EXPR` and
+:opcode:`STOPITERATION_ERROR`, replacing them with the
+:opcode:`CALL_INSTRINSIC_1` instruction.
diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj
index fce1f6705100..4f39756019e6 100644
--- a/PCbuild/_freeze_module.vcxproj
+++ b/PCbuild/_freeze_module.vcxproj
@@ -206,6 +206,7 @@
     <ClCompile Include="..\Python\import.c" />
     <ClCompile Include="..\Python\importdl.c" />
     <ClCompile Include="..\Python\initconfig.c" />
+    <ClCompile Include="..\Python\intrinsics.c" />
     <ClCompile Include="..\Python\marshal.c" />
     <ClCompile Include="..\Python\modsupport.c" />
     <ClCompile Include="..\Python\mysnprintf.c" />
diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters
index dce6278987c5..7d7c4587b9a3 100644
--- a/PCbuild/_freeze_module.vcxproj.filters
+++ b/PCbuild/_freeze_module.vcxproj.filters
@@ -205,6 +205,9 @@
     <ClCompile Include="..\Python\initconfig.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\Python\intrinsics.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\Objects\interpreteridobject.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index bb2aaae3317b..78f5234c6342 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -231,6 +231,7 @@
     <ClInclude Include="..\Include\internal\pycore_initconfig.h" />
     <ClInclude Include="..\Include\internal\pycore_interp.h" />
     <ClInclude Include="..\Include\internal\pycore_interpreteridobject.h" />
+    <ClInclude Include="..\Include\internal\pycore_intrinsics.h" />
     <ClInclude Include="..\Include\internal\pycore_list.h" />
     <ClInclude Include="..\Include\internal\pycore_long.h" />
     <ClInclude Include="..\Include\internal\pycore_moduleobject.h" />
@@ -520,6 +521,7 @@
     <ClCompile Include="..\Python\import.c" />
     <ClCompile Include="..\Python\importdl.c" />
     <ClCompile Include="..\Python\initconfig.c" />
+    <ClCompile Include="..\Python\intrinsics.c" />
     <ClCompile Include="..\Python\marshal.c" />
     <ClCompile Include="..\Python\modsupport.c" />
     <ClCompile Include="..\Python\mysnprintf.c" />
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index 339e7cc4937a..c1b531fd818a 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -600,6 +600,9 @@
     <ClInclude Include="..\Include\internal\pycore_interpreteridobject.h">
       <Filter>Include\cpython</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_intrinsics.h">
+      <Filter>Include\cpython</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_list.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
@@ -1151,6 +1154,9 @@
     <ClCompile Include="..\Python\initconfig.c">
       <Filter>Python</Filter>
     </ClCompile>
+    <ClCompile Include="..\Python\intrinsics.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\Python\marshal.c">
       <Filter>Python</Filter>
     </ClCompile>
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 5f8871c4b3de..9283f590582a 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -12,6 +12,7 @@
 #include "pycore_ceval.h"         // _PyEval_SignalAsyncExc()
 #include "pycore_code.h"
 #include "pycore_function.h"
+#include "pycore_intrinsics.h"
 #include "pycore_long.h"          // _PyLong_GetZero()
 #include "pycore_object.h"        // _PyObject_GC_TRACK()
 #include "pycore_moduleobject.h"  // PyModuleObject
@@ -538,20 +539,11 @@ dummy_func(
             ERROR_IF(err, error);
         }
 
-        inst(PRINT_EXPR, (value --)) {
-            PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook));
-            PyObject *res;
-            // Can't use ERROR_IF here.
-            if (hook == NULL) {
-                _PyErr_SetString(tstate, PyExc_RuntimeError,
-                                 "lost sys.displayhook");
-                DECREF_INPUTS();
-                ERROR_IF(true, error);
-            }
-            res = PyObject_CallOneArg(hook, value);
-            DECREF_INPUTS();
+        inst(CALL_INTRINSIC_1, (value -- res)) {
+            assert(oparg <= MAX_INTRINSIC_1);
+            res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value);
+            Py_DECREF(value);
             ERROR_IF(res == NULL, error);
-            Py_DECREF(res);
         }
 
         // stack effect: (__array[oparg] -- )
@@ -867,47 +859,6 @@ dummy_func(
             }
         }
 
-        inst(STOPITERATION_ERROR) {
-            assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
-            PyObject *exc = TOP();
-            assert(PyExceptionInstance_Check(exc));
-            const char *msg = NULL;
-            if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) {
-                msg = "generator raised StopIteration";
-                if (frame->f_code->co_flags & CO_ASYNC_GENERATOR) {
-                    msg = "async generator raised StopIteration";
-                }
-                else if (frame->f_code->co_flags & CO_COROUTINE) {
-                    msg = "coroutine raised StopIteration";
-                }
-            }
-            else if ((frame->f_code->co_flags & CO_ASYNC_GENERATOR) &&
-                    PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration))
-            {
-                /* code in `gen` raised a StopAsyncIteration error:
-                raise a RuntimeError.
-                */
-                msg = "async generator raised StopAsyncIteration";
-            }
-            if (msg != NULL) {
-                PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg));
-                if (message == NULL) {
-                    goto error;
-                }
-                PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message);
-                if (error == NULL) {
-                    Py_DECREF(message);
-                    goto error;
-                }
-                assert(PyExceptionInstance_Check(error));
-                SET_TOP(error);
-                PyException_SetCause(error, Py_NewRef(exc));
-                // Steal exc reference, rather than Py_NewRef+Py_DECREF
-                PyException_SetContext(error, exc);
-                Py_DECREF(message);
-            }
-        }
-
         inst(LOAD_ASSERTION_ERROR, ( -- value)) {
             value = Py_NewRef(PyExc_AssertionError);
         }
@@ -2065,27 +2016,6 @@ dummy_func(
             ERROR_IF(res == NULL, error);
         }
 
-        inst(IMPORT_STAR, (from --)) {
-            PyObject *locals;
-            int err;
-            if (_PyFrame_FastToLocalsWithError(frame) < 0) {
-                DECREF_INPUTS();
-                ERROR_IF(true, error);
-            }
-
-            locals = LOCALS();
-            if (locals == NULL) {
-                _PyErr_SetString(tstate, PyExc_SystemError,
-                                 "no locals found during 'import *'");
-                DECREF_INPUTS();
-                ERROR_IF(true, error);
-            }
-            err = import_all_from(tstate, locals, from);
-            _PyFrame_LocalsToFast(frame, 0);
-            DECREF_INPUTS();
-            ERROR_IF(err, error);
-        }
-
         inst(IMPORT_FROM, (from -- from, res)) {
             PyObject *name = GETITEM(names, oparg);
             res = import_from(tstate, from, name);
diff --git a/Python/ceval.c b/Python/ceval.c
index 54df1c512502..149b88e1545d 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -13,6 +13,7 @@
 #include "pycore_ceval.h"         // _PyEval_SignalAsyncExc()
 #include "pycore_code.h"
 #include "pycore_function.h"
+#include "pycore_intrinsics.h"
 #include "pycore_long.h"          // _PyLong_GetZero()
 #include "pycore_object.h"        // _PyObject_GC_TRACK()
 #include "pycore_moduleobject.h"  // PyModuleObject
@@ -204,7 +205,6 @@ static void dtrace_function_return(_PyInterpreterFrame *);
 static PyObject * import_name(PyThreadState *, _PyInterpreterFrame *,
                               PyObject *, PyObject *, PyObject *);
 static PyObject * import_from(PyThreadState *, PyObject *, PyObject *);
-static int import_all_from(PyThreadState *, PyObject *, PyObject *);
 static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *);
 static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg);
 static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg);
@@ -3156,95 +3156,6 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name)
     return NULL;
 }
 
-static int
-import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
-{
-    PyObject *all, *dict, *name, *value;
-    int skip_leading_underscores = 0;
-    int pos, err;
-
-    if (_PyObject_LookupAttr(v, &_Py_ID(__all__), &all) < 0) {
-        return -1; /* Unexpected error */
-    }
-    if (all == NULL) {
-        if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &dict) < 0) {
-            return -1;
-        }
-        if (dict == NULL) {
-            _PyErr_SetString(tstate, PyExc_ImportError,
-                    "from-import-* object has no __dict__ and no __all__");
-            return -1;
-        }
-        all = PyMapping_Keys(dict);
-        Py_DECREF(dict);
-        if (all == NULL)
-            return -1;
-        skip_leading_underscores = 1;
-    }
-
-    for (pos = 0, err = 0; ; pos++) {
-        name = PySequence_GetItem(all, pos);
-        if (name == NULL) {
-            if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) {
-                err = -1;
-            }
-            else {
-                _PyErr_Clear(tstate);
-            }
-            break;
-        }
-        if (!PyUnicode_Check(name)) {
-            PyObject *modname = PyObject_GetAttr(v, &_Py_ID(__name__));
-            if (modname == NULL) {
-                Py_DECREF(name);
-                err = -1;
-                break;
-            }
-            if (!PyUnicode_Check(modname)) {
-                _PyErr_Format(tstate, PyExc_TypeError,
-                              "module __name__ must be a string, not %.100s",
-                              Py_TYPE(modname)->tp_name);
-            }
-            else {
-                _PyErr_Format(tstate, PyExc_TypeError,
-                              "%s in %U.%s must be str, not %.100s",
-                              skip_leading_underscores ? "Key" : "Item",
-                              modname,
-                              skip_leading_underscores ? "__dict__" : "__all__",
-                              Py_TYPE(name)->tp_name);
-            }
-            Py_DECREF(modname);
-            Py_DECREF(name);
-            err = -1;
-            break;
-        }
-        if (skip_leading_underscores) {
-            if (PyUnicode_READY(name) == -1) {
-                Py_DECREF(name);
-                err = -1;
-                break;
-            }
-            if (PyUnicode_READ_CHAR(name, 0) == '_') {
-                Py_DECREF(name);
-                continue;
-            }
-        }
-        value = PyObject_GetAttr(v, name);
-        if (value == NULL)
-            err = -1;
-        else if (PyDict_CheckExact(locals))
-            err = PyDict_SetItem(locals, name, value);
-        else
-            err = PyObject_SetItem(locals, name, value);
-        Py_DECREF(name);
-        Py_XDECREF(value);
-        if (err != 0)
-            break;
-    }
-    Py_DECREF(all);
-    return err;
-}
-
 #define CANNOT_CATCH_MSG "catching classes that do not inherit from "\
                          "BaseException is not allowed"
 
diff --git a/Python/compile.c b/Python/compile.c
index 2527023d18e8..ff29fb42c5d1 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -30,6 +30,7 @@
 #include "pycore_ast.h"           // _PyAST_GetDocString()
 #include "pycore_code.h"          // _PyCode_New()
 #include "pycore_compile.h"       // _PyFuture_FromAST()
+#include "pycore_intrinsics.h"
 #include "pycore_long.h"          // _PyLong_GetZero()
 #include "pycore_opcode.h"        // _PyOpcode_Caches
 #include "pycore_pymem.h"         // _PyMem_IsPtrFreed()
@@ -1113,15 +1114,11 @@ stack_effect(int opcode, int oparg, int jump)
         case GET_ITER:
             return 0;
 
-        case PRINT_EXPR:
-            return -1;
         case LOAD_BUILD_CLASS:
             return 1;
 
         case RETURN_VALUE:
             return -1;
-        case IMPORT_STAR:
-            return -1;
         case SETUP_ANNOTATIONS:
             return 0;
         case ASYNC_GEN_WRAP:
@@ -1216,10 +1213,6 @@ stack_effect(int opcode, int oparg, int jump)
              * of __(a)enter__ and push 2 values before jumping to the handler
              * if an exception be raised. */
             return jump ? 1 : 0;
-
-        case STOPITERATION_ERROR:
-            return 0;
-
         case PREP_RERAISE_STAR:
              return -1;
         case RERAISE:
@@ -1249,7 +1242,8 @@ stack_effect(int opcode, int oparg, int jump)
             return 0;
         case CALL:
             return -1-oparg;
-
+        case CALL_INTRINSIC_1:
+            return 0;
         case CALL_FUNCTION_EX:
             return -2 - ((oparg & 0x01) != 0);
         case MAKE_FUNCTION:
@@ -2604,7 +2598,7 @@ wrap_in_stopiteration_handler(struct compiler *c)
     ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
     ADDOP(c, NO_LOCATION, RETURN_VALUE);
     USE_LABEL(c, handler);
-    ADDOP(c, NO_LOCATION, STOPITERATION_ERROR);
+    ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR);
     ADDOP_I(c, NO_LOCATION, RERAISE, 1);
     return SUCCESS;
 }
@@ -3953,7 +3947,8 @@ compiler_from_import(struct compiler *c, stmt_ty s)
 
         if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
             assert(n == 1);
-            ADDOP(c, LOC(s), IMPORT_STAR);
+            ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR);
+            ADDOP(c, NO_LOCATION, POP_TOP);
             return SUCCESS;
         }
 
@@ -4005,7 +4000,8 @@ compiler_stmt_expr(struct compiler *c, location loc, expr_ty value)
 {
     if (c->c_interactive && c->c_nestlevel <= 1) {
         VISIT(c, expr, value);
-        ADDOP(c, loc, PRINT_EXPR);
+        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT);
+        ADDOP(c, NO_LOCATION, POP_TOP);
         return SUCCESS;
     }
 
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index fa1f941044e0..0d4dad40ea54 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -684,22 +684,14 @@
             DISPATCH();
         }
 
-        TARGET(PRINT_EXPR) {
+        TARGET(CALL_INTRINSIC_1) {
             PyObject *value = PEEK(1);
-            PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook));
             PyObject *res;
-            // Can't use ERROR_IF here.
-            if (hook == NULL) {
-                _PyErr_SetString(tstate, PyExc_RuntimeError,
-                                 "lost sys.displayhook");
-                Py_DECREF(value);
-                if (true) goto pop_1_error;
-            }
-            res = PyObject_CallOneArg(hook, value);
+            assert(oparg <= MAX_INTRINSIC_1);
+            res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value);
             Py_DECREF(value);
             if (res == NULL) goto pop_1_error;
-            Py_DECREF(res);
-            STACK_SHRINK(1);
+            POKE(1, res);
             DISPATCH();
         }
 
@@ -1045,48 +1037,6 @@
             DISPATCH();
         }
 
-        TARGET(STOPITERATION_ERROR) {
-            assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
-            PyObject *exc = TOP();
-            assert(PyExceptionInstance_Check(exc));
-            const char *msg = NULL;
-            if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) {
-                msg = "generator raised StopIteration";
-                if (frame->f_code->co_flags & CO_ASYNC_GENERATOR) {
-                    msg = "async generator raised StopIteration";
-                }
-                else if (frame->f_code->co_flags & CO_COROUTINE) {
-                    msg = "coroutine raised StopIteration";
-                }
-            }
-            else if ((frame->f_code->co_flags & CO_ASYNC_GENERATOR) &&
-                    PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration))
-            {
-                /* code in `gen` raised a StopAsyncIteration error:
-                raise a RuntimeError.
-                */
-                msg = "async generator raised StopAsyncIteration";
-            }
-            if (msg != NULL) {
-                PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg));
-                if (message == NULL) {
-                    goto error;
-                }
-                PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message);
-                if (error == NULL) {
-                    Py_DECREF(message);
-                    goto error;
-                }
-                assert(PyExceptionInstance_Check(error));
-                SET_TOP(error);
-                PyException_SetCause(error, Py_NewRef(exc));
-                // Steal exc reference, rather than Py_NewRef+Py_DECREF
-                PyException_SetContext(error, exc);
-                Py_DECREF(message);
-            }
-            DISPATCH();
-        }
-
         TARGET(LOAD_ASSERTION_ERROR) {
             PyObject *value;
             value = Py_NewRef(PyExc_AssertionError);
@@ -2401,30 +2351,6 @@
             DISPATCH();
         }
 
-        TARGET(IMPORT_STAR) {
-            PyObject *from = PEEK(1);
-            PyObject *locals;
-            int err;
-            if (_PyFrame_FastToLocalsWithError(frame) < 0) {
-                Py_DECREF(from);
-                if (true) goto pop_1_error;
-            }
-
-            locals = LOCALS();
-            if (locals == NULL) {
-                _PyErr_SetString(tstate, PyExc_SystemError,
-                                 "no locals found during 'import *'");
-                Py_DECREF(from);
-                if (true) goto pop_1_error;
-            }
-            err = import_all_from(tstate, locals, from);
-            _PyFrame_LocalsToFast(frame, 0);
-            Py_DECREF(from);
-            if (err) goto pop_1_error;
-            STACK_SHRINK(1);
-            DISPATCH();
-        }
-
         TARGET(IMPORT_FROM) {
             PyObject *from = PEEK(1);
             PyObject *res;
diff --git a/Python/intrinsics.c b/Python/intrinsics.c
new file mode 100644
index 000000000000..07b9c6a97c6e
--- /dev/null
+++ b/Python/intrinsics.c
@@ -0,0 +1,194 @@
+
+#define _PY_INTERPRETER
+
+#include "Python.h"
+#include "pycore_frame.h"
+#include "pycore_runtime.h"
+#include "pycore_global_objects.h"
+#include "pycore_intrinsics.h"
+#include "pycore_pyerrors.h"
+
+
+
+static PyObject *
+no_intrinsic(PyThreadState* tstate, PyObject *unused)
+{
+    _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function");
+    return NULL;
+}
+
+static PyObject *
+print_expr(PyThreadState* tstate, PyObject *value)
+{
+    PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook));
+    // Can't use ERROR_IF here.
+    if (hook == NULL) {
+        _PyErr_SetString(tstate, PyExc_RuntimeError,
+                            "lost sys.displayhook");
+        return NULL;
+    }
+    return PyObject_CallOneArg(hook, value);
+}
+
+static int
+import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
+{
+    PyObject *all, *dict, *name, *value;
+    int skip_leading_underscores = 0;
+    int pos, err;
+
+    if (_PyObject_LookupAttr(v, &_Py_ID(__all__), &all) < 0) {
+        return -1; /* Unexpected error */
+    }
+    if (all == NULL) {
+        if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &dict) < 0) {
+            return -1;
+        }
+        if (dict == NULL) {
+            _PyErr_SetString(tstate, PyExc_ImportError,
+                    "from-import-* object has no __dict__ and no __all__");
+            return -1;
+        }
+        all = PyMapping_Keys(dict);
+        Py_DECREF(dict);
+        if (all == NULL)
+            return -1;
+        skip_leading_underscores = 1;
+    }
+
+    for (pos = 0, err = 0; ; pos++) {
+        name = PySequence_GetItem(all, pos);
+        if (name == NULL) {
+            if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) {
+                err = -1;
+            }
+            else {
+                _PyErr_Clear(tstate);
+            }
+            break;
+        }
+        if (!PyUnicode_Check(name)) {
+            PyObject *modname = PyObject_GetAttr(v, &_Py_ID(__name__));
+            if (modname == NULL) {
+                Py_DECREF(name);
+                err = -1;
+                break;
+            }
+            if (!PyUnicode_Check(modname)) {
+                _PyErr_Format(tstate, PyExc_TypeError,
+                              "module __name__ must be a string, not %.100s",
+                              Py_TYPE(modname)->tp_name);
+            }
+            else {
+                _PyErr_Format(tstate, PyExc_TypeError,
+                              "%s in %U.%s must be str, not %.100s",
+                              skip_leading_underscores ? "Key" : "Item",
+                              modname,
+                              skip_leading_underscores ? "__dict__" : "__all__",
+                              Py_TYPE(name)->tp_name);
+            }
+            Py_DECREF(modname);
+            Py_DECREF(name);
+            err = -1;
+            break;
+        }
+        if (skip_leading_underscores) {
+            if (PyUnicode_READY(name) == -1) {
+                Py_DECREF(name);
+                err = -1;
+                break;
+            }
+            if (PyUnicode_READ_CHAR(name, 0) == '_') {
+                Py_DECREF(name);
+                continue;
+            }
+        }
+        value = PyObject_GetAttr(v, name);
+        if (value == NULL)
+            err = -1;
+        else if (PyDict_CheckExact(locals))
+            err = PyDict_SetItem(locals, name, value);
+        else
+            err = PyObject_SetItem(locals, name, value);
+        Py_DECREF(name);
+        Py_XDECREF(value);
+        if (err < 0)
+            break;
+    }
+    Py_DECREF(all);
+    return err;
+}
+
+static PyObject *
+import_star(PyThreadState* tstate, PyObject *from)
+{
+    _PyInterpreterFrame *frame = tstate->cframe->current_frame;
+    if (_PyFrame_FastToLocalsWithError(frame) < 0) {
+        return NULL;
+    }
+
+    PyObject *locals = frame->f_locals;
+    if (locals == NULL) {
+        _PyErr_SetString(tstate, PyExc_SystemError,
+                            "no locals found during 'import *'");
+        return NULL;
+    }
+    int err = import_all_from(tstate, locals, from);
+    _PyFrame_LocalsToFast(frame, 0);
+    if (err < 0) {
+        return NULL;
+    }
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+stopiteration_error(PyThreadState* tstate, PyObject *exc)
+{
+    _PyInterpreterFrame *frame = tstate->cframe->current_frame;
+    assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
+    assert(PyExceptionInstance_Check(exc));
+    const char *msg = NULL;
+    if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) {
+        msg = "generator raised StopIteration";
+        if (frame->f_code->co_flags & CO_ASYNC_GENERATOR) {
+            msg = "async generator raised StopIteration";
+        }
+        else if (frame->f_code->co_flags & CO_COROUTINE) {
+            msg = "coroutine raised StopIteration";
+        }
+    }
+    else if ((frame->f_code->co_flags & CO_ASYNC_GENERATOR) &&
+            PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration))
+    {
+        /* code in `gen` raised a StopAsyncIteration error:
+        raise a RuntimeError.
+        */
+        msg = "async generator raised StopAsyncIteration";
+    }
+    if (msg != NULL) {
+        PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg));
+        if (message == NULL) {
+            return NULL;
+        }
+        PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message);
+        if (error == NULL) {
+            Py_DECREF(message);
+            return NULL;
+        }
+        assert(PyExceptionInstance_Check(error));
+        PyException_SetCause(error, Py_NewRef(exc));
+        // Steal exc reference, rather than Py_NewRef+Py_DECREF
+        PyException_SetContext(error, Py_NewRef(exc));
+        Py_DECREF(message);
+        return error;
+    }
+    return Py_NewRef(exc);
+}
+
+instrinsic_func1
+_PyIntrinsics_UnaryFunctions[] = {
+    [0] = no_intrinsic,
+    [INTRINSIC_PRINT] = print_expr,
+    [INTRINSIC_IMPORT_STAR] = import_star,
+    [INTRINSIC_STOPITERATION_ERROR] = stopiteration_error,
+};
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index 0716fccb964e..4bb6d53e995d 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -62,30 +62,30 @@ static void *opcode_targets[256] = {
     &&TARGET_STORE_SUBSCR,
     &&TARGET_DELETE_SUBSCR,
     &&TARGET_FOR_ITER_TUPLE,
-    &&TARGET_STOPITERATION_ERROR,
     &&TARGET_FOR_ITER_RANGE,
     &&TARGET_FOR_ITER_GEN,
     &&TARGET_LOAD_ATTR_CLASS,
     &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN,
+    &&TARGET_LOAD_ATTR_INSTANCE_VALUE,
     &&TARGET_GET_ITER,
     &&TARGET_GET_YIELD_FROM_ITER,
-    &&TARGET_PRINT_EXPR,
-    &&TARGET_LOAD_BUILD_CLASS,
-    &&TARGET_LOAD_ATTR_INSTANCE_VALUE,
     &&TARGET_LOAD_ATTR_MODULE,
-    &&TARGET_LOAD_ASSERTION_ERROR,
-    &&TARGET_RETURN_GENERATOR,
+    &&TARGET_LOAD_BUILD_CLASS,
     &&TARGET_LOAD_ATTR_PROPERTY,
     &&TARGET_LOAD_ATTR_SLOT,
+    &&TARGET_LOAD_ASSERTION_ERROR,
+    &&TARGET_RETURN_GENERATOR,
     &&TARGET_LOAD_ATTR_WITH_HINT,
     &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT,
     &&TARGET_LOAD_ATTR_METHOD_NO_DICT,
     &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES,
+    &&TARGET_LOAD_CONST__LOAD_FAST,
+    &&TARGET_LOAD_FAST__LOAD_CONST,
     &&TARGET_LIST_TO_TUPLE,
     &&TARGET_RETURN_VALUE,
-    &&TARGET_IMPORT_STAR,
+    &&TARGET_LOAD_FAST__LOAD_FAST,
     &&TARGET_SETUP_ANNOTATIONS,
-    &&TARGET_LOAD_CONST__LOAD_FAST,
+    &&TARGET_LOAD_GLOBAL_BUILTIN,
     &&TARGET_ASYNC_GEN_WRAP,
     &&TARGET_PREP_RERAISE_STAR,
     &&TARGET_POP_EXCEPT,
@@ -112,7 +112,7 @@ static void *opcode_targets[256] = {
     &&TARGET_JUMP_FORWARD,
     &&TARGET_JUMP_IF_FALSE_OR_POP,
     &&TARGET_JUMP_IF_TRUE_OR_POP,
-    &&TARGET_LOAD_FAST__LOAD_CONST,
+    &&TARGET_LOAD_GLOBAL_MODULE,
     &&TARGET_POP_JUMP_IF_FALSE,
     &&TARGET_POP_JUMP_IF_TRUE,
     &&TARGET_LOAD_GLOBAL,
@@ -120,7 +120,7 @@ static void *opcode_targets[256] = {
     &&TARGET_CONTAINS_OP,
     &&TARGET_RERAISE,
     &&TARGET_COPY,
-    &&TARGET_LOAD_FAST__LOAD_FAST,
+    &&TARGET_STORE_ATTR_INSTANCE_VALUE,
     &&TARGET_BINARY_OP,
     &&TARGET_SEND,
     &&TARGET_LOAD_FAST,
@@ -140,9 +140,9 @@ static void *opcode_targets[256] = {
     &&TARGET_STORE_DEREF,
     &&TARGET_DELETE_DEREF,
     &&TARGET_JUMP_BACKWARD,
-    &&TARGET_LOAD_GLOBAL_BUILTIN,
+    &&TARGET_STORE_ATTR_SLOT,
     &&TARGET_CALL_FUNCTION_EX,
-    &&TARGET_LOAD_GLOBAL_MODULE,
+    &&TARGET_STORE_ATTR_WITH_HINT,
     &&TARGET_EXTENDED_ARG,
     &&TARGET_LIST_APPEND,
     &&TARGET_SET_ADD,
@@ -152,27 +152,27 @@ static void *opcode_targets[256] = {
     &&TARGET_YIELD_VALUE,
     &&TARGET_RESUME,
     &&TARGET_MATCH_CLASS,
-    &&TARGET_STORE_ATTR_INSTANCE_VALUE,
-    &&TARGET_STORE_ATTR_SLOT,
+    &&TARGET_STORE_FAST__LOAD_FAST,
+    &&TARGET_STORE_FAST__STORE_FAST,
     &&TARGET_FORMAT_VALUE,
     &&TARGET_BUILD_CONST_KEY_MAP,
     &&TARGET_BUILD_STRING,
-    &&TARGET_STORE_ATTR_WITH_HINT,
-    &&TARGET_STORE_FAST__LOAD_FAST,
-    &&TARGET_STORE_FAST__STORE_FAST,
     &&TARGET_STORE_SUBSCR_DICT,
+    &&TARGET_STORE_SUBSCR_LIST_INT,
+    &&TARGET_UNPACK_SEQUENCE_LIST,
+    &&TARGET_UNPACK_SEQUENCE_TUPLE,
     &&TARGET_LIST_EXTEND,
     &&TARGET_SET_UPDATE,
     &&TARGET_DICT_MERGE,
     &&TARGET_DICT_UPDATE,
-    &&TARGET_STORE_SUBSCR_LIST_INT,
-    &&TARGET_UNPACK_SEQUENCE_LIST,
-    &&TARGET_UNPACK_SEQUENCE_TUPLE,
     &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE,
     &&_unknown_opcode,
+    &&_unknown_opcode,
+    &&_unknown_opcode,
+    &&_unknown_opcode,
     &&TARGET_CALL,
     &&TARGET_KW_NAMES,
-    &&_unknown_opcode,
+    &&TARGET_CALL_INTRINSIC_1,
     &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,



More information about the Python-checkins mailing list