@@ -47,10 +47,6 @@ static struct memberlist frame_memberlist[] = {
4747 {"f_builtins" , T_OBJECT , OFF (f_builtins ),RO },
4848 {"f_globals" , T_OBJECT , OFF (f_globals ), RO },
4949 {"f_locals" , T_OBJECT , OFF (f_locals ), RO },
50- {"f_owner" , T_OBJECT , OFF (f_owner ), RO },
51- #if 0
52- {"f_fastlocals" ,T_OBJECT , OFF (f_fastlocals ),RO }, /* XXX Unsafe */
53- #endif
5450 {"f_lasti" , T_INT , OFF (f_lasti ), RO },
5551 {"f_lineno" , T_INT , OFF (f_lineno ), RO },
5652 {"f_restricted" ,T_INT , OFF (f_restricted ),RO },
@@ -84,10 +80,8 @@ frame_setattr(f, name, value)
8480 is on the free list, only the following members have a meaning:
8581 ob_type == &Frametype
8682 f_back next item on free list, or NULL
87- f_nvalues size of f_valuestack
88- f_valuestack array of (f_nvalues+1) object pointers, or NULL
89- f_nblocks size of f_blockstack
90- f_blockstack array of (f_nblocks+1) blocks, or NULL
83+ f_nlocals number of locals
84+ f_stacksize size of value stack
9185 Note that the value and block stacks are preserved -- this can save
9286 another malloc() call or two (and two free() calls as well!).
9387 Also note that, unlike for integers, each frame object is a
@@ -109,8 +103,6 @@ frame_dealloc(f)
109103 XDECREF (f -> f_builtins );
110104 XDECREF (f -> f_globals );
111105 XDECREF (f -> f_locals );
112- XDECREF (f -> f_owner );
113- XDECREF (f -> f_fastlocals );
114106 XDECREF (f -> f_trace );
115107 f -> f_back = free_list ;
116108 free_list = f ;
@@ -134,28 +126,26 @@ typeobject Frametype = {
134126};
135127
136128frameobject *
137- newframeobject (back , code , globals , locals , owner , nvalues , nblocks )
129+ newframeobject (back , code , globals , locals )
138130 frameobject * back ;
139131 codeobject * code ;
140132 object * globals ;
141133 object * locals ;
142- object * owner ;
143- int nvalues ;
144- int nblocks ;
145134{
146135 static object * builtin_object ;
147136 frameobject * f ;
148137 object * builtins ;
138+ int extras = code -> co_stacksize + code -> co_nlocals ;
139+
149140 if (builtin_object == NULL ) {
150141 builtin_object = PyString_InternFromString ("__builtins__" );
151142 if (builtin_object == NULL )
152143 return NULL ;
153144 }
154145 if ((back != NULL && !is_frameobject (back )) ||
155- code == NULL || !is_codeobject (code ) ||
156- globals == NULL || !is_dictobject (globals ) ||
157- (locals != NULL && !is_dictobject (locals )) ||
158- nvalues < 0 || nblocks < 0 ) {
146+ code == NULL || !is_codeobject (code ) ||
147+ globals == NULL || !is_dictobject (globals ) ||
148+ (locals != NULL && !is_dictobject (locals ))) {
159149 err_badcall ();
160150 return NULL ;
161151 }
@@ -167,16 +157,21 @@ newframeobject(back, code, globals, locals, owner, nvalues, nblocks)
167157 return NULL ;
168158 }
169159 if (free_list == NULL ) {
170- f = NEWOBJ (frameobject , & Frametype );
160+ f = (frameobject * )
161+ malloc (sizeof (frameobject ) + extras * sizeof (object * ));
171162 if (f == NULL )
172- return NULL ;
173- f -> f_nvalues = f -> f_nblocks = 0 ;
174- f -> f_valuestack = NULL ;
175- f -> f_blockstack = NULL ;
163+ return (PyFrameObject * )err_nomem ();
164+ f -> ob_type = & Frametype ;
165+ NEWREF (f );
176166 }
177167 else {
178168 f = free_list ;
179169 free_list = free_list -> f_back ;
170+ 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+ }
180175 f -> ob_type = & Frametype ;
181176 NEWREF (f );
182177 }
@@ -205,57 +200,22 @@ newframeobject(back, code, globals, locals, owner, nvalues, nblocks)
205200 INCREF (locals );
206201 }
207202 f -> f_locals = locals ;
208- XINCREF (owner );
209- f -> f_owner = owner ;
210- f -> f_fastlocals = NULL ;
211- if (code -> co_nlocals > 0 ) {
212- f -> f_fastlocals = newlistobject (code -> co_nlocals );
213- if (f -> f_fastlocals == NULL ) {
214- DECREF (f );
215- return NULL ;
216- }
217- }
218- if (nvalues > f -> f_nvalues || f -> f_valuestack == NULL ) {
219- XDEL (f -> f_valuestack );
220- f -> f_valuestack = NEW (object * , nvalues + 1 );
221- f -> f_nvalues = nvalues ;
222- }
223- if (nblocks > f -> f_nblocks || f -> f_blockstack == NULL ) {
224- XDEL (f -> f_blockstack );
225- f -> f_blockstack = NEW (block , nblocks + 1 );
226- f -> f_nblocks = nblocks ;
227- }
228- f -> f_iblock = 0 ;
203+ f -> f_trace = NULL ;
204+
229205 f -> f_lasti = 0 ;
230206 f -> f_lineno = -1 ;
231207 f -> f_restricted = (builtins != getbuiltindict ());
232- f -> f_trace = NULL ;
233- if (f -> f_valuestack == NULL || f -> f_blockstack == NULL ) {
234- err_nomem ();
235- DECREF (f );
236- return NULL ;
237- }
238- return f ;
239- }
208+ f -> f_iblock = 0 ;
209+ f -> f_nlocals = code -> co_nlocals ;
210+ f -> f_stacksize = code -> co_stacksize ;
240211
241- #if 0
242- object * *
243- extend_stack (f , level , incr )
244- frameobject * f ;
245- int level ;
246- int incr ;
247- {
248- f -> f_nvalues = level + incr + 10 ;
249- f -> f_valuestack =
250- (object * * ) realloc ((ANY * )f -> f_valuestack ,
251- sizeof (object * ) * (f -> f_nvalues + 1 ));
252- if (f -> f_valuestack == NULL ) {
253- err_nomem ();
254- return NULL ;
255- }
256- return f -> f_valuestack + level ;
212+ while (-- extras >= 0 )
213+ f -> f_localsplus [extras ] = NULL ;
214+
215+ f -> f_valuestack = f -> f_localsplus + f -> f_nlocals ;
216+
217+ return f ;
257218}
258- #endif
259219
260220/* Block management */
261221
@@ -267,7 +227,7 @@ setup_block(f, type, handler, level)
267227 int level ;
268228{
269229 block * b ;
270- if (f -> f_iblock >= f -> f_nblocks )
230+ if (f -> f_iblock >= CO_MAXBLOCKS )
271231 fatal ("XXX block stack overflow" );
272232 b = & f -> f_blockstack [f -> f_iblock ++ ];
273233 b -> b_type = type ;
292252fast_2_locals (f )
293253 frameobject * f ;
294254{
295- /* Merge f->f_fastlocals into f->f_locals */
296- object * locals , * fast , * map ;
255+ /* Merge fast locals into f->f_locals */
256+ object * locals , * map ;
257+ object * * fast ;
297258 object * error_type , * error_value , * error_traceback ;
298259 int j ;
299260 if (f == NULL )
@@ -306,17 +267,19 @@ fast_2_locals(f)
306267 return ;
307268 }
308269 }
309- fast = f -> f_fastlocals ;
310- if (fast == NULL || f -> f_code -> co_nlocals == 0 )
270+ if (f -> f_nlocals == 0 )
311271 return ;
312272 map = f -> f_code -> co_varnames ;
313- if (!is_dictobject (locals ) || !is_listobject (fast ) ||
314- !is_tupleobject (map ))
273+ if (!is_dictobject (locals ) || !is_tupleobject (map ))
315274 return ;
316275 err_fetch (& error_type , & error_value , & error_traceback );
317- for (j = gettuplesize (map ); -- j >= 0 ; ) {
276+ fast = f -> f_localsplus ;
277+ j = gettuplesize (map );
278+ if (j > f -> f_nlocals )
279+ j = f -> f_nlocals ;
280+ for (; -- j >= 0 ; ) {
318281 object * key = gettupleitem (map , j );
319- object * value = getlistitem ( fast , j ) ;
282+ object * value = fast [ j ] ;
320283 if (value == NULL ) {
321284 err_clear ();
322285 if (dict2remove (locals , key ) != 0 )
@@ -335,31 +298,36 @@ locals_2_fast(f, clear)
335298 frameobject * f ;
336299 int clear ;
337300{
338- /* Merge f->f_locals into f->f_fastlocals */
339- object * locals , * fast , * map ;
301+ /* Merge f->f_locals into fast locals */
302+ object * locals , * map ;
303+ object * * fast ;
340304 object * error_type , * error_value , * error_traceback ;
341305 int j ;
342306 if (f == NULL )
343307 return ;
344308 locals = f -> f_locals ;
345- fast = f -> f_fastlocals ;
346309 map = f -> f_code -> co_varnames ;
347310 if (locals == NULL || fast == NULL || f -> f_code -> co_nlocals == 0 )
348311 return ;
349- if (!is_dictobject (locals ) || !is_listobject (fast ) ||
350- !is_tupleobject (map ))
312+ if (!is_dictobject (locals ) || !is_tupleobject (map ))
351313 return ;
352314 err_fetch (& error_type , & error_value , & error_traceback );
353- for (j = gettuplesize (map ); -- j >= 0 ; ) {
315+ fast = f -> f_localsplus ;
316+ j = gettuplesize (map );
317+ if (j > f -> f_nlocals )
318+ j = f -> f_nlocals ;
319+ for (; -- j >= 0 ; ) {
354320 object * key = gettupleitem (map , j );
355321 object * value = dict2lookup (locals , key );
356322 if (value == NULL )
357323 err_clear ();
358324 else
359325 INCREF (value );
360- if (value != NULL || clear )
361- if (setlistitem (fast , j , value ) != 0 )
362- err_clear ();
326+ if (value != NULL || clear ) {
327+ XDECREF (fast [j ]);
328+ XINCREF (value );
329+ fast [j ] = value ;
330+ }
363331 }
364332 err_restore (error_type , error_value , error_traceback );
365333}
0 commit comments