diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 55 |
1 files changed, 25 insertions, 30 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.76 2008/08/26 13:27:42 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.77 2008/09/09 13:53: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 | */ |
@@ -76,31 +76,24 @@ static void traceexec (lua_State *L) { | |||
76 | } | 76 | } |
77 | 77 | ||
78 | 78 | ||
79 | static void callTMres (lua_State *L, StkId res, const TValue *f, | ||
80 | const TValue *p1, const TValue *p2) { | ||
81 | ptrdiff_t result = savestack(L, res); | ||
82 | setobj2s(L, L->top, f); /* push function */ | ||
83 | setobj2s(L, L->top+1, p1); /* 1st argument */ | ||
84 | setobj2s(L, L->top+2, p2); /* 2nd argument */ | ||
85 | L->top += 3; | ||
86 | luaD_checkstack(L, 0); | ||
87 | luaD_call(L, L->top - 3, 1); | ||
88 | res = restorestack(L, result); | ||
89 | L->top--; | ||
90 | setobjs2s(L, res, L->top); | ||
91 | } | ||
92 | |||
93 | |||
94 | |||
95 | static void callTM (lua_State *L, const TValue *f, const TValue *p1, | 79 | static void callTM (lua_State *L, const TValue *f, const TValue *p1, |
96 | const TValue *p2, const TValue *p3) { | 80 | const TValue *p2, TValue *p3, int hasres) { |
97 | setobj2s(L, L->top, f); /* push function */ | 81 | ptrdiff_t result = savestack(L, p3); |
98 | setobj2s(L, L->top+1, p1); /* 1st argument */ | 82 | int oldbase = L->baseCcalls; |
99 | setobj2s(L, L->top+2, p2); /* 2nd argument */ | 83 | setobj2s(L, L->top++, f); /* push function */ |
100 | setobj2s(L, L->top+3, p3); /* 3th argument */ | 84 | setobj2s(L, L->top++, p1); /* 1st argument */ |
101 | L->top += 4; | 85 | setobj2s(L, L->top++, p2); /* 2nd argument */ |
86 | if (!hasres) /* no result? 'p3' is third argument */ | ||
87 | setobj2s(L, L->top++, p3); /* 3th argument */ | ||
102 | luaD_checkstack(L, 0); | 88 | luaD_checkstack(L, 0); |
103 | luaD_call(L, L->top - 4, 0); | 89 | if (isLua(L->ci)) /* metamethod invoked from a Lua function? */ |
90 | L->baseCcalls++; /* allow it to yield */ | ||
91 | luaD_call(L, L->top - (4 - hasres), hasres); | ||
92 | L->baseCcalls = oldbase; | ||
93 | if (hasres) { /* if has result, move it to its place */ | ||
94 | p3 = restorestack(L, result); | ||
95 | setobjs2s(L, p3, --L->top); | ||
96 | } | ||
104 | } | 97 | } |
105 | 98 | ||
106 | 99 | ||
@@ -121,7 +114,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
121 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) | 114 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) |
122 | luaG_typeerror(L, t, "index"); | 115 | luaG_typeerror(L, t, "index"); |
123 | if (ttisfunction(tm)) { | 116 | if (ttisfunction(tm)) { |
124 | callTMres(L, val, tm, t, key); | 117 | callTM(L, tm, t, key, val, 1); |
125 | return; | 118 | return; |
126 | } | 119 | } |
127 | t = tm; /* else repeat with `tm' */ | 120 | t = tm; /* else repeat with `tm' */ |
@@ -148,7 +141,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
148 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) | 141 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) |
149 | luaG_typeerror(L, t, "index"); | 142 | luaG_typeerror(L, t, "index"); |
150 | if (ttisfunction(tm)) { | 143 | if (ttisfunction(tm)) { |
151 | callTM(L, tm, t, key, val); | 144 | callTM(L, tm, t, key, val, 0); |
152 | return; | 145 | return; |
153 | } | 146 | } |
154 | t = tm; /* else repeat with `tm' */ | 147 | t = tm; /* else repeat with `tm' */ |
@@ -163,7 +156,7 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
163 | if (ttisnil(tm)) | 156 | if (ttisnil(tm)) |
164 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | 157 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
165 | if (ttisnil(tm)) return 0; | 158 | if (ttisnil(tm)) return 0; |
166 | callTMres(L, res, tm, p1, p2); | 159 | callTM(L, tm, p1, p2, res, 1); |
167 | return 1; | 160 | return 1; |
168 | } | 161 | } |
169 | 162 | ||
@@ -190,7 +183,7 @@ static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
190 | tm2 = luaT_gettmbyobj(L, p2, event); | 183 | tm2 = luaT_gettmbyobj(L, p2, event); |
191 | if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ | 184 | if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ |
192 | return -1; | 185 | return -1; |
193 | callTMres(L, L->top, tm1, p1, p2); | 186 | callTM(L, tm1, p1, p2, L->top, 1); |
194 | return !l_isfalse(L->top); | 187 | return !l_isfalse(L->top); |
195 | } | 188 | } |
196 | 189 | ||
@@ -268,7 +261,7 @@ int luaV_equalval_ (lua_State *L, const TValue *t1, const TValue *t2) { | |||
268 | default: return gcvalue(t1) == gcvalue(t2); | 261 | default: return gcvalue(t1) == gcvalue(t2); |
269 | } | 262 | } |
270 | if (tm == NULL) return 0; /* no TM? */ | 263 | if (tm == NULL) return 0; /* no TM? */ |
271 | callTMres(L, L->top, tm, t1, t2); /* call TM */ | 264 | callTM(L, tm, t1, t2, L->top, 1); /* call TM */ |
272 | return !l_isfalse(L->top); | 265 | return !l_isfalse(L->top); |
273 | } | 266 | } |
274 | 267 | ||
@@ -336,7 +329,7 @@ static void objlen (lua_State *L, StkId ra, const TValue *rb) { | |||
336 | break; | 329 | break; |
337 | } | 330 | } |
338 | } | 331 | } |
339 | callTMres(L, ra, tm, rb, luaO_nilobject); | 332 | callTM(L, tm, rb, luaO_nilobject, ra, 1); |
340 | } | 333 | } |
341 | 334 | ||
342 | 335 | ||
@@ -680,7 +673,9 @@ void luaV_execute (lua_State *L) { | |||
680 | setobjs2s(L, cb+1, ra+1); | 673 | setobjs2s(L, cb+1, ra+1); |
681 | setobjs2s(L, cb, ra); | 674 | setobjs2s(L, cb, ra); |
682 | L->top = cb+3; /* func. + 2 args (state and index) */ | 675 | L->top = cb+3; /* func. + 2 args (state and index) */ |
676 | L->baseCcalls++; | ||
683 | Protect(luaD_call(L, cb, GETARG_C(i))); | 677 | Protect(luaD_call(L, cb, GETARG_C(i))); |
678 | L->baseCcalls--; | ||
684 | L->top = L->ci->top; | 679 | L->top = L->ci->top; |
685 | cb = RA(i) + 3; /* previous call may change the stack */ | 680 | cb = RA(i) + 3; /* previous call may change the stack */ |
686 | if (!ttisnil(cb)) { /* continue loop? */ | 681 | if (!ttisnil(cb)) { /* continue loop? */ |