mirror of
https://github.com/python/cpython.git
synced 2025-10-31 21:51:50 +00:00
bpo-45256: Rationalize code around Python-to-Python calls a bit. (GH-29235)
This commit is contained in:
parent
0a1a36b74b
commit
7f61d9d848
4 changed files with 121 additions and 70 deletions
|
|
@ -152,6 +152,21 @@ _PyFrame_LocalsToFast(InterpreterFrame *frame, int clear);
|
||||||
InterpreterFrame *_PyThreadState_PushFrame(
|
InterpreterFrame *_PyThreadState_PushFrame(
|
||||||
PyThreadState *tstate, PyFrameConstructor *con, PyObject *locals);
|
PyThreadState *tstate, PyFrameConstructor *con, PyObject *locals);
|
||||||
|
|
||||||
|
extern InterpreterFrame *
|
||||||
|
_PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size);
|
||||||
|
|
||||||
|
static inline InterpreterFrame *
|
||||||
|
_PyThreadState_BumpFramePointer(PyThreadState *tstate, size_t size)
|
||||||
|
{
|
||||||
|
PyObject **base = tstate->datastack_top;
|
||||||
|
PyObject **top = base + size;
|
||||||
|
if (top < tstate->datastack_limit) {
|
||||||
|
tstate->datastack_top = top;
|
||||||
|
return (InterpreterFrame *)base;
|
||||||
|
}
|
||||||
|
return _PyThreadState_BumpFramePointerSlow(tstate, size);
|
||||||
|
}
|
||||||
|
|
||||||
void _PyThreadState_PopFrame(PyThreadState *tstate, InterpreterFrame *frame);
|
void _PyThreadState_PopFrame(PyThreadState *tstate, InterpreterFrame *frame);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -786,16 +786,15 @@ allocate_heap_frame(PyFrameConstructor *con, PyObject *locals)
|
||||||
{
|
{
|
||||||
PyCodeObject *code = (PyCodeObject *)con->fc_code;
|
PyCodeObject *code = (PyCodeObject *)con->fc_code;
|
||||||
int size = code->co_nlocalsplus+code->co_stacksize + FRAME_SPECIALS_SIZE;
|
int size = code->co_nlocalsplus+code->co_stacksize + FRAME_SPECIALS_SIZE;
|
||||||
PyObject **localsarray = PyMem_Malloc(sizeof(PyObject *)*size);
|
InterpreterFrame *frame = (InterpreterFrame *)PyMem_Malloc(sizeof(PyObject *)*size);
|
||||||
if (localsarray == NULL) {
|
if (frame == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (Py_ssize_t i=0; i < code->co_nlocalsplus; i++) {
|
|
||||||
localsarray[i] = NULL;
|
|
||||||
}
|
|
||||||
InterpreterFrame *frame = (InterpreterFrame *)(localsarray + code->co_nlocalsplus);
|
|
||||||
_PyFrame_InitializeSpecials(frame, con, locals, code->co_nlocalsplus);
|
_PyFrame_InitializeSpecials(frame, con, locals, code->co_nlocalsplus);
|
||||||
|
for (Py_ssize_t i = 0; i < code->co_nlocalsplus; i++) {
|
||||||
|
frame->localsplus[i] = NULL;
|
||||||
|
}
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
143
Python/ceval.c
143
Python/ceval.c
|
|
@ -101,7 +101,7 @@ static int get_exception_handler(PyCodeObject *, int, int*, int*, int*);
|
||||||
static InterpreterFrame *
|
static InterpreterFrame *
|
||||||
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con,
|
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
PyObject *locals, PyObject* const* args,
|
PyObject *locals, PyObject* const* args,
|
||||||
size_t argcount, PyObject *kwnames, int steal_args);
|
size_t argcount, PyObject *kwnames);
|
||||||
static int
|
static int
|
||||||
_PyEvalFrameClearAndPop(PyThreadState *tstate, InterpreterFrame * frame);
|
_PyEvalFrameClearAndPop(PyThreadState *tstate, InterpreterFrame * frame);
|
||||||
|
|
||||||
|
|
@ -4633,7 +4633,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
|
||||||
InterpreterFrame *new_frame = _PyEvalFramePushAndInit(
|
InterpreterFrame *new_frame = _PyEvalFramePushAndInit(
|
||||||
tstate, PyFunction_AS_FRAME_CONSTRUCTOR(function), locals,
|
tstate, PyFunction_AS_FRAME_CONSTRUCTOR(function), locals,
|
||||||
stack_pointer,
|
stack_pointer,
|
||||||
nargs, kwnames, 1);
|
nargs, kwnames);
|
||||||
STACK_SHRINK(postcall_shrink);
|
STACK_SHRINK(postcall_shrink);
|
||||||
// The frame has stolen all the arguments from the stack,
|
// The frame has stolen all the arguments from the stack,
|
||||||
// so there is no need to clean them up.
|
// so there is no need to clean them up.
|
||||||
|
|
@ -4708,11 +4708,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
|
||||||
/* PEP 523 */
|
/* PEP 523 */
|
||||||
DEOPT_IF(tstate->interp->eval_frame != NULL, CALL_FUNCTION);
|
DEOPT_IF(tstate->interp->eval_frame != NULL, CALL_FUNCTION);
|
||||||
STAT_INC(CALL_FUNCTION, hit);
|
STAT_INC(CALL_FUNCTION, hit);
|
||||||
InterpreterFrame *new_frame = _PyThreadState_PushFrame(
|
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||||
tstate, PyFunction_AS_FRAME_CONSTRUCTOR(func), NULL);
|
size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE;
|
||||||
|
InterpreterFrame *new_frame = _PyThreadState_BumpFramePointer(tstate, size);
|
||||||
if (new_frame == NULL) {
|
if (new_frame == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
_PyFrame_InitializeSpecials(new_frame, PyFunction_AS_FRAME_CONSTRUCTOR(func),
|
||||||
|
NULL, code->co_nlocalsplus);
|
||||||
STACK_SHRINK(argcount);
|
STACK_SHRINK(argcount);
|
||||||
for (int i = 0; i < argcount; i++) {
|
for (int i = 0; i < argcount; i++) {
|
||||||
new_frame->localsplus[i] = stack_pointer[i];
|
new_frame->localsplus[i] = stack_pointer[i];
|
||||||
|
|
@ -4723,6 +4726,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
|
||||||
Py_INCREF(def);
|
Py_INCREF(def);
|
||||||
new_frame->localsplus[argcount+i] = def;
|
new_frame->localsplus[argcount+i] = def;
|
||||||
}
|
}
|
||||||
|
for (int i = argcount+deflen; i < code->co_nlocalsplus; i++) {
|
||||||
|
new_frame->localsplus[i] = NULL;
|
||||||
|
}
|
||||||
STACK_SHRINK(1);
|
STACK_SHRINK(1);
|
||||||
Py_DECREF(func);
|
Py_DECREF(func);
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
|
@ -5595,7 +5601,7 @@ get_exception_handler(PyCodeObject *code, int index, int *level, int *handler, i
|
||||||
static int
|
static int
|
||||||
initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
PyObject **localsplus, PyObject *const *args,
|
PyObject **localsplus, PyObject *const *args,
|
||||||
Py_ssize_t argcount, PyObject *kwnames, int steal_args)
|
Py_ssize_t argcount, PyObject *kwnames)
|
||||||
{
|
{
|
||||||
PyCodeObject *co = (PyCodeObject*)con->fc_code;
|
PyCodeObject *co = (PyCodeObject*)con->fc_code;
|
||||||
const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
|
const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
|
||||||
|
|
@ -5629,9 +5635,6 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
}
|
}
|
||||||
for (j = 0; j < n; j++) {
|
for (j = 0; j < n; j++) {
|
||||||
PyObject *x = args[j];
|
PyObject *x = args[j];
|
||||||
if (!steal_args) {
|
|
||||||
Py_INCREF(x);
|
|
||||||
}
|
|
||||||
assert(localsplus[j] == NULL);
|
assert(localsplus[j] == NULL);
|
||||||
localsplus[j] = x;
|
localsplus[j] = x;
|
||||||
}
|
}
|
||||||
|
|
@ -5639,11 +5642,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
/* Pack other positional arguments into the *args argument */
|
/* Pack other positional arguments into the *args argument */
|
||||||
if (co->co_flags & CO_VARARGS) {
|
if (co->co_flags & CO_VARARGS) {
|
||||||
PyObject *u = NULL;
|
PyObject *u = NULL;
|
||||||
if (steal_args) {
|
u = _PyTuple_FromArraySteal(args + n, argcount - n);
|
||||||
u = _PyTuple_FromArraySteal(args + n, argcount - n);
|
|
||||||
} else {
|
|
||||||
u = _PyTuple_FromArray(args + n, argcount - n);
|
|
||||||
}
|
|
||||||
if (u == NULL) {
|
if (u == NULL) {
|
||||||
goto fail_post_positional;
|
goto fail_post_positional;
|
||||||
}
|
}
|
||||||
|
|
@ -5652,10 +5651,8 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
}
|
}
|
||||||
else if (argcount > n) {
|
else if (argcount > n) {
|
||||||
/* Too many postional args. Error is reported later */
|
/* Too many postional args. Error is reported later */
|
||||||
if (steal_args) {
|
for (j = n; j < argcount; j++) {
|
||||||
for (j = n; j < argcount; j++) {
|
Py_DECREF(args[j]);
|
||||||
Py_DECREF(args[j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5717,19 +5714,15 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
if (PyDict_SetItem(kwdict, keyword, value) == -1) {
|
if (PyDict_SetItem(kwdict, keyword, value) == -1) {
|
||||||
goto kw_fail;
|
goto kw_fail;
|
||||||
}
|
}
|
||||||
if (steal_args) {
|
Py_DECREF(value);
|
||||||
Py_DECREF(value);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
kw_fail:
|
kw_fail:
|
||||||
if (steal_args) {
|
for (;i < kwcount; i++) {
|
||||||
for (;i < kwcount; i++) {
|
PyObject *value = args[i+argcount];
|
||||||
PyObject *value = args[i+argcount];
|
Py_DECREF(value);
|
||||||
Py_DECREF(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
goto fail_noclean;
|
goto fail_post_args;
|
||||||
|
|
||||||
kw_found:
|
kw_found:
|
||||||
if (localsplus[j] != NULL) {
|
if (localsplus[j] != NULL) {
|
||||||
|
|
@ -5738,9 +5731,6 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
con->fc_qualname, keyword);
|
con->fc_qualname, keyword);
|
||||||
goto kw_fail;
|
goto kw_fail;
|
||||||
}
|
}
|
||||||
if (!steal_args) {
|
|
||||||
Py_INCREF(value);
|
|
||||||
}
|
|
||||||
localsplus[j] = value;
|
localsplus[j] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5749,7 +5739,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) {
|
if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) {
|
||||||
too_many_positional(tstate, co, argcount, con->fc_defaults, localsplus,
|
too_many_positional(tstate, co, argcount, con->fc_defaults, localsplus,
|
||||||
con->fc_qualname);
|
con->fc_qualname);
|
||||||
goto fail_noclean;
|
goto fail_post_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add missing positional arguments (copy default values from defs) */
|
/* Add missing positional arguments (copy default values from defs) */
|
||||||
|
|
@ -5765,7 +5755,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
if (missing) {
|
if (missing) {
|
||||||
missing_arguments(tstate, co, missing, defcount, localsplus,
|
missing_arguments(tstate, co, missing, defcount, localsplus,
|
||||||
con->fc_qualname);
|
con->fc_qualname);
|
||||||
goto fail_noclean;
|
goto fail_post_args;
|
||||||
}
|
}
|
||||||
if (n > m)
|
if (n > m)
|
||||||
i = n - m;
|
i = n - m;
|
||||||
|
|
@ -5798,7 +5788,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (_PyErr_Occurred(tstate)) {
|
else if (_PyErr_Occurred(tstate)) {
|
||||||
goto fail_noclean;
|
goto fail_post_args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
missing++;
|
missing++;
|
||||||
|
|
@ -5806,35 +5796,31 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
if (missing) {
|
if (missing) {
|
||||||
missing_arguments(tstate, co, missing, -1, localsplus,
|
missing_arguments(tstate, co, missing, -1, localsplus,
|
||||||
con->fc_qualname);
|
con->fc_qualname);
|
||||||
goto fail_noclean;
|
goto fail_post_args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy closure variables to free variables */
|
/* Copy closure variables to free variables */
|
||||||
for (i = 0; i < co->co_nfreevars; ++i) {
|
for (i = 0; i < co->co_nfreevars; ++i) {
|
||||||
PyObject *o = PyTuple_GET_ITEM(con->fc_closure, i);
|
PyObject *o = PyTuple_GET_ITEM(con->fc_closure, i);
|
||||||
Py_INCREF(o);
|
Py_INCREF(o);
|
||||||
localsplus[co->co_nlocals + co->co_nplaincellvars + i] = o;
|
localsplus[co->co_nlocals + co->co_nplaincellvars + i] = o;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_pre_positional:
|
fail_pre_positional:
|
||||||
if (steal_args) {
|
for (j = 0; j < argcount; j++) {
|
||||||
for (j = 0; j < argcount; j++) {
|
Py_DECREF(args[j]);
|
||||||
Py_DECREF(args[j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
fail_post_positional:
|
fail_post_positional:
|
||||||
if (steal_args) {
|
if (kwnames) {
|
||||||
Py_ssize_t kwcount = kwnames != NULL ? PyTuple_GET_SIZE(kwnames) : 0;
|
Py_ssize_t kwcount = PyTuple_GET_SIZE(kwnames);
|
||||||
for (j = argcount; j < argcount+kwcount; j++) {
|
for (j = argcount; j < argcount+kwcount; j++) {
|
||||||
Py_DECREF(args[j]);
|
Py_DECREF(args[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
fail_noclean:
|
fail_post_args:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5850,21 +5836,34 @@ make_coro_frame(PyThreadState *tstate,
|
||||||
int size = code->co_nlocalsplus+code->co_stacksize + FRAME_SPECIALS_SIZE;
|
int size = code->co_nlocalsplus+code->co_stacksize + FRAME_SPECIALS_SIZE;
|
||||||
InterpreterFrame *frame = (InterpreterFrame *)PyMem_Malloc(sizeof(PyObject *)*size);
|
InterpreterFrame *frame = (InterpreterFrame *)PyMem_Malloc(sizeof(PyObject *)*size);
|
||||||
if (frame == NULL) {
|
if (frame == NULL) {
|
||||||
PyErr_NoMemory();
|
goto fail_no_memory;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i=0; i < code->co_nlocalsplus; i++) {
|
|
||||||
frame->localsplus[i] = NULL;
|
|
||||||
}
|
}
|
||||||
_PyFrame_InitializeSpecials(frame, con, locals, code->co_nlocalsplus);
|
_PyFrame_InitializeSpecials(frame, con, locals, code->co_nlocalsplus);
|
||||||
|
for (int i = 0; i < code->co_nlocalsplus; i++) {
|
||||||
|
frame->localsplus[i] = NULL;
|
||||||
|
}
|
||||||
assert(frame->frame_obj == NULL);
|
assert(frame->frame_obj == NULL);
|
||||||
if (initialize_locals(tstate, con, frame->localsplus, args, argcount, kwnames, 0)) {
|
if (initialize_locals(tstate, con, frame->localsplus, args, argcount, kwnames)) {
|
||||||
_PyFrame_Clear(frame, 1);
|
_PyFrame_Clear(frame, 1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return frame;
|
return frame;
|
||||||
|
fail_no_memory:
|
||||||
|
/* Consume the references */
|
||||||
|
for (Py_ssize_t i = 0; i < argcount; i++) {
|
||||||
|
Py_DECREF(args[i]);
|
||||||
|
}
|
||||||
|
if (kwnames) {
|
||||||
|
Py_ssize_t kwcount = PyTuple_GET_SIZE(kwnames);
|
||||||
|
for (Py_ssize_t i = 0; i < kwcount; i++) {
|
||||||
|
Py_DECREF(args[i+argcount]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Consumes all the references to the args */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
make_coro(PyThreadState *tstate, PyFrameConstructor *con,
|
make_coro(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
PyObject *locals,
|
PyObject *locals,
|
||||||
|
|
@ -5880,28 +5879,44 @@ make_coro(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
if (gen == NULL) {
|
if (gen == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gen;
|
return gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If *steal_args* is set, the function will steal the references to all the arguments.
|
/* Consumes all the references to the args */
|
||||||
// In case of error, the function returns null and if *steal_args* is set, the caller
|
|
||||||
// will still own all the arguments.
|
|
||||||
static InterpreterFrame *
|
static InterpreterFrame *
|
||||||
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con,
|
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
PyObject *locals, PyObject* const* args,
|
PyObject *locals, PyObject* const* args,
|
||||||
size_t argcount, PyObject *kwnames, int steal_args)
|
size_t argcount, PyObject *kwnames)
|
||||||
{
|
{
|
||||||
InterpreterFrame * frame = _PyThreadState_PushFrame(tstate, con, locals);
|
PyCodeObject * code = (PyCodeObject *)con->fc_code;
|
||||||
|
size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE;
|
||||||
|
InterpreterFrame *frame = _PyThreadState_BumpFramePointer(tstate, size);
|
||||||
if (frame == NULL) {
|
if (frame == NULL) {
|
||||||
return NULL;
|
goto fail;
|
||||||
}
|
}
|
||||||
PyObject **localsarray = _PyFrame_GetLocalsArray(frame);
|
_PyFrame_InitializeSpecials(frame, con, locals, code->co_nlocalsplus);
|
||||||
if (initialize_locals(tstate, con, localsarray, args, argcount, kwnames, steal_args)) {
|
PyObject **localsarray = &frame->localsplus[0];
|
||||||
|
for (int i = 0; i < code->co_nlocalsplus; i++) {
|
||||||
|
localsarray[i] = NULL;
|
||||||
|
}
|
||||||
|
if (initialize_locals(tstate, con, localsarray, args, argcount, kwnames)) {
|
||||||
_PyFrame_Clear(frame, 0);
|
_PyFrame_Clear(frame, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return frame;
|
return frame;
|
||||||
|
fail:
|
||||||
|
/* Consume the references */
|
||||||
|
for (size_t i = 0; i < argcount; i++) {
|
||||||
|
Py_DECREF(args[i]);
|
||||||
|
}
|
||||||
|
if (kwnames) {
|
||||||
|
Py_ssize_t kwcount = PyTuple_GET_SIZE(kwnames);
|
||||||
|
for (Py_ssize_t i = 0; i < kwcount; i++) {
|
||||||
|
Py_DECREF(args[i+argcount]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -5925,13 +5940,25 @@ _PyEval_Vector(PyThreadState *tstate, PyFrameConstructor *con,
|
||||||
PyObject *kwnames)
|
PyObject *kwnames)
|
||||||
{
|
{
|
||||||
PyCodeObject *code = (PyCodeObject *)con->fc_code;
|
PyCodeObject *code = (PyCodeObject *)con->fc_code;
|
||||||
|
/* _PyEvalFramePushAndInit and make_coro consume
|
||||||
|
* all the references to their arguments
|
||||||
|
*/
|
||||||
|
for (size_t i = 0; i < argcount; i++) {
|
||||||
|
Py_INCREF(args[i]);
|
||||||
|
}
|
||||||
|
if (kwnames) {
|
||||||
|
Py_ssize_t kwcount = PyTuple_GET_SIZE(kwnames);
|
||||||
|
for (Py_ssize_t i = 0; i < kwcount; i++) {
|
||||||
|
Py_INCREF(args[i+argcount]);
|
||||||
|
}
|
||||||
|
}
|
||||||
int is_coro = code->co_flags &
|
int is_coro = code->co_flags &
|
||||||
(CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR);
|
(CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR);
|
||||||
if (is_coro) {
|
if (is_coro) {
|
||||||
return make_coro(tstate, con, locals, args, argcount, kwnames);
|
return make_coro(tstate, con, locals, args, argcount, kwnames);
|
||||||
}
|
}
|
||||||
InterpreterFrame *frame = _PyEvalFramePushAndInit(
|
InterpreterFrame *frame = _PyEvalFramePushAndInit(
|
||||||
tstate, con, locals, args, argcount, kwnames, 0);
|
tstate, con, locals, args, argcount, kwnames);
|
||||||
if (frame == NULL) {
|
if (frame == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2065,12 +2065,8 @@ push_chunk(PyThreadState *tstate, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
InterpreterFrame *
|
InterpreterFrame *
|
||||||
_PyThreadState_PushFrame(PyThreadState *tstate, PyFrameConstructor *con, PyObject *locals)
|
_PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size)
|
||||||
{
|
{
|
||||||
PyCodeObject *code = (PyCodeObject *)con->fc_code;
|
|
||||||
int nlocalsplus = code->co_nlocalsplus;
|
|
||||||
size_t size = nlocalsplus + code->co_stacksize +
|
|
||||||
FRAME_SPECIALS_SIZE;
|
|
||||||
assert(size < INT_MAX/sizeof(PyObject *));
|
assert(size < INT_MAX/sizeof(PyObject *));
|
||||||
PyObject **base = tstate->datastack_top;
|
PyObject **base = tstate->datastack_top;
|
||||||
PyObject **top = base + size;
|
PyObject **top = base + size;
|
||||||
|
|
@ -2083,7 +2079,21 @@ _PyThreadState_PushFrame(PyThreadState *tstate, PyFrameConstructor *con, PyObjec
|
||||||
else {
|
else {
|
||||||
tstate->datastack_top = top;
|
tstate->datastack_top = top;
|
||||||
}
|
}
|
||||||
InterpreterFrame *frame = (InterpreterFrame *)base;
|
return (InterpreterFrame *)base;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InterpreterFrame *
|
||||||
|
_PyThreadState_PushFrame(PyThreadState *tstate, PyFrameConstructor *con, PyObject *locals)
|
||||||
|
{
|
||||||
|
PyCodeObject *code = (PyCodeObject *)con->fc_code;
|
||||||
|
int nlocalsplus = code->co_nlocalsplus;
|
||||||
|
size_t size = nlocalsplus + code->co_stacksize +
|
||||||
|
FRAME_SPECIALS_SIZE;
|
||||||
|
InterpreterFrame *frame = _PyThreadState_BumpFramePointer(tstate, size);
|
||||||
|
if (frame == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
_PyFrame_InitializeSpecials(frame, con, locals, nlocalsplus);
|
_PyFrame_InitializeSpecials(frame, con, locals, nlocalsplus);
|
||||||
for (int i=0; i < nlocalsplus; i++) {
|
for (int i=0; i < nlocalsplus; i++) {
|
||||||
frame->localsplus[i] = NULL;
|
frame->localsplus[i] = NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue