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 | ||