diff options
Diffstat (limited to 'lfunc.c')
-rw-r--r-- | lfunc.c | 38 |
1 files changed, 31 insertions, 7 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 2.4 2004/04/30 20:13:38 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 2.5 2004/11/24 19:20:21 roberto Exp $ |
3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -43,42 +43,66 @@ Closure *luaF_newLclosure (lua_State *L, int nelems, TValue *e) { | |||
43 | UpVal *luaF_newupval (lua_State *L) { | 43 | UpVal *luaF_newupval (lua_State *L) { |
44 | UpVal *uv = luaM_new(L, UpVal); | 44 | UpVal *uv = luaM_new(L, UpVal); |
45 | luaC_link(L, obj2gco(uv), LUA_TUPVAL); | 45 | luaC_link(L, obj2gco(uv), LUA_TUPVAL); |
46 | uv->v = &uv->value; | 46 | uv->v = &uv->u.value; |
47 | setnilvalue(uv->v); | 47 | setnilvalue(uv->v); |
48 | return uv; | 48 | return uv; |
49 | } | 49 | } |
50 | 50 | ||
51 | 51 | ||
52 | UpVal *luaF_findupval (lua_State *L, StkId level) { | 52 | UpVal *luaF_findupval (lua_State *L, StkId level) { |
53 | global_State *g = G(L); | ||
53 | GCObject **pp = &L->openupval; | 54 | GCObject **pp = &L->openupval; |
54 | UpVal *p; | 55 | UpVal *p; |
55 | UpVal *uv; | 56 | UpVal *uv; |
56 | while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { | 57 | while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { |
58 | lua_assert(p->v != &p->u.value); | ||
57 | if (p->v == level) return p; | 59 | if (p->v == level) return p; |
58 | pp = &p->next; | 60 | pp = &p->next; |
59 | } | 61 | } |
60 | uv = luaM_new(L, UpVal); /* not found: create a new one */ | 62 | uv = luaM_new(L, UpVal); /* not found: create a new one */ |
61 | uv->tt = LUA_TUPVAL; | 63 | uv->tt = LUA_TUPVAL; |
62 | uv->marked = luaC_white(G(L)); | 64 | uv->marked = luaC_white(g); |
63 | uv->v = level; /* current value lives in the stack */ | 65 | uv->v = level; /* current value lives in the stack */ |
64 | uv->next = *pp; /* chain it in the proper position */ | 66 | uv->next = *pp; /* chain it in the proper position */ |
65 | *pp = obj2gco(uv); | 67 | *pp = obj2gco(uv); |
68 | lua_assert(g->uvhead.u.l.next->u.l.prev == &g->uvhead && | ||
69 | g->uvhead.u.l.prev->u.l.next == &g->uvhead); | ||
70 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ | ||
71 | uv->u.l.next = g->uvhead.u.l.next; | ||
72 | uv->u.l.next->u.l.prev = uv; | ||
73 | g->uvhead.u.l.next = uv; | ||
74 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | ||
66 | return uv; | 75 | return uv; |
67 | } | 76 | } |
68 | 77 | ||
69 | 78 | ||
79 | static void unlinkupval (UpVal *uv) { | ||
80 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | ||
81 | uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ | ||
82 | uv->u.l.prev->u.l.next = uv->u.l.next; | ||
83 | } | ||
84 | |||
85 | |||
86 | void luaF_freeupval (lua_State *L, UpVal *uv) { | ||
87 | if (uv->v != &uv->u.value) /* is it open? */ | ||
88 | unlinkupval(uv); /* remove from open list */ | ||
89 | luaM_free(L, uv); /* free upvalue */ | ||
90 | } | ||
91 | |||
92 | |||
70 | void luaF_close (lua_State *L, StkId level) { | 93 | void luaF_close (lua_State *L, StkId level) { |
71 | UpVal *uv; | 94 | UpVal *uv; |
72 | global_State *g = G(L); | 95 | global_State *g = G(L); |
73 | while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) { | 96 | while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) { |
74 | GCObject *o = obj2gco(uv); | 97 | GCObject *o = obj2gco(uv); |
75 | lua_assert(!isblack(o)); | 98 | lua_assert(!isblack(o) && uv->v != &uv->u.value); |
76 | L->openupval = uv->next; /* remove from `open' list */ | 99 | L->openupval = uv->next; /* remove from `open' list */ |
77 | if (isdead(g, o)) | 100 | if (isdead(g, o)) |
78 | luaM_free(L, uv); /* free upvalue */ | 101 | luaF_freeupval(L, uv); /* free upvalue */ |
79 | else { | 102 | else { |
80 | setobj(L, &uv->value, uv->v); | 103 | unlinkupval(uv); |
81 | uv->v = &uv->value; /* now current value lives here */ | 104 | setobj(L, &uv->u.value, uv->v); |
105 | uv->v = &uv->u.value; /* now current value lives here */ | ||
82 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ | 106 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ |
83 | } | 107 | } |
84 | } | 108 | } |