11/***********************************************************
2- Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
2+ Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
33Amsterdam, The Netherlands.
44
55 All Rights Reserved
@@ -34,15 +34,16 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3434#define OFF (x ) offsetof(frameobject, x)
3535
3636static struct memberlist frame_memberlist [] = {
37- {"f_back" , T_OBJECT , OFF (f_back )},
38- {"f_code" , T_OBJECT , OFF (f_code )},
39- {"f_globals" , T_OBJECT , OFF (f_globals )},
40- {"f_locals" , T_OBJECT , OFF (f_locals )},
41- {"f_owner" , T_OBJECT , OFF (f_owner )},
42- /* {"f_fastlocals",T_OBJECT, OFF(f_fastlocals)}, /* XXX Unsafe */
43- {"f_localmap" , T_OBJECT , OFF (f_localmap )},
44- {"f_lasti" , T_INT , OFF (f_lasti )},
45- {"f_lineno" , T_INT , OFF (f_lineno )},
37+ {"f_back" , T_OBJECT , OFF (f_back ), RO },
38+ {"f_code" , T_OBJECT , OFF (f_code ), RO },
39+ {"f_globals" , T_OBJECT , OFF (f_globals ), RO },
40+ {"f_locals" , T_OBJECT , OFF (f_locals ), RO },
41+ {"f_owner" , T_OBJECT , OFF (f_owner ), RO },
42+ /* {"f_fastlocals",T_OBJECT, OFF(f_fastlocals),RO}, /* XXX Unsafe */
43+ {"f_localmap" , T_OBJECT , OFF (f_localmap ),RO },
44+ {"f_lasti" , T_INT , OFF (f_lasti ), RO },
45+ {"f_lineno" , T_INT , OFF (f_lineno ), RO },
46+ {"f_trace" , T_OBJECT , OFF (f_trace )},
4647 {NULL } /* Sentinel */
4748};
4849
@@ -51,9 +52,20 @@ frame_getattr(f, name)
5152 frameobject * f ;
5253 char * name ;
5354{
55+ if (strcmp (name , "f_locals" ) == 0 )
56+ fast_2_locals (f );
5457 return getmember ((char * )f , frame_memberlist , name );
5558}
5659
60+ static int
61+ frame_setattr (f , name , value )
62+ frameobject * f ;
63+ char * name ;
64+ object * value ;
65+ {
66+ return setmember ((char * )f , frame_memberlist , name , value );
67+ }
68+
5769/* Stack frames are allocated and deallocated at a considerable rate.
5870 In an attempt to improve the speed of function calls, we maintain a
5971 separate free list of stack frames (just like integers are
@@ -88,6 +100,7 @@ frame_dealloc(f)
88100 XDECREF (f -> f_owner );
89101 XDECREF (f -> f_fastlocals );
90102 XDECREF (f -> f_localmap );
103+ XDECREF (f -> f_trace );
91104 f -> f_back = free_list ;
92105 free_list = f ;
93106}
@@ -98,10 +111,10 @@ typeobject Frametype = {
98111 "frame" ,
99112 sizeof (frameobject ),
100113 0 ,
101- frame_dealloc , /*tp_dealloc*/
114+ ( destructor ) frame_dealloc , /*tp_dealloc*/
102115 0 , /*tp_print*/
103- frame_getattr , /*tp_getattr*/
104- 0 , /*tp_setattr*/
116+ ( getattrfunc ) frame_getattr , /*tp_getattr*/
117+ ( setattrfunc ) frame_setattr , /*tp_setattr*/
105118 0 , /*tp_compare*/
106119 0 , /*tp_repr*/
107120 0 , /*tp_as_number*/
@@ -167,6 +180,7 @@ newframeobject(back, code, globals, locals, owner, nvalues, nblocks)
167180 f -> f_iblock = 0 ;
168181 f -> f_lasti = 0 ;
169182 f -> f_lineno = -1 ;
183+ f -> f_trace = NULL ;
170184 if (f -> f_valuestack == NULL || f -> f_blockstack == NULL ) {
171185 err_nomem ();
172186 DECREF (f );
@@ -225,3 +239,74 @@ pop_block(f)
225239 b = & f -> f_blockstack [-- f -> f_iblock ];
226240 return b ;
227241}
242+
243+ /* Convert between "fast" version of locals and dictionary version */
244+
245+ void
246+ fast_2_locals (f )
247+ frameobject * f ;
248+ {
249+ /* Merge f->f_fastlocals into f->f_locals */
250+ object * locals , * fast , * map ;
251+ object * error_type , * error_value ;
252+ int j ;
253+ if (f == NULL )
254+ return ;
255+ locals = f -> f_locals ;
256+ fast = f -> f_fastlocals ;
257+ map = f -> f_localmap ;
258+ if (locals == NULL || fast == NULL || map == NULL )
259+ return ;
260+ if (!is_dictobject (locals ) || !is_listobject (fast ) ||
261+ !is_tupleobject (map ))
262+ return ;
263+ err_get (& error_type , & error_value );
264+ for (j = gettuplesize (map ); -- j >= 0 ; ) {
265+ object * key = gettupleitem (map , j );
266+ object * value = getlistitem (fast , j );
267+ if (value == NULL ) {
268+ err_clear ();
269+ if (dict2remove (locals , key ) != 0 )
270+ err_clear ();
271+ }
272+ else {
273+ if (dict2insert (locals , key , value ) != 0 )
274+ err_clear ();
275+ }
276+ }
277+ err_setval (error_type , error_value );
278+ }
279+
280+ void
281+ locals_2_fast (f , clear )
282+ frameobject * f ;
283+ int clear ;
284+ {
285+ /* Merge f->f_locals into f->f_fastlocals */
286+ object * locals , * fast , * map ;
287+ object * error_type , * error_value ;
288+ int j ;
289+ if (f == NULL )
290+ return ;
291+ locals = f -> f_locals ;
292+ fast = f -> f_fastlocals ;
293+ map = f -> f_localmap ;
294+ if (locals == NULL || fast == NULL || map == NULL )
295+ return ;
296+ if (!is_dictobject (locals ) || !is_listobject (fast ) ||
297+ !is_tupleobject (map ))
298+ return ;
299+ err_get (& error_type , & error_value );
300+ for (j = gettuplesize (map ); -- j >= 0 ; ) {
301+ object * key = gettupleitem (map , j );
302+ object * value = dict2lookup (locals , key );
303+ if (value == NULL )
304+ err_clear ();
305+ else
306+ INCREF (value );
307+ if (value != NULL || clear )
308+ if (setlistitem (fast , j , value ) != 0 )
309+ err_clear ();
310+ }
311+ err_setval (error_type , error_value );
312+ }
0 commit comments