diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-02 13:45:03 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-02 13:45:03 -0300 |
| commit | 15462edb0ff86bf1904011b29635420451cab2c5 (patch) | |
| tree | 9a626d34736b830f83fda3f1b2f3342990a05b1f /lfunc.c | |
| parent | 6f936bc7931662d0460d47ad73eca308ba5fab2f (diff) | |
| download | lua-15462edb0ff86bf1904011b29635420451cab2c5.tar.gz lua-15462edb0ff86bf1904011b29635420451cab2c5.tar.bz2 lua-15462edb0ff86bf1904011b29635420451cab2c5.zip | |
new definitions for closure structures
Diffstat (limited to 'lfunc.c')
| -rw-r--r-- | lfunc.c | 62 |
1 files changed, 29 insertions, 33 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 1.45 2001/06/28 14:57:17 roberto Exp $ | 2 | ** $Id: lfunc.c,v 1.47 2001/09/07 17:39:10 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 | */ |
| @@ -16,30 +16,29 @@ | |||
| 16 | #include "lstate.h" | 16 | #include "lstate.h" |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | #define sizeCclosure(n) (cast(int, sizeof(Closure)) + \ | 19 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ |
| 20 | cast(int, sizeof(TObject)*((n)-1))) | 20 | cast(int, sizeof(TObject)*((n)-1))) |
| 21 | 21 | ||
| 22 | #define sizeLclosure(n) (cast(int, sizeof(Closure)) + \ | 22 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ |
| 23 | cast(int, sizeof(TObject *)*((n)-1))) | 23 | cast(int, sizeof(LClosureEntry)*((n)-1))) |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | Closure *luaF_newCclosure (lua_State *L, int nelems) { | 26 | Closure *luaF_newCclosure (lua_State *L, int nelems) { |
| 27 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); | 27 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); |
| 28 | c->isC = 1; | 28 | c->c.isC = 1; |
| 29 | c->next = G(L)->rootcl; | 29 | c->c.next = G(L)->rootcl; |
| 30 | G(L)->rootcl = c; | 30 | G(L)->rootcl = c; |
| 31 | c->mark = c; | 31 | c->c.marked = 0; |
| 32 | c->nupvalues = nelems; | 32 | c->c.nupvalues = nelems; |
| 33 | return c; | 33 | return c; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | Closure *luaF_newLclosure (lua_State *L, int nelems) { | 37 | Closure *luaF_newLclosure (lua_State *L, int nelems) { |
| 38 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); | 38 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); |
| 39 | c->isC = 0; | 39 | c->l.isC = 0; |
| 40 | c->mark = c; | 40 | c->l.marked = 0; |
| 41 | c->u.l.isopen = 0; | 41 | c->l.nupvalues = nelems; |
| 42 | c->nupvalues = nelems; | ||
| 43 | return c; | 42 | return c; |
| 44 | } | 43 | } |
| 45 | 44 | ||
| @@ -47,42 +46,38 @@ Closure *luaF_newLclosure (lua_State *L, int nelems) { | |||
| 47 | /* | 46 | /* |
| 48 | ** returns the open pointer in a closure that points higher into the stack | 47 | ** returns the open pointer in a closure that points higher into the stack |
| 49 | */ | 48 | */ |
| 50 | static StkId uppoint (Closure *cl) { | 49 | static StkId uppoint (LClosure *cl) { |
| 51 | StkId lp = NULL; | 50 | StkId lp = NULL; |
| 52 | int i; | 51 | int i; |
| 53 | lua_assert(cl->u.l.isopen); | ||
| 54 | for (i=0; i<cl->nupvalues; i++) { | 52 | for (i=0; i<cl->nupvalues; i++) { |
| 55 | if (!luaF_isclosed(cl, i)) | 53 | if (cl->upvals[i].heap == NULL && (lp == NULL || cl->upvals[i].val > lp)) |
| 56 | if (lp == NULL || cl->u.l.upvals[i] > lp) | 54 | lp = cl->upvals[i].val; |
| 57 | lp = cl->u.l.upvals[i]; | ||
| 58 | } | 55 | } |
| 59 | lua_assert(lp != NULL); | ||
| 60 | return lp; | 56 | return lp; |
| 61 | } | 57 | } |
| 62 | 58 | ||
| 63 | 59 | ||
| 64 | void luaF_LConlist (lua_State *L, Closure *cl) { | 60 | void luaF_LConlist (lua_State *L, Closure *cl) { |
| 65 | lua_assert(!cl->isC); | 61 | StkId cli = uppoint(&cl->l); |
| 66 | if (cl->u.l.isopen == 0) { /* no more open entries? */ | 62 | if (cli == NULL) { /* no more open entries? */ |
| 67 | cl->next = G(L)->rootcl; /* insert in final list */ | 63 | cl->l.next = G(L)->rootcl; /* insert in final list */ |
| 68 | G(L)->rootcl = cl; | 64 | G(L)->rootcl = cl; |
| 69 | } | 65 | } |
| 70 | else { /* insert in list of open closures, ordered by decreasing uppoints */ | 66 | else { /* insert in list of open closures, ordered by decreasing uppoints */ |
| 71 | StkId cli = uppoint(cl); | ||
| 72 | Closure **p = &L->opencl; | 67 | Closure **p = &L->opencl; |
| 73 | while (*p != NULL && uppoint(*p) > cli) p = &(*p)->next; | 68 | while (*p != NULL && uppoint(&(*p)->l) > cli) p = &(*p)->l.next; |
| 74 | cl->next = *p; | 69 | cl->l.next = *p; |
| 75 | *p = cl; | 70 | *p = cl; |
| 76 | } | 71 | } |
| 77 | } | 72 | } |
| 78 | 73 | ||
| 79 | 74 | ||
| 80 | static int closeCl (lua_State *L, Closure *cl, StkId level) { | 75 | static int closeCl (lua_State *L, LClosure *cl, StkId level) { |
| 81 | int got = 0; /* flag: 1 if some pointer in the closure was corrected */ | 76 | int got = 0; /* flag: 1 if some pointer in the closure was corrected */ |
| 82 | int i; | 77 | int i; |
| 83 | for (i=0; i<cl->nupvalues; i++) { | 78 | for (i=0; i<cl->nupvalues; i++) { |
| 84 | StkId var; | 79 | StkId var; |
| 85 | if (!luaF_isclosed(cl, i) && (var=cl->u.l.upvals[i]) >= level) { | 80 | if (cl->upvals[i].heap == NULL && (var=cl->upvals[i].val) >= level) { |
| 86 | if (ttype(var) != LUA_TUPVAL) { | 81 | if (ttype(var) != LUA_TUPVAL) { |
| 87 | UpVal *v = luaM_new(L, UpVal); | 82 | UpVal *v = luaM_new(L, UpVal); |
| 88 | v->val = *var; | 83 | v->val = *var; |
| @@ -91,8 +86,8 @@ static int closeCl (lua_State *L, Closure *cl, StkId level) { | |||
| 91 | G(L)->rootupval = v; | 86 | G(L)->rootupval = v; |
| 92 | setupvalue(var, v); | 87 | setupvalue(var, v); |
| 93 | } | 88 | } |
| 94 | cl->u.l.upvals[i] = cast(TObject *, vvalue(var)); | 89 | cl->upvals[i].heap = vvalue(var); |
| 95 | luaF_closeentry(cl, i); | 90 | cl->upvals[i].val = &vvalue(var)->val; |
| 96 | got = 1; | 91 | got = 1; |
| 97 | } | 92 | } |
| 98 | } | 93 | } |
| @@ -104,15 +99,15 @@ void luaF_close (lua_State *L, StkId level) { | |||
| 104 | Closure *affected = NULL; /* closures with open pointers >= level */ | 99 | Closure *affected = NULL; /* closures with open pointers >= level */ |
| 105 | Closure *cl; | 100 | Closure *cl; |
| 106 | while ((cl=L->opencl) != NULL) { | 101 | while ((cl=L->opencl) != NULL) { |
| 107 | if (!closeCl(L, cl, level)) break; | 102 | if (!closeCl(L, cast(LClosure *, cl), level)) break; |
| 108 | /* some pointer in `cl' changed; will re-insert it in original list */ | 103 | /* some pointer in `cl' changed; will re-insert it in original list */ |
| 109 | L->opencl = cl->next; /* remove from original list */ | 104 | L->opencl = cl->l.next; /* remove from original list */ |
| 110 | cl->next = affected; | 105 | cl->l.next = affected; |
| 111 | affected = cl; /* insert in affected list */ | 106 | affected = cl; /* insert in affected list */ |
| 112 | } | 107 | } |
| 113 | /* re-insert all affected closures in original list */ | 108 | /* re-insert all affected closures in original list */ |
| 114 | while ((cl=affected) != NULL) { | 109 | while ((cl=affected) != NULL) { |
| 115 | affected = cl->next; | 110 | affected = cl->l.next; |
| 116 | luaF_LConlist(L, cl); | 111 | luaF_LConlist(L, cl); |
| 117 | } | 112 | } |
| 118 | } | 113 | } |
| @@ -154,7 +149,8 @@ void luaF_freeproto (lua_State *L, Proto *f) { | |||
| 154 | 149 | ||
| 155 | 150 | ||
| 156 | void luaF_freeclosure (lua_State *L, Closure *c) { | 151 | void luaF_freeclosure (lua_State *L, Closure *c) { |
| 157 | int size = (c->isC) ? sizeCclosure(c->nupvalues) : sizeLclosure(c->nupvalues); | 152 | int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : |
| 153 | sizeLclosure(c->l.nupvalues); | ||
| 158 | luaM_free(L, c, size); | 154 | luaM_free(L, c, size); |
| 159 | } | 155 | } |
| 160 | 156 | ||
