aboutsummaryrefslogtreecommitdiff
path: root/lfunc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-09-07 14:39:10 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-09-07 14:39:10 -0300
commitabdbe883a86bbc7fbf1d1bfc50756e1b42fc45b5 (patch)
tree051a7571c8acaf5451b5c9b7d67f1796a345c565 /lfunc.c
parent4d0935ec0ffed827aade5594216fae15bed7c6b5 (diff)
downloadlua-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.c100
1 files changed, 95 insertions, 5 deletions
diff --git a/lfunc.c b/lfunc.c
index cece5a1b..8c197499 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -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
22Closure *luaF_newclosure (lua_State *L, int nelems) { 25
23 Closure *c = cast(Closure *, luaM_malloc(L, sizeclosure(nelems))); 26Closure *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
37Closure *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*/
50static 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
64void 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
80static 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
103void 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
32Proto *luaF_newproto (lua_State *L) { 121Proto *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
67void luaF_freeclosure (lua_State *L, Closure *c) { 156void 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