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

* Remove PRINT_EXPR instruction

* Remove STOPITERATION_ERROR instruction

* Remove IMPORT_STAR instruction
This commit is contained in:
Mark Shannon 2023-01-05 16:05:51 +00:00 committed by GitHub
parent f20c553a45
commit 28187141cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 336 additions and 361 deletions

View file

@ -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

View file

@ -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[];

View file

@ -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: \

58
Include/opcode.h generated
View file

@ -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)))\

View file

@ -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

View file

@ -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])

View file

@ -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

View file

@ -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 \

View file

@ -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.

View file

@ -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" />

View file

@ -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>

View file

@ -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" />

View file

@ -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>

View file

@ -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);

View file

@ -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"

View file

@ -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;
}

View file

@ -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;

194
Python/intrinsics.c Normal file
View file

@ -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,
};

View file

@ -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,