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