diff options
Diffstat (limited to 'Objects/frameobject.c')
-rw-r--r-- | Objects/frameobject.c | 142 |
1 files changed, 55 insertions, 87 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 546f1e8..2814455 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -47,10 +47,6 @@ static struct memberlist frame_memberlist[] = { {"f_builtins", T_OBJECT, OFF(f_builtins),RO}, {"f_globals", T_OBJECT, OFF(f_globals), RO}, {"f_locals", T_OBJECT, OFF(f_locals), RO}, - {"f_owner", T_OBJECT, OFF(f_owner), RO}, -#if 0 - {"f_fastlocals",T_OBJECT, OFF(f_fastlocals),RO}, /* XXX Unsafe */ -#endif {"f_lasti", T_INT, OFF(f_lasti), RO}, {"f_lineno", T_INT, OFF(f_lineno), RO}, {"f_restricted",T_INT, OFF(f_restricted),RO}, @@ -84,10 +80,8 @@ frame_setattr(f, name, value) is on the free list, only the following members have a meaning: ob_type == &Frametype f_back next item on free list, or NULL - f_nvalues size of f_valuestack - f_valuestack array of (f_nvalues+1) object pointers, or NULL - f_nblocks size of f_blockstack - f_blockstack array of (f_nblocks+1) blocks, or NULL + f_nlocals number of locals + f_stacksize size of value stack Note that the value and block stacks are preserved -- this can save another malloc() call or two (and two free() calls as well!). Also note that, unlike for integers, each frame object is a @@ -109,8 +103,6 @@ frame_dealloc(f) XDECREF(f->f_builtins); XDECREF(f->f_globals); XDECREF(f->f_locals); - XDECREF(f->f_owner); - XDECREF(f->f_fastlocals); XDECREF(f->f_trace); f->f_back = free_list; free_list = f; @@ -134,28 +126,26 @@ typeobject Frametype = { }; frameobject * -newframeobject(back, code, globals, locals, owner, nvalues, nblocks) +newframeobject(back, code, globals, locals) frameobject *back; codeobject *code; object *globals; object *locals; - object *owner; - int nvalues; - int nblocks; { static object *builtin_object; frameobject *f; object *builtins; + int extras = code->co_stacksize + code->co_nlocals; + if (builtin_object == NULL) { builtin_object = PyString_InternFromString("__builtins__"); if (builtin_object == NULL) return NULL; } if ((back != NULL && !is_frameobject(back)) || - code == NULL || !is_codeobject(code) || - globals == NULL || !is_dictobject(globals) || - (locals != NULL && !is_dictobject(locals)) || - nvalues < 0 || nblocks < 0) { + code == NULL || !is_codeobject(code) || + globals == NULL || !is_dictobject(globals) || + (locals != NULL && !is_dictobject(locals))) { err_badcall(); return NULL; } @@ -167,16 +157,21 @@ newframeobject(back, code, globals, locals, owner, nvalues, nblocks) return NULL; } if (free_list == NULL) { - f = NEWOBJ(frameobject, &Frametype); + f = (frameobject *) + malloc(sizeof(frameobject) + extras*sizeof(object *)); if (f == NULL) - return NULL; - f->f_nvalues = f->f_nblocks = 0; - f->f_valuestack = NULL; - f->f_blockstack = NULL; + return (PyFrameObject *)err_nomem(); + f->ob_type = &Frametype; + NEWREF(f); } else { f = free_list; free_list = free_list->f_back; + if (f->f_nlocals + f->f_stacksize < extras) { + f = realloc(f, sizeof(frameobject) + extras*sizeof(object *)); + if (f == NULL) + return (PyFrameObject *)err_nomem(); + } f->ob_type = &Frametype; NEWREF(f); } @@ -205,57 +200,22 @@ newframeobject(back, code, globals, locals, owner, nvalues, nblocks) INCREF(locals); } f->f_locals = locals; - XINCREF(owner); - f->f_owner = owner; - f->f_fastlocals = NULL; - if (code->co_nlocals > 0) { - f->f_fastlocals = newlistobject(code->co_nlocals); - if (f->f_fastlocals == NULL) { - DECREF(f); - return NULL; - } - } - if (nvalues > f->f_nvalues || f->f_valuestack == NULL) { - XDEL(f->f_valuestack); - f->f_valuestack = NEW(object *, nvalues+1); - f->f_nvalues = nvalues; - } - if (nblocks > f->f_nblocks || f->f_blockstack == NULL) { - XDEL(f->f_blockstack); - f->f_blockstack = NEW(block, nblocks+1); - f->f_nblocks = nblocks; - } - f->f_iblock = 0; + f->f_trace = NULL; + f->f_lasti = 0; f->f_lineno = -1; f->f_restricted = (builtins != getbuiltindict()); - f->f_trace = NULL; - if (f->f_valuestack == NULL || f->f_blockstack == NULL) { - err_nomem(); - DECREF(f); - return NULL; - } - return f; -} + f->f_iblock = 0; + f->f_nlocals = code->co_nlocals; + f->f_stacksize = code->co_stacksize; -#if 0 -object ** -extend_stack(f, level, incr) - frameobject *f; - int level; - int incr; -{ - f->f_nvalues = level + incr + 10; - f->f_valuestack = - (object **) realloc((ANY *)f->f_valuestack, - sizeof(object *) * (f->f_nvalues + 1)); - if (f->f_valuestack == NULL) { - err_nomem(); - return NULL; - } - return f->f_valuestack + level; + while (--extras >= 0) + f->f_localsplus[extras] = NULL; + + f->f_valuestack = f->f_localsplus + f->f_nlocals; + + return f; } -#endif /* Block management */ @@ -267,7 +227,7 @@ setup_block(f, type, handler, level) int level; { block *b; - if (f->f_iblock >= f->f_nblocks) + if (f->f_iblock >= CO_MAXBLOCKS) fatal("XXX block stack overflow"); b = &f->f_blockstack[f->f_iblock++]; b->b_type = type; @@ -292,8 +252,9 @@ void fast_2_locals(f) frameobject *f; { - /* Merge f->f_fastlocals into f->f_locals */ - object *locals, *fast, *map; + /* Merge fast locals into f->f_locals */ + object *locals, *map; + object **fast; object *error_type, *error_value, *error_traceback; int j; if (f == NULL) @@ -306,17 +267,19 @@ fast_2_locals(f) return; } } - fast = f->f_fastlocals; - if (fast == NULL || f->f_code->co_nlocals == 0) + if (f->f_nlocals == 0) return; map = f->f_code->co_varnames; - if (!is_dictobject(locals) || !is_listobject(fast) || - !is_tupleobject(map)) + if (!is_dictobject(locals) || !is_tupleobject(map)) return; err_fetch(&error_type, &error_value, &error_traceback); - for (j = gettuplesize(map); --j >= 0; ) { + fast = f->f_localsplus; + j = gettuplesize(map); + if (j > f->f_nlocals) + j = f->f_nlocals; + for (; --j >= 0; ) { object *key = gettupleitem(map, j); - object *value = getlistitem(fast, j); + object *value = fast[j]; if (value == NULL) { err_clear(); if (dict2remove(locals, key) != 0) @@ -335,31 +298,36 @@ locals_2_fast(f, clear) frameobject *f; int clear; { - /* Merge f->f_locals into f->f_fastlocals */ - object *locals, *fast, *map; + /* Merge f->f_locals into fast locals */ + object *locals, *map; + object **fast; object *error_type, *error_value, *error_traceback; int j; if (f == NULL) return; locals = f->f_locals; - fast = f->f_fastlocals; map = f->f_code->co_varnames; if (locals == NULL || fast == NULL || f->f_code->co_nlocals == 0) return; - if (!is_dictobject(locals) || !is_listobject(fast) || - !is_tupleobject(map)) + if (!is_dictobject(locals) || !is_tupleobject(map)) return; err_fetch(&error_type, &error_value, &error_traceback); - for (j = gettuplesize(map); --j >= 0; ) { + fast = f->f_localsplus; + j = gettuplesize(map); + if (j > f->f_nlocals) + j = f->f_nlocals; + for (; --j >= 0; ) { object *key = gettupleitem(map, j); object *value = dict2lookup(locals, key); if (value == NULL) err_clear(); else INCREF(value); - if (value != NULL || clear) - if (setlistitem(fast, j, value) != 0) - err_clear(); + if (value != NULL || clear) { + XDECREF(fast[j]); + XINCREF(value); + fast[j] = value; + } } err_restore(error_type, error_value, error_traceback); } |