blob: ab36e6766750b8f04868d19a5b241f5d8ef4b4d1 [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{
Guido van Rossum7582bfb1997-02-14 16:27:29 +0000101 int i;
102 PyObject **fastlocals;
103
104 /* Kill all local variables */
105 fastlocals = f->f_localsplus;
106 for (i = f->f_nlocals; --i >= 0; ++fastlocals) {
107 XDECREF(*fastlocals);
108 }
109
Guido van Rossum3f5da241990-12-20 15:06:42 +0000110 XDECREF(f->f_back);
111 XDECREF(f->f_code);
Guido van Rossumc1134821995-01-10 10:39:16 +0000112 XDECREF(f->f_builtins);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000113 XDECREF(f->f_globals);
114 XDECREF(f->f_locals);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000115 XDECREF(f->f_trace);
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000116 f->f_back = free_list;
117 free_list = f;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000118}
119
120typeobject Frametype = {
121 OB_HEAD_INIT(&Typetype)
122 0,
123 "frame",
124 sizeof(frameobject),
125 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000126 (destructor)frame_dealloc, /*tp_dealloc*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000127 0, /*tp_print*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000128 (getattrfunc)frame_getattr, /*tp_getattr*/
129 (setattrfunc)frame_setattr, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000130 0, /*tp_compare*/
131 0, /*tp_repr*/
132 0, /*tp_as_number*/
133 0, /*tp_as_sequence*/
134 0, /*tp_as_mapping*/
135};
136
137frameobject *
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000138newframeobject(back, code, globals, locals)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000139 frameobject *back;
140 codeobject *code;
141 object *globals;
142 object *locals;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000143{
Sjoerd Mullender5b7f3cd1995-04-04 11:47:41 +0000144 static object *builtin_object;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000145 frameobject *f;
Guido van Rossumc1134821995-01-10 10:39:16 +0000146 object *builtins;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000147 int extras = code->co_stacksize + code->co_nlocals;
148
Sjoerd Mullender5b7f3cd1995-04-04 11:47:41 +0000149 if (builtin_object == NULL) {
Guido van Rossumb56933e1997-01-18 07:58:41 +0000150 builtin_object = PyString_InternFromString("__builtins__");
Sjoerd Mullender5b7f3cd1995-04-04 11:47:41 +0000151 if (builtin_object == NULL)
152 return NULL;
153 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000154 if ((back != NULL && !is_frameobject(back)) ||
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000155 code == NULL || !is_codeobject(code) ||
156 globals == NULL || !is_dictobject(globals) ||
157 (locals != NULL && !is_dictobject(locals))) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000158 err_badcall();
159 return NULL;
160 }
Sjoerd Mullender5b7f3cd1995-04-04 11:47:41 +0000161 builtins = mappinglookup(globals, builtin_object);
Guido van Rossumb4e7e251995-01-17 16:27:25 +0000162 if (builtins != NULL && is_moduleobject(builtins))
163 builtins = getmoduledict(builtins);
Guido van Rossumc1134821995-01-10 10:39:16 +0000164 if (builtins == NULL || !is_mappingobject(builtins)) {
165 err_setstr(TypeError, "bad __builtins__ dictionary");
166 return NULL;
167 }
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000168 if (free_list == NULL) {
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000169 f = (frameobject *)
170 malloc(sizeof(frameobject) + extras*sizeof(object *));
Guido van Rossum2271bf71995-07-18 14:30:34 +0000171 if (f == NULL)
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000172 return (PyFrameObject *)err_nomem();
173 f->ob_type = &Frametype;
174 NEWREF(f);
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000175 }
176 else {
177 f = free_list;
178 free_list = free_list->f_back;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000179 if (f->f_nlocals + f->f_stacksize < extras) {
Guido van Rossum7582bfb1997-02-14 16:27:29 +0000180 f = realloc(f, sizeof(frameobject) +
181 extras*sizeof(object *));
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000182 if (f == NULL)
183 return (PyFrameObject *)err_nomem();
184 }
Guido van Rossum747596a1997-01-24 04:00:21 +0000185 else
186 extras = f->f_nlocals + f->f_stacksize;
Sjoerd Mullenderf64992e1993-08-03 15:11:36 +0000187 f->ob_type = &Frametype;
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000188 NEWREF(f);
189 }
Guido van Rossum2271bf71995-07-18 14:30:34 +0000190 XINCREF(back);
191 f->f_back = back;
192 INCREF(code);
193 f->f_code = code;
194 XINCREF(builtins);
195 f->f_builtins = builtins;
196 INCREF(globals);
197 f->f_globals = globals;
Guido van Rossumbdd207a1995-07-26 16:14:30 +0000198 if (code->co_flags & CO_NEWLOCALS) {
199 if (code->co_flags & CO_OPTIMIZED)
200 locals = NULL; /* Let fast_2_locals handle it */
201 else {
202 locals = newdictobject();
203 if (locals == NULL) {
204 DECREF(f);
205 return NULL;
206 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000207 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000208 }
Guido van Rossum2271bf71995-07-18 14:30:34 +0000209 else {
210 if (locals == NULL)
211 locals = globals;
212 INCREF(locals);
213 }
214 f->f_locals = locals;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000215 f->f_trace = NULL;
216
Guido van Rossum2271bf71995-07-18 14:30:34 +0000217 f->f_lasti = 0;
Guido van Rossum747596a1997-01-24 04:00:21 +0000218 f->f_lineno = code->co_firstlineno;
Guido van Rossum2271bf71995-07-18 14:30:34 +0000219 f->f_restricted = (builtins != getbuiltindict());
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000220 f->f_iblock = 0;
221 f->f_nlocals = code->co_nlocals;
Guido van Rossum747596a1997-01-24 04:00:21 +0000222 f->f_stacksize = extras - code->co_nlocals;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000223
224 while (--extras >= 0)
225 f->f_localsplus[extras] = NULL;
226
227 f->f_valuestack = f->f_localsplus + f->f_nlocals;
228
Guido van Rossum3f5da241990-12-20 15:06:42 +0000229 return f;
230}
231
Guido van Rossum3f5da241990-12-20 15:06:42 +0000232/* Block management */
233
234void
235setup_block(f, type, handler, level)
236 frameobject *f;
237 int type;
238 int handler;
239 int level;
240{
241 block *b;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000242 if (f->f_iblock >= CO_MAXBLOCKS)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000243 fatal("XXX block stack overflow");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000244 b = &f->f_blockstack[f->f_iblock++];
245 b->b_type = type;
246 b->b_level = level;
247 b->b_handler = handler;
248}
249
250block *
251pop_block(f)
252 frameobject *f;
253{
254 block *b;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000255 if (f->f_iblock <= 0)
256 fatal("XXX block stack underflow");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000257 b = &f->f_blockstack[--f->f_iblock];
258 return b;
259}
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000260
261/* Convert between "fast" version of locals and dictionary version */
262
263void
264fast_2_locals(f)
265 frameobject *f;
266{
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000267 /* Merge fast locals into f->f_locals */
268 object *locals, *map;
269 object **fast;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000270 object *error_type, *error_value, *error_traceback;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000271 int j;
272 if (f == NULL)
273 return;
Guido van Rossum2271bf71995-07-18 14:30:34 +0000274 locals = f->f_locals;
275 if (locals == NULL) {
276 locals = f->f_locals = newdictobject();
277 if (locals == NULL) {
278 err_clear(); /* Can't report it :-( */
279 return;
280 }
281 }
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000282 if (f->f_nlocals == 0)
Guido van Rossumbdd207a1995-07-26 16:14:30 +0000283 return;
284 map = f->f_code->co_varnames;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000285 if (!is_dictobject(locals) || !is_tupleobject(map))
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000286 return;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000287 err_fetch(&error_type, &error_value, &error_traceback);
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000288 fast = f->f_localsplus;
289 j = gettuplesize(map);
290 if (j > f->f_nlocals)
291 j = f->f_nlocals;
292 for (; --j >= 0; ) {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000293 object *key = gettupleitem(map, j);
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000294 object *value = fast[j];
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000295 if (value == NULL) {
296 err_clear();
297 if (dict2remove(locals, key) != 0)
298 err_clear();
299 }
300 else {
301 if (dict2insert(locals, key, value) != 0)
302 err_clear();
303 }
304 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000305 err_restore(error_type, error_value, error_traceback);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000306}
307
308void
309locals_2_fast(f, clear)
310 frameobject *f;
311 int clear;
312{
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000313 /* Merge f->f_locals into fast locals */
314 object *locals, *map;
315 object **fast;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000316 object *error_type, *error_value, *error_traceback;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000317 int j;
318 if (f == NULL)
319 return;
320 locals = f->f_locals;
Guido van Rossum2271bf71995-07-18 14:30:34 +0000321 map = f->f_code->co_varnames;
Guido van Rossum3bb63a81997-01-20 04:29:16 +0000322 if (locals == NULL || f->f_code->co_nlocals == 0)
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000323 return;
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000324 if (!is_dictobject(locals) || !is_tupleobject(map))
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000325 return;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000326 err_fetch(&error_type, &error_value, &error_traceback);
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000327 fast = f->f_localsplus;
328 j = gettuplesize(map);
329 if (j > f->f_nlocals)
330 j = f->f_nlocals;
331 for (; --j >= 0; ) {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000332 object *key = gettupleitem(map, j);
333 object *value = dict2lookup(locals, key);
334 if (value == NULL)
335 err_clear();
336 else
337 INCREF(value);
Guido van Rossumf3e85a01997-01-20 04:20:52 +0000338 if (value != NULL || clear) {
339 XDECREF(fast[j]);
340 XINCREF(value);
341 fast[j] = value;
342 }
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000343 }
Guido van Rossumd7047b31995-01-02 19:07:15 +0000344 err_restore(error_type, error_value, error_traceback);
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000345}