summaryrefslogtreecommitdiffstats
path: root/Objects/frameobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/frameobject.c')
-rw-r--r--Objects/frameobject.c85
1 files changed, 33 insertions, 52 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 4c5eaa2..45a275b 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -22,7 +22,6 @@ static PyMemberDef frame_memberlist[] = {
{NULL} /* Sentinel */
};
-
static struct _Py_frame_state *
get_frame_state(void)
{
@@ -816,54 +815,12 @@ frame_alloc(PyCodeObject *code)
}
-static inline PyObject *
-frame_get_builtins(PyFrameObject *back, PyObject *globals)
-{
- PyObject *builtins;
-
- if (back != NULL && back->f_globals == globals) {
- /* If we share the globals, we share the builtins.
- Save a lookup and a call. */
- builtins = back->f_builtins;
- assert(builtins != NULL);
- Py_INCREF(builtins);
- return builtins;
- }
-
- builtins = _PyDict_GetItemIdWithError(globals, &PyId___builtins__);
- if (builtins != NULL && PyModule_Check(builtins)) {
- builtins = PyModule_GetDict(builtins);
- assert(builtins != NULL);
- }
- if (builtins != NULL) {
- Py_INCREF(builtins);
- return builtins;
- }
-
- if (PyErr_Occurred()) {
- return NULL;
- }
-
- /* No builtins! Make up a minimal one.
- Give them 'None', at least. */
- builtins = PyDict_New();
- if (builtins == NULL) {
- return NULL;
- }
- if (PyDict_SetItemString(builtins, "None", Py_None) < 0) {
- Py_DECREF(builtins);
- return NULL;
- }
- return builtins;
-}
-
-
PyFrameObject* _Py_HOT_FUNCTION
_PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code,
- PyObject *globals, PyObject *locals)
+ PyObject *globals, PyObject *builtins, PyObject *locals)
{
#ifdef Py_DEBUG
- if (code == NULL || globals == NULL || !PyDict_Check(globals) ||
+ if (code == NULL || globals == NULL || builtins == NULL ||
(locals != NULL && !PyMapping_Check(locals))) {
PyErr_BadInternalCall();
return NULL;
@@ -871,18 +828,14 @@ _PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code,
#endif
PyFrameObject *back = tstate->frame;
- PyObject *builtins = frame_get_builtins(back, globals);
- if (builtins == NULL) {
- return NULL;
- }
PyFrameObject *f = frame_alloc(code);
if (f == NULL) {
- Py_DECREF(builtins);
return NULL;
}
f->f_stackdepth = 0;
+ Py_INCREF(builtins);
f->f_builtins = builtins;
Py_XINCREF(back);
f->f_back = back;
@@ -902,8 +855,9 @@ _PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code,
f->f_locals = locals;
}
else {
- if (locals == NULL)
+ if (locals == NULL) {
locals = globals;
+ }
Py_INCREF(locals);
f->f_locals = locals;
}
@@ -925,7 +879,9 @@ PyFrameObject*
PyFrame_New(PyThreadState *tstate, PyCodeObject *code,
PyObject *globals, PyObject *locals)
{
- PyFrameObject *f = _PyFrame_New_NoTrack(tstate, code, globals, locals);
+ PyObject *builtins = _PyEval_BuiltinsFromGlobals(globals);
+ PyFrameObject *f = _PyFrame_New_NoTrack(tstate, code, globals, builtins, locals);
+ Py_DECREF(builtins);
if (f)
_PyObject_GC_TRACK(f);
return f;
@@ -1223,3 +1179,28 @@ PyFrame_GetBack(PyFrameObject *frame)
Py_XINCREF(back);
return back;
}
+
+PyObject *_PyEval_BuiltinsFromGlobals(PyObject *globals) {
+ PyObject *builtins = _PyDict_GetItemIdWithError(globals, &PyId___builtins__);
+ if (builtins) {
+ if (PyModule_Check(builtins)) {
+ builtins = PyModule_GetDict(builtins);
+ assert(builtins != NULL);
+ }
+ }
+ if (builtins == NULL) {
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ /* No builtins! Make up a minimal one
+ Give them 'None', at least. */
+ builtins = PyDict_New();
+ if (builtins == NULL ||
+ PyDict_SetItemString(
+ builtins, "None", Py_None) < 0)
+ return NULL;
+ }
+ else
+ Py_INCREF(builtins);
+ return builtins;
+}