aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-05 18:15:18 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-05 18:15:18 -0200
commit592a309177edc52847b1196969ad6d49ba21f4fb (patch)
tree06add977885c012ee22cc4f105785c435b6af353 /lvm.c
parent413fc7334bf8ceaea71417d73edef15c99d3a793 (diff)
downloadlua-592a309177edc52847b1196969ad6d49ba21f4fb.tar.gz
lua-592a309177edc52847b1196969ad6d49ba21f4fb.tar.bz2
lua-592a309177edc52847b1196969ad6d49ba21f4fb.zip
tag system replaced by event tables
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c137
1 files changed, 58 insertions, 79 deletions
diff --git a/lvm.c b/lvm.c
index c4281e44..ea1ba100 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.198 2001/11/06 21:41:53 roberto Exp $ 2** $Id: lvm.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -85,69 +85,66 @@ static void traceexec (lua_State *L, lua_Hook linehook) {
85/* maximum stack used by a call to a tag method (func + args) */ 85/* maximum stack used by a call to a tag method (func + args) */
86#define MAXSTACK_TM 4 86#define MAXSTACK_TM 4
87 87
88static StkId callTM (lua_State *L, Closure *f, const char *fmt, ...) { 88static void callTM (lua_State *L, const TObject *f,
89 va_list argp; 89 const TObject *p1, const TObject *p2, const TObject *p3, TObject *result ) {
90 StkId base = L->top; 90 StkId base = L->top;
91 lua_assert(strlen(fmt)+1 <= MAXSTACK_TM);
92 luaD_checkstack(L, MAXSTACK_TM); 91 luaD_checkstack(L, MAXSTACK_TM);
93 va_start(argp, fmt); 92 setobj(base, f); /* push function */
94 setclvalue(L->top, f); /* push function */ 93 setobj(base+1, p1); /* 1st argument */
95 L->top++; 94 setobj(base+2, p2); /* 2nd argument */
96 while (*fmt) { 95 L->top += 3;
97 if (*fmt++ == 'o') { 96 if (p3) {
98 setobj(L->top, va_arg(argp, TObject *)); 97 setobj(base+3, p3); /* 3th argument */
99 }
100 else {
101 lua_assert(*(fmt-1) == 's');
102 setsvalue(L->top, va_arg(argp, TString *));
103 }
104 L->top++; 98 L->top++;
105 } 99 }
106 luaD_call(L, base); 100 luaD_call(L, base);
107 va_end(argp); 101 if (result) { /* need a result? */
108 return base; 102 if (L->top == base) { /* are there valid results? */
109} 103 setnilvalue(result); /* function had no results */
110 104 }
111 105 else {
112#define setTM(L, base) (L->top = (base)) 106 setobj(result, base); /* get first result */
113 107 }
114static void setTMresult (lua_State *L, TObject *result, StkId base) {
115 if (L->top == base) { /* are there valid results? */
116 setnilvalue(result); /* function had no results */
117 }
118 else {
119 setobj(result, base); /* get first result */
120 } 108 }
121 L->top = base; /* restore top */ 109 L->top = base; /* restore top */
122} 110}
123 111
124 112
113
125/* 114/*
126** Function to index a table. 115** Function to index a table.
127** Receives the table at `t' and the key at the `key'. 116** Receives the table at `t' and the key at the `key'.
128** leaves the result at `res'. 117** leaves the result at `res'.
129*/ 118*/
130void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { 119void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
131 Closure *tm; 120 const TObject *tm;
121 init:
132 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ 122 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
133 int tg = hvalue(t)->htag; 123 Table *et = hvalue(t)->eventtable;
134 if (tg == LUA_TTABLE || /* with default tag? */ 124 if ((tm = fasttm(L, et, TM_GETTABLE)) == NULL) { /* no gettable TM? */
135 (tm = luaT_gettm(G(L), tg, TM_GETTABLE)) == NULL) { /* or no TM? */
136 const TObject *h = luaH_get(hvalue(t), key); /* do a primitive get */ 125 const TObject *h = luaH_get(hvalue(t), key); /* do a primitive get */
137 /* result is no nil or there is no `index' tag method? */ 126 /* result is no nil or there is no `index' tag method? */
138 if (ttype(h) != LUA_TNIL || /* no nil? */ 127 if (ttype(h) != LUA_TNIL || /* no nil? */
139 ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) { /* or no index TM? */ 128 (tm = fasttm(L, et, TM_INDEX)) == NULL) { /* or no index TM? */
140 setobj(res, h); /* default get */ 129 setobj(res, h); /* default get */
141 return; 130 return;
142 } 131 }
143 } 132 }
144 /* else will call the tag method */ 133 /* else will call the tag method */
145 } else { /* not a table; try a `gettable' tag method */ 134 } else { /* not a table; try a `gettable' tag method */
146 tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); 135 if (ttype(t) != LUA_TUSERDATA ||
147 if (tm == NULL) /* no tag method? */ 136 (tm = fasttm(L, uvalue(t)->uv.eventtable, TM_GETTABLE)) == NULL) {
148 luaG_typeerror(L, t, "index"); 137 luaG_typeerror(L, t, "index");
138 return; /* to avoid warnings */
139 }
140 }
141 lua_assert(tm != NULL);
142 if (ttype(tm) == LUA_TFUNCTION)
143 callTM(L, tm, t, key, NULL, res);
144 else {
145 t = tm;
146 goto init; /* return luaV_gettable(L, tm, key, res); */
149 } 147 }
150 setTMresult(L, res, callTM(L, tm, "oo", t, key));
151} 148}
152 149
153 150
@@ -156,63 +153,44 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
156** Receives table at `t', key at `key' and value at `val'. 153** Receives table at `t', key at `key' and value at `val'.
157*/ 154*/
158void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { 155void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
159 Closure *tm; 156 const TObject *tm;
157 init:
160 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ 158 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
161 int tg = hvalue(t)->htag; 159 Table *et = hvalue(t)->eventtable;
162 if (hvalue(t)->htag == LUA_TTABLE || /* with default tag? */ 160 if ((tm = fasttm(L, et, TM_SETTABLE)) == NULL) { /* no TM? */
163 (tm = luaT_gettm(G(L), tg, TM_SETTABLE)) == NULL) { /* or no TM? */
164 luaH_set(L, hvalue(t), key, val); /* do a primitive set */ 161 luaH_set(L, hvalue(t), key, val); /* do a primitive set */
165 return; 162 return;
166 } 163 }
167 /* else will call the tag method */ 164 /* else will call the tag method */
168 } else { /* not a table; try a `settable' tag method */ 165 } else { /* not a table; try a `settable' tag method */
169 tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); 166 if (ttype(t) != LUA_TUSERDATA ||
170 if (tm == NULL) /* no tag method? */ 167 (tm = fasttm(L, uvalue(t)->uv.eventtable, TM_SETTABLE)) == NULL) {
171 luaG_typeerror(L, t, "index"); 168 luaG_typeerror(L, t, "index");
169 return; /* to avoid warnings */
170 }
172 } 171 }
173 setTM(L, callTM(L, tm, "ooo", t, key, val)); 172 lua_assert(tm != NULL);
174} 173 if (ttype(tm) == LUA_TFUNCTION)
175 174 callTM(L, tm, t, key, val, NULL);
176 175 else {
177void luaV_getglobal (lua_State *L, TString *name, StkId res) { 176 t = tm;
178 const TObject *value = luaH_getstr(hvalue(&L->gt), name); 177 goto init; /* luaV_settable(L, tm, key, val); */
179 Closure *tm;
180 if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */
181 (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) {
182 setobj(res, value); /* default behavior */
183 }
184 else
185 setTMresult(L, res, callTM(L, tm, "so", name, value));
186}
187
188
189void luaV_setglobal (lua_State *L, TString *name, StkId val) {
190 const TObject *oldvalue = luaH_getstr(hvalue(&L->gt), name);
191 Closure *tm;
192 if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */
193 (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) {
194 if (oldvalue == &luaO_nilobject)
195 luaH_setstr(L, hvalue(&L->gt), name, val); /* raw set */
196 else
197 settableval(oldvalue, val); /* warning: tricky optimization! */
198 } 178 }
199 else
200 setTM(L, callTM(L, tm, "soo", name, oldvalue, val));
201} 179}
202 180
203 181
204static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, 182static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
205 TObject *res, TMS event) { 183 TObject *res, TMS event) {
206 Closure *tm = luaT_gettmbyObj(G(L), p1, event); /* try first operand */ 184 const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
207 if (tm == NULL) { 185 if (tm == NULL) {
208 tm = luaT_gettmbyObj(G(L), p2, event); /* try second operand */ 186 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
209 if (tm == NULL) { 187 if (tm == NULL) {
210 tm = luaT_gettm(G(L), 0, event); /* try a `global' method */ 188 tm = fasttm(L, hvalue(gt(L)), event);
211 if (tm == NULL) 189 if (tm == NULL) return 0; /* no tag method */
212 return 0; /* no tag method */
213 } 190 }
214 } 191 }
215 setTMresult(L, res, callTM(L, tm, "oo", p1, p2)); 192 if (ttype(tm) != LUA_TFUNCTION) return 0;
193 callTM(L, tm, p1, p2, NULL, res);
216 return 1; 194 return 1;
217} 195}
218 196
@@ -295,12 +273,13 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
295static void luaV_pack (lua_State *L, StkId firstelem) { 273static void luaV_pack (lua_State *L, StkId firstelem) {
296 int i; 274 int i;
297 Table *htab = luaH_new(L, 0, 0); 275 Table *htab = luaH_new(L, 0, 0);
298 TObject n; 276 TObject n, nname;
299 for (i=0; firstelem+i<L->top; i++) 277 for (i=0; firstelem+i<L->top; i++)
300 luaH_setnum(L, htab, i+1, firstelem+i); 278 luaH_setnum(L, htab, i+1, firstelem+i);
301 /* store counter in field `n' */ 279 /* store counter in field `n' */
302 setnvalue(&n, i); 280 setnvalue(&n, i);
303 luaH_setstr(L, htab, luaS_newliteral(L, "n"), &n); 281 setsvalue(&nname, luaS_newliteral(L, "n"));
282 luaH_set(L, htab, &nname, &n);
304 L->top = firstelem; /* remove elements from the stack */ 283 L->top = firstelem; /* remove elements from the stack */
305 sethvalue(L->top, htab); 284 sethvalue(L->top, htab);
306 incr_top; 285 incr_top;
@@ -395,7 +374,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
395 } 374 }
396 case OP_GETGLOBAL: { 375 case OP_GETGLOBAL: {
397 lua_assert(ttype(KBc(i)) == LUA_TSTRING); 376 lua_assert(ttype(KBc(i)) == LUA_TSTRING);
398 luaV_getglobal(L, tsvalue(KBc(i)), ra); 377 luaV_gettable(L, gt(L), KBc(i), ra);
399 break; 378 break;
400 } 379 }
401 case OP_GETTABLE: { 380 case OP_GETTABLE: {
@@ -404,7 +383,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
404 } 383 }
405 case OP_SETGLOBAL: { 384 case OP_SETGLOBAL: {
406 lua_assert(ttype(KBc(i)) == LUA_TSTRING); 385 lua_assert(ttype(KBc(i)) == LUA_TSTRING);
407 luaV_setglobal(L, tsvalue(KBc(i)), ra); 386 luaV_settable(L, gt(L), KBc(i), ra);
408 break; 387 break;
409 } 388 }
410 case OP_SETUPVAL: { 389 case OP_SETUPVAL: {