aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-10-27 17:14:31 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-10-27 17:14:31 -0200
commit1e944de6cb6a20f6abeaab6f5d1039d06d8d2812 (patch)
treef2e49281dd7402b72e4409f4ef6a332886a2aa74 /lvm.c
parent275c150b17ffc621deb5f25ddb851ec942760c04 (diff)
downloadlua-1e944de6cb6a20f6abeaab6f5d1039d06d8d2812.tar.gz
lua-1e944de6cb6a20f6abeaab6f5d1039d06d8d2812.tar.bz2
lua-1e944de6cb6a20f6abeaab6f5d1039d06d8d2812.zip
towards a "stackless" call of metamethods (?)
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/lvm.c b/lvm.c
index e10763d6..a88f784d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.288 2003/07/07 13:37:56 roberto Exp roberto $ 2** $Id: lvm.c,v 1.289 2003/07/16 20:49:02 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -88,13 +88,17 @@ static void traceexec (lua_State *L, const Instruction *pc) {
88} 88}
89 89
90 90
91static void callTMres (lua_State *L, const TObject *f, 91static void prepTMcall (lua_State *L, const TObject *f,
92 const TObject *p1, const TObject *p2, StkId res) { 92 const TObject *p1, const TObject *p2) {
93 ptrdiff_t result = savestack(L, res);
94 setobj2s(L->top, f); /* push function */ 93 setobj2s(L->top, f); /* push function */
95 setobj2s(L->top+1, p1); /* 1st argument */ 94 setobj2s(L->top+1, p1); /* 1st argument */
96 setobj2s(L->top+2, p2); /* 2nd argument */ 95 setobj2s(L->top+2, p2); /* 2nd argument */
97 luaD_checkstack(L, 3); /* cannot check before (could invalidate p1, p2) */ 96}
97
98
99static void callTMres (lua_State *L, StkId res) {
100 ptrdiff_t result = savestack(L, res);
101 luaD_checkstack(L, 3);
98 L->top += 3; 102 L->top += 3;
99 luaD_call(L, L->top - 3, 1); 103 luaD_call(L, L->top - 3, 1);
100 res = restorestack(L, result); 104 res = restorestack(L, result);
@@ -104,13 +108,8 @@ static void callTMres (lua_State *L, const TObject *f,
104 108
105 109
106 110
107static void callTM (lua_State *L, const TObject *f, 111static void callTM (lua_State *L) {
108 const TObject *p1, const TObject *p2, const TObject *p3) { 112 luaD_checkstack(L, 4);
109 setobj2s(L->top, f); /* push function */
110 setobj2s(L->top+1, p1); /* 1st argument */
111 setobj2s(L->top+2, p2); /* 2nd argument */
112 setobj2s(L->top+3, p3); /* 3th argument */
113 luaD_checkstack(L, 4); /* cannot check before (could invalidate p1...p3) */
114 L->top += 4; 113 L->top += 4;
115 luaD_call(L, L->top - 4, 0); 114 luaD_call(L, L->top - 4, 0);
116} 115}
@@ -133,7 +132,8 @@ void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId val) {
133 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) 132 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
134 luaG_typeerror(L, t, "index"); 133 luaG_typeerror(L, t, "index");
135 if (ttisfunction(tm)) { 134 if (ttisfunction(tm)) {
136 callTMres(L, tm, t, key, val); 135 prepTMcall(L, tm, t, key);
136 callTMres(L, val);
137 return; 137 return;
138 } 138 }
139 t = tm; /* else repeat with `tm' */ 139 t = tm; /* else repeat with `tm' */
@@ -159,7 +159,9 @@ void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) {
159 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) 159 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
160 luaG_typeerror(L, t, "index"); 160 luaG_typeerror(L, t, "index");
161 if (ttisfunction(tm)) { 161 if (ttisfunction(tm)) {
162 callTM(L, tm, t, key, val); 162 prepTMcall(L, tm, t, key);
163 setobj2s(L->top+3, val); /* 3th argument */
164 callTM(L);
163 return; 165 return;
164 } 166 }
165 t = tm; /* else repeat with `tm' */ 167 t = tm; /* else repeat with `tm' */
@@ -174,7 +176,8 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
174 if (ttisnil(tm)) 176 if (ttisnil(tm))
175 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 177 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
176 if (!ttisfunction(tm)) return 0; 178 if (!ttisfunction(tm)) return 0;
177 callTMres(L, tm, p1, p2, res); 179 prepTMcall(L, tm, p1, p2);
180 callTMres(L, res);
178 return 1; 181 return 1;
179} 182}
180 183
@@ -201,7 +204,8 @@ static int call_orderTM (lua_State *L, const TObject *p1, const TObject *p2,
201 tm2 = luaT_gettmbyobj(L, p2, event); 204 tm2 = luaT_gettmbyobj(L, p2, event);
202 if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ 205 if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
203 return -1; 206 return -1;
204 callTMres(L, tm1, p1, p2, L->top); 207 prepTMcall(L, tm1, p1, p2);
208 callTMres(L, L->top);
205 return !l_isfalse(L->top); 209 return !l_isfalse(L->top);
206} 210}
207 211
@@ -280,7 +284,8 @@ int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) {
280 default: return gcvalue(t1) == gcvalue(t2); 284 default: return gcvalue(t1) == gcvalue(t2);
281 } 285 }
282 if (tm == NULL) return 0; /* no TM? */ 286 if (tm == NULL) return 0; /* no TM? */
283 callTMres(L, tm, t1, t2, L->top); /* call TM */ 287 prepTMcall(L, tm, t1, t2);
288 callTMres(L, L->top); /* call TM */
284 return !l_isfalse(L->top); 289 return !l_isfalse(L->top);
285} 290}
286 291
@@ -334,7 +339,8 @@ static StkId Arith (lua_State *L, StkId ra, const TObject *rb,
334 const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]); 339 const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]);
335 if (!ttisfunction(f)) 340 if (!ttisfunction(f))
336 luaG_runerror(L, "`__pow' (`^' operator) is not a function"); 341 luaG_runerror(L, "`__pow' (`^' operator) is not a function");
337 callTMres(L, f, b, c, ra); 342 prepTMcall(L, f, b, c);
343 callTMres(L, ra);
338 break; 344 break;
339 } 345 }
340 default: lua_assert(0); break; 346 default: lua_assert(0); break;