blob: ae962e995869807e8d369e3471b2454324e50d9e [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum3f5da241990-12-20 15:06:42 +000032/* Frame object implementation */
33
34#include "allobjects.h"
35
36#include "compile.h"
37#include "frameobject.h"
38#include "opcode.h"
39#include "structmember.h"
Guido van Rossumc1134821995-01-10 10:39:16 +000040#include "bltinmodule.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000041
42#define OFF(x) offsetof(frameobject, x)
43
44static struct memberlist frame_memberlist[] = {
Guido van Rossum1d5735e1994-08-30 08:27:36 +000045 {"f_back", T_OBJECT, OFF(f_back), RO},
46 {"f_code", T_OBJECT, OFF(f_code), RO},
Guido van Rossumc1134821995-01-10 10:39:16 +000047 {"f_builtins", T_OBJECT, OFF(f_builtins),RO},
Guido van Rossum1d5735e1994-08-30 08:27:36 +000048 {"f_globals", T_OBJECT, OFF(f_globals), RO},
49 {"f_locals", T_OBJECT, OFF(f_locals), RO},
Guido van Rossum1d5735e1994-08-30 08:27:36 +000050 {"f_lasti", T_INT, OFF(f_lasti), RO},
51 {"f_lineno", T_INT, OFF(f_lineno), RO},
Guido van Rossumc1134821995-01-10 10:39:16 +000052 {"f_restricted",T_INT, OFF(f_restricted),RO},
Guido van Rossum1d5735e1994-08-30 08:27:36 +000053 {"f_trace", T_OBJECT, OFF(f_trace)},
Guido van Rossum3f5da241990-12-20 15:06:42 +000054 {NULL} /* Sentinel */
55};
56
57static object *
58frame_getattr(f, name)
59 frameobject *f;
60 char *name;
61{
Guido van Rossum1d5735e1994-08-30 08:27:36 +000062 if (strcmp(name, "f_locals") == 0)
63 fast_2_locals(f);
Guido van Rossum3f5da241990-12-20 15:06:42 +000064 return getmember((char *)f, frame_memberlist, name);
65}
66
Guido van Rossum1d5735e1994-08-30 08:27:36 +000067static int
68frame_setattr(f, name, value)
69 frameobject *f;
70 char *name;
71 object *value;
72{
73 return setmember((char *)f, frame_memberlist, name, value);
74}
75
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000076/* Stack frames are allocated and deallocated at a considerable rate.
77 In an attempt to improve the speed of function calls, we maintain a
78 separate free list of stack frames (just like integers are
79 allocated in a special way -- see intobject.c). When a stack frame
80 is on the free list, only the following members have a meaning:
81 ob_type == &Frametype
82 f_back next item on free list, or NULL
Guido van Rossumf3e85a01997-01-20 04:20:52 +000083 f_nlocals number of locals
84 f_stacksize size of value stack
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000085 Note that the value and block stacks are preserved -- this can save
86 another malloc() call or two (and two free() calls as well!).
87 Also note that, unlike for integers, each frame object is a
88 malloc'ed object in its own right -- it is only the actual calls to
89 malloc() that we are trying to save here, not the administration.
90 After all, while a typical program may make millions of calls, a
91 call depth of more than 20 or 30 is probably already exceptional
92 unless the program contains run-away recursion. I hope.
93*/
94
95static frameobject *free_list = NULL;
96
Guido van Rossum3f5da241990-12-20 15:06:42 +000097static void
98frame_dealloc(f)
99 frameobject *f;
100{
101 XDECREF(f->f_back);
102 XDECREF(f->f_code);
Guido van Rossumc1134821995-01-10 10:39:16 +0000103 XDECREF(f->f_builtins);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000104 XDECREF(f->f_globals);
105 XDECREF(f->f_locals);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000106 XDECREF(f->f_trace);
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000107 f->f_back = free_list;
108 free_list = f;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000109}
110
111typeobject Frametype = {
112 OB_HEAD_INIT(&Typetype)
113 0,
114 "frame",
115 sizeof(frameobject),
116 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000117 (destructor)frame_dealloc, /*tp_dealloc*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000118 0, /*tp_print*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000119 (getattrfunc)frame_getattr, /*tp_getattr*/
120 (setattrfunc)frame_setattr, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000121 0, /*tp_compare*/
122 0, /*tp_repr*/
123 0, /*tp_as_number*/
124 0, /*tp_as_sequence*/
125 0, /*tp_as_mapping*/
126};
127
128frameobject *
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000129newframeobject(back, code, globals, locals)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000130 frameobject *back;
131 codeobject *code;
132 object *globals;
133 object *locals;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000134{
Sjoerd Mullender5b7f3cd1995-04-04 11:47:41 +0000135 static object *builtin_object;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000136 frameobject *f;
Guido van Rossumc1134821995-01-10 10:39:16 +0000137 object *builtins;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000138 int extras = code->co_stacksize + code->co_nlocals;
139
Sjoerd Mullender5b7f3cd1995-04-04 11:47:41 +0000140 if (builtin_object == NULL) {
Guido van Rossumb56933e1997-01-18 07:58:41 +0000141 builtin_object = PyString_InternFromString("__builtins__");
Sjoerd Mullender5b7f3cd1995-04-04 11:47:41 +0000142 if (builtin_object == NULL)
143 return NULL;
144 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000145 if ((back != NULL && !is_frameobject(back)) ||
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000146 code == NULL || !is_codeobject(code) ||
147 globals == NULL || !is_dictobject(globals) ||
148 (locals != NULL && !is_dictobject(locals))) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000149 err_badcall();
150 return NULL;
151 }
Sjoerd Mullender5b7f3cd1995-04-04 11:47:41 +0000152 builtins = mappinglookup(globals, builtin_object);
Guido van Rossumb4e7e251995-01-17 16:27:25 +0000153 if (builtins != NULL && is_moduleobject(builtins))
154 builtins = getmoduledict(builtins);
Guido van Rossumc1134821995-01-10 10:39:16 +0000155 if (builtins == NULL || !is_mappingobject(builtins)) {
156 err_setstr(TypeError, "bad __builtins__ dictionary");
157 return NULL;
158 }
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000159 if (free_list == NULL) {
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000160 f = (frameobject *)
161 malloc(sizeof(frameobject) + extras*sizeof(object *));
Guido van Rossum2271bf71995-07-18 14:30:34 +0000162 if (f == NULL)
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000163 return (PyFrameObject *)err_nomem();
164 f->ob_type = &Frametype;
165 NEWREF(f);
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000166 }
167 else {
168 f = free_list;
169 free_list = free_list->f_back;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000170 if (f->f_nlocals + f->f_stacksize < extras) {
171 f = realloc(f, sizeof(frameobject) + extras*sizeof(object *));
172 if (f == NULL)
173 return (PyFrameObject *)err_nomem();
174 }
Guido van Rossum747596a1997-01-24 04:00:21 +0000175 else
176 extras = f->f_nlocals + f->f_stacksize;
Sjoerd Mullenderf64992e1993-08-03 15:11:36 +0000177 f->ob_type = &Frametype;
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000178 NEWREF(f);
179 }
Guido van Rossum2271bf71995-07-18 14:30:34 +0000180 XINCREF(back);
181 f->f_back = back;
182 INCREF(code);
183 f->f_code = code;
184 XINCREF(builtins);
185 f->f_builtins = builtins;
186 INCREF(globals);
187 f->f_globals = globals;
Guido van Rossumbdd207a1995-07-26 16:14:30 +0000188 if (code->co_flags & CO_NEWLOCALS) {
189 if (code->co_flags & CO_OPTIMIZED)
190 locals = NULL; /* Let fast_2_locals handle it */
191 else {
192 locals = newdictobject();
193 if (locals == NULL) {
194 DECREF(f);
195 return NULL;
196 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000197 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000198 }
Guido van Rossum2271bf71995-07-18 14:30:34 +0000199 else {
200 if (locals == NULL)
201 locals = globals;
202 INCREF(locals);
203 }
204 f->f_locals = locals;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000205 f->f_trace = NULL;
206
Guido van Rossum2271bf71995-07-18 14:30:34 +0000207 f->f_lasti = 0;
Guido van Rossum747596a1997-01-24 04:00:21 +0000208 f->f_lineno = code->co_firstlineno;
Guido van Rossum2271bf71995-07-18 14:30:34 +0000209 f->f_restricted = (builtins != getbuiltindict());
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000210 f->f_iblock = 0;
211 f->f_nlocals = code->co_nlocals;
Guido van Rossum747596a1997-01-24 04:00:21 +0000212 f->f_stacksize = extras - code->co_nlocals;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000213
214 while (--extras >= 0)
215 f->f_localsplus[extras] = NULL;
216
217 f->f_valuestack = f->f_localsplus + f->f_nlocals;
218
Guido van Rossum3f5da241990-12-20 15:06:42 +0000219 return f;
220}
221
Guido van Rossum3f5da241990-12-20 15:06:42 +0000222/* Block management */
223
224void
225setup_block(f, type, handler, level)
226 frameobject *f;
227 int type;
228 int handler;
229 int level;
230{
231 block *b;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000232 if (f->f_iblock >= CO_MAXBLOCKS)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000233 fatal("XXX block stack overflow");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000234 b = &f->f_blockstack[f->f_iblock++];
235 b->b_type = type;
236 b->b_level = level;
237 b->b_handler = handler;
238}
239
240block *
241pop_block(f)
242 frameobject *f;
243{
244 block *b;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000245 if (f->f_iblock <= 0)
246 fatal("XXX block stack underflow");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000247 b = &f->f_blockstack[--f->f_iblock];
248 return b;
249}
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000250
251/* Convert between "fast" version of locals and dictionary version */
252
253void
254fast_2_locals(f)
255 frameobject *f;
256{
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000257 /* Merge fast locals into f->f_locals */
258 object *locals, *map;
259 object **fast;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000260 object *error_type, *error_value, *error_traceback;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000261 int j;
262 if (f == NULL)
263 return;
Guido van Rossum2271bf71995-07-18 14:30:34 +0000264 locals = f->f_locals;
265 if (locals == NULL) {
266 locals = f->f_locals = newdictobject();
267 if (locals == NULL) {
268 err_clear(); /* Can't report it :-( */
269 return;
270 }
271 }
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000272 if (f->f_nlocals == 0)
Guido van Rossumbdd207a1995-07-26 16:14:30 +0000273 return;
274 map = f->f_code->co_varnames;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000275 if (!is_dictobject(locals) || !is_tupleobject(map))
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000276 return;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000277 err_fetch(&error_type, &error_value, &error_traceback);
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000278 fast = f->f_localsplus;
279 j = gettuplesize(map);
280 if (j > f->f_nlocals)
281 j = f->f_nlocals;
282 for (; --j >= 0; ) {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000283 object *key = gettupleitem(map, j);
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000284 object *value = fast[j];
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000285 if (value == NULL) {
286 err_clear();
287 if (dict2remove(locals, key) != 0)
288 err_clear();
289 }
290 else {
291 if (dict2insert(locals, key, value) != 0)
292 err_clear();
293 }
294 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000295 err_restore(error_type, error_value, error_traceback);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000296}
297
298void
299locals_2_fast(f, clear)
300 frameobject *f;
301 int clear;
302{
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000303 /* Merge f->f_locals into fast locals */
304 object *locals, *map;
305 object **fast;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000306 object *error_type, *error_value, *error_traceback;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000307 int j;
308 if (f == NULL)
309 return;
310 locals = f->f_locals;
Guido van Rossum2271bf71995-07-18 14:30:34 +0000311 map = f->f_code->co_varnames;
Guido van Rossum3bb63a81997-01-20 04:29:16 +0000312 if (locals == NULL || f->f_code->co_nlocals == 0)
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000313 return;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000314 if (!is_dictobject(locals) || !is_tupleobject(map))
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000315 return;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000316 err_fetch(&error_type, &error_value, &error_traceback);
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000317 fast = f->f_localsplus;
318 j = gettuplesize(map);
319 if (j > f->f_nlocals)
320 j = f->f_nlocals;
321 for (; --j >= 0; ) {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000322 object *key = gettupleitem(map, j);
323 object *value = dict2lookup(locals, key);
324 if (value == NULL)
325 err_clear();
326 else
327 INCREF(value);
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000328 if (value != NULL || clear) {
329 XDECREF(fast[j]);
330 XINCREF(value);
331 fast[j] = value;
332 }
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000333 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000334 err_restore(error_type, error_value, error_traceback);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000335}