diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 49 |
1 files changed, 21 insertions, 28 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.35 2005/03/28 17:17:53 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.36 2005/04/04 18:12:51 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 | */ |
@@ -59,9 +59,8 @@ int luaV_tostring (lua_State *L, StkId obj) { | |||
59 | 59 | ||
60 | static void traceexec (lua_State *L, const Instruction *pc) { | 60 | static void traceexec (lua_State *L, const Instruction *pc) { |
61 | lu_byte mask = L->hookmask; | 61 | lu_byte mask = L->hookmask; |
62 | CallInfo *ci = L->ci; | 62 | const Instruction *oldpc = L->savedpc; |
63 | const Instruction *oldpc = ci->savedpc; | 63 | L->savedpc = pc; |
64 | ci->savedpc = pc; | ||
65 | if (mask > LUA_MASKLINE) { /* instruction-hook set? */ | 64 | if (mask > LUA_MASKLINE) { /* instruction-hook set? */ |
66 | if (L->hookcount == 0) { | 65 | if (L->hookcount == 0) { |
67 | resethookcount(L); | 66 | resethookcount(L); |
@@ -70,7 +69,7 @@ static void traceexec (lua_State *L, const Instruction *pc) { | |||
70 | } | 69 | } |
71 | } | 70 | } |
72 | if (mask & LUA_MASKLINE) { | 71 | if (mask & LUA_MASKLINE) { |
73 | Proto *p = ci_func(ci)->l.p; | 72 | Proto *p = ci_func(L->ci)->l.p; |
74 | int npc = pcRel(pc, p); | 73 | int npc = pcRel(pc, p); |
75 | int newline = getline(p, npc); | 74 | int newline = getline(p, npc); |
76 | /* call linehook when enter a new function, when jump back (loop), | 75 | /* call linehook when enter a new function, when jump back (loop), |
@@ -81,17 +80,13 @@ static void traceexec (lua_State *L, const Instruction *pc) { | |||
81 | } | 80 | } |
82 | 81 | ||
83 | 82 | ||
84 | static void prepTMcall (lua_State *L, const TValue *f, | 83 | static void callTMres (lua_State *L, StkId res, const TValue *f, |
85 | const TValue *p1, const TValue *p2) { | 84 | const TValue *p1, const TValue *p2) { |
85 | ptrdiff_t result = savestack(L, res); | ||
86 | luaD_checkstack(L, 3); | ||
86 | setobj2s(L, L->top, f); /* push function */ | 87 | setobj2s(L, L->top, f); /* push function */ |
87 | setobj2s(L, L->top+1, p1); /* 1st argument */ | 88 | setobj2s(L, L->top+1, p1); /* 1st argument */ |
88 | setobj2s(L, L->top+2, p2); /* 2nd argument */ | 89 | setobj2s(L, L->top+2, p2); /* 2nd argument */ |
89 | } | ||
90 | |||
91 | |||
92 | static void callTMres (lua_State *L, StkId res) { | ||
93 | ptrdiff_t result = savestack(L, res); | ||
94 | luaD_checkstack(L, 3); | ||
95 | L->top += 3; | 90 | L->top += 3; |
96 | luaD_call(L, L->top - 3, 1); | 91 | luaD_call(L, L->top - 3, 1); |
97 | res = restorestack(L, result); | 92 | res = restorestack(L, result); |
@@ -101,8 +96,12 @@ static void callTMres (lua_State *L, StkId res) { | |||
101 | 96 | ||
102 | 97 | ||
103 | 98 | ||
104 | static void callTM (lua_State *L) { | 99 | static void callTM (lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, const TValue *p3) { |
105 | luaD_checkstack(L, 4); | 100 | luaD_checkstack(L, 4); |
101 | setobj2s(L, L->top, f); /* push function */ | ||
102 | setobj2s(L, L->top+1, p1); /* 1st argument */ | ||
103 | setobj2s(L, L->top+2, p2); /* 2nd argument */ | ||
104 | setobj2s(L, L->top+3, p3); /* 3th argument */ | ||
106 | L->top += 4; | 105 | L->top += 4; |
107 | luaD_call(L, L->top - 4, 0); | 106 | luaD_call(L, L->top - 4, 0); |
108 | } | 107 | } |
@@ -125,8 +124,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
125 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) | 124 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) |
126 | luaG_typeerror(L, t, "index"); | 125 | luaG_typeerror(L, t, "index"); |
127 | if (ttisfunction(tm)) { | 126 | if (ttisfunction(tm)) { |
128 | prepTMcall(L, tm, t, key); | 127 | callTMres(L, val, tm, t, key); |
129 | callTMres(L, val); | ||
130 | return; | 128 | return; |
131 | } | 129 | } |
132 | t = tm; /* else repeat with `tm' */ | 130 | t = tm; /* else repeat with `tm' */ |
@@ -153,9 +151,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
153 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) | 151 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) |
154 | luaG_typeerror(L, t, "index"); | 152 | luaG_typeerror(L, t, "index"); |
155 | if (ttisfunction(tm)) { | 153 | if (ttisfunction(tm)) { |
156 | prepTMcall(L, tm, t, key); | 154 | callTM(L, tm, t, key, val); |
157 | setobj2s(L, L->top+3, val); /* 3th argument */ | ||
158 | callTM(L); | ||
159 | return; | 155 | return; |
160 | } | 156 | } |
161 | t = tm; /* else repeat with `tm' */ | 157 | t = tm; /* else repeat with `tm' */ |
@@ -170,8 +166,7 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
170 | if (ttisnil(tm)) | 166 | if (ttisnil(tm)) |
171 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | 167 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
172 | if (!ttisfunction(tm)) return 0; | 168 | if (!ttisfunction(tm)) return 0; |
173 | prepTMcall(L, tm, p1, p2); | 169 | callTMres(L, res, tm, p1, p2); |
174 | callTMres(L, res); | ||
175 | return 1; | 170 | return 1; |
176 | } | 171 | } |
177 | 172 | ||
@@ -198,8 +193,7 @@ static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
198 | tm2 = luaT_gettmbyobj(L, p2, event); | 193 | tm2 = luaT_gettmbyobj(L, p2, event); |
199 | if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ | 194 | if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ |
200 | return -1; | 195 | return -1; |
201 | prepTMcall(L, tm1, p1, p2); | 196 | callTMres(L, L->top, tm1, p1, p2); |
202 | callTMres(L, L->top); | ||
203 | return !l_isfalse(L->top); | 197 | return !l_isfalse(L->top); |
204 | } | 198 | } |
205 | 199 | ||
@@ -278,8 +272,7 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { | |||
278 | default: return gcvalue(t1) == gcvalue(t2); | 272 | default: return gcvalue(t1) == gcvalue(t2); |
279 | } | 273 | } |
280 | if (tm == NULL) return 0; /* no TM? */ | 274 | if (tm == NULL) return 0; /* no TM? */ |
281 | prepTMcall(L, tm, t1, t2); | 275 | callTMres(L, L->top, tm, t1, t2); /* call TM */ |
282 | callTMres(L, L->top); /* call TM */ | ||
283 | return !l_isfalse(L->top); | 276 | return !l_isfalse(L->top); |
284 | } | 277 | } |
285 | 278 | ||
@@ -369,7 +362,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { | |||
369 | if (L->hookmask & LUA_MASKCALL) | 362 | if (L->hookmask & LUA_MASKCALL) |
370 | luaD_callhook(L, LUA_HOOKCALL, -1); | 363 | luaD_callhook(L, LUA_HOOKCALL, -1); |
371 | retentry: /* entry point when returning to old functions */ | 364 | retentry: /* entry point when returning to old functions */ |
372 | pc = L->ci->savedpc; | 365 | pc = L->savedpc; |
373 | cl = &clvalue(L->ci->func)->l; | 366 | cl = &clvalue(L->ci->func)->l; |
374 | k = cl->p->k; | 367 | k = cl->p->k; |
375 | /* main loop of interpreter */ | 368 | /* main loop of interpreter */ |
@@ -381,14 +374,14 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { | |||
381 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { | 374 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
382 | traceexec(L, pc); /***/ | 375 | traceexec(L, pc); /***/ |
383 | if (L->status == LUA_YIELD) { /* did hook yield? */ | 376 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
384 | L->ci->savedpc = pc - 1; | 377 | L->savedpc = pc - 1; |
385 | return NULL; | 378 | return NULL; |
386 | } | 379 | } |
387 | } | 380 | } |
388 | /* warning!! several calls may realloc the stack and invalidate `ra' */ | 381 | /* warning!! several calls may realloc the stack and invalidate `ra' */ |
389 | base = L->base; | 382 | base = L->base; |
390 | ra = RA(i); | 383 | ra = RA(i); |
391 | L->ci->savedpc = pc; | 384 | L->savedpc = pc; |
392 | lua_assert(base == L->ci->base); | 385 | lua_assert(base == L->ci->base); |
393 | lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); | 386 | lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); |
394 | lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); | 387 | lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); |
@@ -634,7 +627,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { | |||
634 | setobjs2s(L, func+aux, pfunc+aux); | 627 | setobjs2s(L, func+aux, pfunc+aux); |
635 | ci->top = L->top = func+aux; /* correct top */ | 628 | ci->top = L->top = func+aux; /* correct top */ |
636 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); | 629 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); |
637 | ci->savedpc = (ci+1)->savedpc; | 630 | ci->savedpc = L->savedpc; |
638 | ci->tailcalls++; /* one more call lost */ | 631 | ci->tailcalls++; /* one more call lost */ |
639 | L->ci--; /* remove new frame */ | 632 | L->ci--; /* remove new frame */ |
640 | goto callentry; | 633 | goto callentry; |