mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
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:
parent
f20c553a45
commit
28187141cc
19 changed files with 336 additions and 361 deletions
194
Python/intrinsics.c
Normal file
194
Python/intrinsics.c
Normal 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,
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue