Line data Source code
1 : /*
2 : ** $Id: lvm.c,v 2.63.1.5 2011/08/17 20:43:11 roberto Exp $
3 : ** Lua virtual machine
4 : ** See Copyright Notice in lua.h
5 : */
6 :
7 :
8 : #include <stdio.h>
9 : #include <stdlib.h>
10 : #include <string.h>
11 :
12 : #define lvm_c
13 : #define LUA_CORE
14 :
15 : #include "lua.h"
16 :
17 : #include "ldebug.h"
18 : #include "ldo.h"
19 : #include "lfunc.h"
20 : #include "lgc.h"
21 : #include "lobject.h"
22 : #include "lopcodes.h"
23 : #include "lstate.h"
24 : #include "lstring.h"
25 : #include "ltable.h"
26 : #include "ltm.h"
27 : #include "lvm.h"
28 :
29 :
30 :
31 : /* limit for table tag-method chains (to avoid loops) */
32 : #define MAXTAGLOOP 100
33 :
34 :
35 322 : const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
36 : lua_Number num;
37 322 : if (ttisnumber(obj)) return obj;
38 275 : if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
39 87 : setnvalue(n, num);
40 87 : return n;
41 : }
42 : else
43 188 : return NULL;
44 : }
45 :
46 :
47 2202 : int luaV_tostring (lua_State *L, StkId obj) {
48 2202 : if (!ttisnumber(obj))
49 12 : return 0;
50 : else {
51 : char s[LUAI_MAXNUMBER2STR];
52 2190 : lua_Number n = nvalue(obj);
53 2190 : lua_number2str(s, n);
54 2190 : setsvalue2s(L, obj, luaS_new(L, s));
55 2190 : return 1;
56 : }
57 : }
58 :
59 :
60 34 : static void traceexec (lua_State *L, const Instruction *pc) {
61 34 : lu_byte mask = L->hookmask;
62 34 : const Instruction *oldpc = L->savedpc;
63 34 : L->savedpc = pc;
64 34 : if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
65 34 : resethookcount(L);
66 34 : luaD_callhook(L, LUA_HOOKCOUNT, -1);
67 : }
68 34 : if (mask & LUA_MASKLINE) {
69 0 : Proto *p = ci_func(L->ci)->l.p;
70 0 : int npc = pcRel(pc, p);
71 0 : int newline = getline(p, npc);
72 : /* call linehook when enter a new function, when jump back (loop),
73 : or when enter a new line */
74 0 : if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
75 0 : luaD_callhook(L, LUA_HOOKLINE, newline);
76 : }
77 34 : }
78 :
79 :
80 44 : static void callTMres (lua_State *L, StkId res, const TValue *f,
81 : const TValue *p1, const TValue *p2) {
82 44 : ptrdiff_t result = savestack(L, res);
83 44 : setobj2s(L, L->top, f); /* push function */
84 44 : setobj2s(L, L->top+1, p1); /* 1st argument */
85 44 : setobj2s(L, L->top+2, p2); /* 2nd argument */
86 44 : luaD_checkstack(L, 3);
87 44 : L->top += 3;
88 44 : luaD_call(L, L->top - 3, 1);
89 44 : res = restorestack(L, result);
90 44 : L->top--;
91 44 : setobjs2s(L, res, L->top);
92 44 : }
93 :
94 :
95 :
96 4 : static void callTM (lua_State *L, const TValue *f, const TValue *p1,
97 : const TValue *p2, const TValue *p3) {
98 4 : setobj2s(L, L->top, f); /* push function */
99 4 : setobj2s(L, L->top+1, p1); /* 1st argument */
100 4 : setobj2s(L, L->top+2, p2); /* 2nd argument */
101 4 : setobj2s(L, L->top+3, p3); /* 3th argument */
102 4 : luaD_checkstack(L, 4);
103 4 : L->top += 4;
104 4 : luaD_call(L, L->top - 4, 0);
105 2 : }
106 :
107 :
108 133884 : void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
109 : int loop;
110 141022 : for (loop = 0; loop < MAXTAGLOOP; loop++) {
111 : const TValue *tm;
112 141022 : if (ttistable(t)) { /* `t' is a table? */
113 133917 : Table *h = hvalue(t);
114 133917 : const TValue *res = luaH_get(h, key); /* do a primitive get */
115 133917 : if (!ttisnil(res) || /* result is no nil? */
116 1672 : (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
117 133865 : setobj2s(L, val, res);
118 133865 : return;
119 : }
120 : /* else will try the tag method */
121 : }
122 7105 : else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
123 7 : luaG_typeerror(L, t, "index");
124 7150 : if (ttisfunction(tm)) {
125 12 : callTMres(L, val, tm, t, key);
126 12 : return;
127 : }
128 7138 : t = tm; /* else repeat with `tm' */
129 : }
130 0 : luaG_runerror(L, "loop in gettable");
131 : }
132 :
133 :
134 99216 : void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
135 : int loop;
136 : TValue temp;
137 99217 : for (loop = 0; loop < MAXTAGLOOP; loop++) {
138 : const TValue *tm;
139 99217 : if (ttistable(t)) { /* `t' is a table? */
140 99209 : Table *h = hvalue(t);
141 99209 : TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
142 99207 : if (!ttisnil(oldval) || /* result is no nil? */
143 58190 : (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
144 99202 : setobj2t(L, oldval, val);
145 99202 : h->flags = 0;
146 99202 : luaC_barriert(L, h, val);
147 99204 : return;
148 : }
149 : /* else will try the tag method */
150 : }
151 8 : else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
152 8 : luaG_typeerror(L, t, "index");
153 5 : if (ttisfunction(tm)) {
154 4 : callTM(L, tm, t, key, val);
155 2 : return;
156 : }
157 : /* else repeat with `tm' */
158 1 : setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */
159 1 : t = &temp;
160 : }
161 0 : luaG_runerror(L, "loop in settable");
162 : }
163 :
164 :
165 117 : static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
166 : StkId res, TMS event) {
167 117 : const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
168 117 : if (ttisnil(tm))
169 101 : tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
170 117 : if (ttisnil(tm)) return 0;
171 24 : callTMres(L, res, tm, p1, p2);
172 24 : return 1;
173 : }
174 :
175 :
176 7 : static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
177 : TMS event) {
178 7 : const TValue *tm1 = fasttm(L, mt1, event);
179 : const TValue *tm2;
180 7 : if (tm1 == NULL) return NULL; /* no metamethod */
181 2 : if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
182 0 : tm2 = fasttm(L, mt2, event);
183 0 : if (tm2 == NULL) return NULL; /* no metamethod */
184 0 : if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
185 0 : return tm1;
186 0 : return NULL;
187 : }
188 :
189 :
190 48 : static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
191 : TMS event) {
192 48 : const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
193 : const TValue *tm2;
194 48 : if (ttisnil(tm1)) return -1; /* no metamethod? */
195 6 : tm2 = luaT_gettmbyobj(L, p2, event);
196 6 : if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
197 0 : return -1;
198 6 : callTMres(L, L->top, tm1, p1, p2);
199 6 : return !l_isfalse(L->top);
200 : }
201 :
202 :
203 91706 : static int l_strcmp (const TString *ls, const TString *rs) {
204 91706 : const char *l = getstr(ls);
205 91706 : size_t ll = ls->tsv.len;
206 91706 : const char *r = getstr(rs);
207 91706 : size_t lr = rs->tsv.len;
208 1 : for (;;) {
209 91707 : int temp = strcoll(l, r);
210 91707 : if (temp != 0) return temp;
211 : else { /* strings are equal up to a `\0' */
212 2642 : size_t len = strlen(l); /* index of first `\0' in both strings */
213 2642 : if (len == lr) /* r is finished? */
214 2640 : return (len == ll) ? 0 : 1;
215 2 : else if (len == ll) /* l is finished? */
216 1 : return -1; /* l is smaller than r (because r is not finished) */
217 : /* both strings longer than `len'; go on comparing (after the `\0') */
218 1 : len++;
219 1 : l += len; ll -= len; r += len; lr -= len;
220 : }
221 : }
222 : }
223 :
224 :
225 91721 : int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
226 : int res;
227 91721 : if (ttype(l) != ttype(r))
228 28 : return luaG_ordererror(L, l, r);
229 91693 : else if (ttisnumber(l))
230 54 : return luai_numlt(nvalue(l), nvalue(r));
231 91639 : else if (ttisstring(l))
232 91620 : return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
233 19 : else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
234 4 : return res;
235 15 : return luaG_ordererror(L, l, r);
236 : }
237 :
238 :
239 11456 : static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
240 : int res;
241 11456 : if (ttype(l) != ttype(r))
242 18 : return luaG_ordererror(L, l, r);
243 11438 : else if (ttisnumber(l))
244 11337 : return luai_numle(nvalue(l), nvalue(r));
245 101 : else if (ttisstring(l))
246 86 : return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
247 15 : else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
248 1 : return res;
249 14 : else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
250 1 : return !res;
251 13 : return luaG_ordererror(L, l, r);
252 : }
253 :
254 :
255 25160 : int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
256 : const TValue *tm;
257 : lua_assert(ttype(t1) == ttype(t2));
258 25160 : switch (ttype(t1)) {
259 153 : case LUA_TNIL: return 1;
260 877 : case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
261 145 : case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
262 0 : case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
263 8 : case LUA_TUSERDATA: {
264 8 : if (uvalue(t1) == uvalue(t2)) return 1;
265 1 : tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
266 : TM_EQ);
267 1 : break; /* will try TM */
268 : }
269 44 : case LUA_TTABLE: {
270 44 : if (hvalue(t1) == hvalue(t2)) return 1;
271 6 : tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
272 6 : break; /* will try TM */
273 : }
274 23933 : default: return gcvalue(t1) == gcvalue(t2);
275 : }
276 7 : if (tm == NULL) return 0; /* no TM? */
277 2 : callTMres(L, L->top, tm, t1, t2); /* call TM */
278 2 : return !l_isfalse(L->top);
279 : }
280 :
281 :
282 10907 : void luaV_concat (lua_State *L, int total, int last) {
283 : do {
284 11454 : StkId top = L->base + last + 1;
285 11454 : int n = 2; /* number of elements handled in this pass (at least 2) */
286 11454 : if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
287 12 : if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
288 9 : luaG_concaterror(L, top-2, top-1);
289 11442 : } else if (tsvalue(top-1)->len == 0) /* second op is empty? */
290 545 : (void)tostring(L, top - 2); /* result is first op (as string) */
291 : else {
292 : /* at least two string values; get as many as possible */
293 10897 : size_t tl = tsvalue(top-1)->len;
294 : char *buffer;
295 : int i;
296 : /* collect total length */
297 30094 : for (n = 1; n < total && tostring(L, top-n-1); n++) {
298 19197 : size_t l = tsvalue(top-n-1)->len;
299 19197 : if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
300 19197 : tl += l;
301 : }
302 10897 : buffer = luaZ_openspace(L, &G(L)->buff, tl);
303 10897 : tl = 0;
304 40991 : for (i=n; i>0; i--) { /* concat all strings */
305 30094 : size_t l = tsvalue(top-i)->len;
306 30094 : memcpy(buffer+tl, svalue(top-i), l);
307 30094 : tl += l;
308 : }
309 10897 : setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
310 : }
311 11445 : total -= n-1; /* got `n' strings to create 1 new */
312 11445 : last -= n-1;
313 11445 : } while (total > 1); /* repeat until only 1 result left */
314 10898 : }
315 :
316 :
317 123 : static void Arith (lua_State *L, StkId ra, const TValue *rb,
318 : const TValue *rc, TMS op) {
319 : TValue tempb, tempc;
320 : const TValue *b, *c;
321 182 : if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
322 83 : (c = luaV_tonumber(rc, &tempc)) != NULL) {
323 24 : lua_Number nb = nvalue(b), nc = nvalue(c);
324 24 : switch (op) {
325 4 : case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
326 3 : case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
327 7 : case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
328 3 : case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
329 3 : case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
330 3 : case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
331 1 : case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
332 0 : default: lua_assert(0); break;
333 : }
334 : }
335 99 : else if (!call_binTM(L, rb, rc, ra, op))
336 78 : luaG_aritherror(L, rb, rc);
337 45 : }
338 :
339 :
340 :
341 : /*
342 : ** some macros for common tasks in `luaV_execute'
343 : */
344 :
345 : #define runtime_check(L, c) { if (!(c)) break; }
346 :
347 : #define RA(i) (base+GETARG_A(i))
348 : /* to be used after possible stack reallocation */
349 : #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
350 : #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
351 : #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
352 : ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
353 : #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
354 : ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
355 : #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
356 :
357 :
358 : #define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
359 :
360 :
361 : #define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
362 :
363 :
364 : #define arith_op(op,tm) { \
365 : TValue *rb = RKB(i); \
366 : TValue *rc = RKC(i); \
367 : if (ttisnumber(rb) && ttisnumber(rc)) { \
368 : lua_Number nb = nvalue(rb), nc = nvalue(rc); \
369 : setnvalue(ra, op(nb, nc)); \
370 : } \
371 : else \
372 : Protect(Arith(L, ra, rb, rc, tm)); \
373 : }
374 :
375 :
376 :
377 12981 : void luaV_execute (lua_State *L, int nexeccalls) {
378 : LClosure *cl;
379 : StkId base;
380 : TValue *k;
381 : const Instruction *pc;
382 32210 : reentry: /* entry point */
383 : lua_assert(isLua(L->ci));
384 45191 : pc = L->savedpc;
385 45191 : cl = &clvalue(L->ci->func)->l;
386 45191 : base = L->base;
387 45191 : k = cl->p->k;
388 : /* main loop of interpreter */
389 616935 : for (;;) {
390 662126 : const Instruction i = *pc++;
391 : StkId ra;
392 662126 : if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
393 1445 : (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
394 34 : traceexec(L, pc);
395 34 : if (L->status == LUA_YIELD) { /* did hook yield? */
396 0 : L->savedpc = pc - 1;
397 0 : return;
398 : }
399 34 : base = L->base;
400 : }
401 : /* warning!! several calls may realloc the stack and invalidate `ra' */
402 662126 : ra = RA(i);
403 : lua_assert(base == L->base && L->base == L->ci->base);
404 : lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
405 : lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
406 662126 : switch (GET_OPCODE(i)) {
407 88434 : case OP_MOVE: {
408 88434 : setobjs2s(L, ra, RB(i));
409 88434 : continue;
410 : }
411 32312 : case OP_LOADK: {
412 32312 : setobj2s(L, ra, KBx(i));
413 32312 : continue;
414 : }
415 7571 : case OP_LOADBOOL: {
416 7571 : setbvalue(ra, GETARG_B(i));
417 7571 : if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
418 7571 : continue;
419 : }
420 1108 : case OP_LOADNIL: {
421 554 : TValue *rb = RB(i);
422 : do {
423 723 : setnilvalue(rb--);
424 723 : } while (rb >= ra);
425 554 : continue;
426 : }
427 32657 : case OP_GETUPVAL: {
428 32657 : int b = GETARG_B(i);
429 32657 : setobj2s(L, ra, cl->upvals[b]->v);
430 32657 : continue;
431 : }
432 96394 : case OP_GETGLOBAL: {
433 : TValue g;
434 48197 : TValue *rb = KBx(i);
435 48197 : sethvalue(L, &g, cl->env);
436 : lua_assert(ttisstring(rb));
437 48197 : Protect(luaV_gettable(L, &g, rb, ra));
438 48197 : continue;
439 : }
440 72960 : case OP_GETTABLE: {
441 72960 : Protect(luaV_gettable(L, RB(i), RKC(i), ra));
442 72953 : continue;
443 : }
444 2983 : case OP_SETGLOBAL: {
445 : TValue g;
446 1492 : sethvalue(L, &g, cl->env);
447 : lua_assert(ttisstring(KBx(i)));
448 1492 : Protect(luaV_settable(L, &g, KBx(i), ra));
449 1491 : continue;
450 : }
451 5282 : case OP_SETUPVAL: {
452 2641 : UpVal *uv = cl->upvals[GETARG_B(i)];
453 2641 : setobj(L, uv->v, ra);
454 2641 : luaC_barrier(L, uv, ra);
455 2641 : continue;
456 : }
457 82817 : case OP_SETTABLE: {
458 82817 : Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
459 82806 : continue;
460 : }
461 13162 : case OP_NEWTABLE: {
462 6581 : int b = GETARG_B(i);
463 6581 : int c = GETARG_C(i);
464 6581 : sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
465 6581 : Protect(luaC_checkGC(L));
466 6581 : continue;
467 : }
468 14228 : case OP_SELF: {
469 7114 : StkId rb = RB(i);
470 7114 : setobjs2s(L, ra+1, rb);
471 7114 : Protect(luaV_gettable(L, rb, RKC(i), ra));
472 7114 : continue;
473 : }
474 14376 : case OP_ADD: {
475 14376 : arith_op(luai_numadd, TM_ADD);
476 14364 : continue;
477 : }
478 11099 : case OP_SUB: {
479 11099 : arith_op(luai_numsub, TM_SUB);
480 11088 : continue;
481 : }
482 1159 : case OP_MUL: {
483 1159 : arith_op(luai_nummul, TM_MUL);
484 1145 : continue;
485 : }
486 37 : case OP_DIV: {
487 37 : arith_op(luai_numdiv, TM_DIV);
488 26 : continue;
489 : }
490 16 : case OP_MOD: {
491 16 : arith_op(luai_nummod, TM_MOD);
492 5 : continue;
493 : }
494 20 : case OP_POW: {
495 20 : arith_op(luai_numpow, TM_POW);
496 9 : continue;
497 : }
498 18 : case OP_UNM: {
499 13 : TValue *rb = RB(i);
500 13 : if (ttisnumber(rb)) {
501 3 : lua_Number nb = nvalue(rb);
502 3 : setnvalue(ra, luai_numunm(nb));
503 : }
504 : else {
505 10 : Protect(Arith(L, ra, rb, rb, TM_UNM));
506 : }
507 5 : continue;
508 : }
509 24 : case OP_NOT: {
510 12 : int res = l_isfalse(RB(i)); /* next assignment may change this value */
511 12 : setbvalue(ra, res);
512 12 : continue;
513 : }
514 1226 : case OP_LEN: {
515 616 : const TValue *rb = RB(i);
516 616 : switch (ttype(rb)) {
517 609 : case LUA_TTABLE: {
518 609 : setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
519 609 : break;
520 : }
521 1 : case LUA_TSTRING: {
522 1 : setnvalue(ra, cast_num(tsvalue(rb)->len));
523 1 : break;
524 : }
525 6 : default: { /* try metamethod */
526 6 : Protect(
527 : if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
528 : luaG_typeerror(L, rb, "get length of");
529 : )
530 : }
531 : }
532 610 : continue;
533 : }
534 15875 : case OP_CONCAT: {
535 7942 : int b = GETARG_B(i);
536 7942 : int c = GETARG_C(i);
537 7942 : Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
538 7933 : setobjs2s(L, RA(i), base+b);
539 7933 : continue;
540 : }
541 18297 : case OP_JMP: {
542 18297 : dojump(L, pc, GETARG_sBx(i));
543 18297 : continue;
544 : }
545 50508 : case OP_EQ: {
546 25254 : TValue *rb = RKB(i);
547 25254 : TValue *rc = RKC(i);
548 25254 : Protect(
549 : if (equalobj(L, rb, rc) == GETARG_A(i))
550 : dojump(L, pc, GETARG_sBx(*pc));
551 : )
552 25254 : pc++;
553 25254 : continue;
554 : }
555 113 : case OP_LT: {
556 113 : Protect(
557 : if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
558 : dojump(L, pc, GETARG_sBx(*pc));
559 : )
560 70 : pc++;
561 70 : continue;
562 : }
563 11456 : case OP_LE: {
564 11456 : Protect(
565 : if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
566 : dojump(L, pc, GETARG_sBx(*pc));
567 : )
568 11425 : pc++;
569 11425 : continue;
570 : }
571 17766 : case OP_TEST: {
572 17766 : if (l_isfalse(ra) != GETARG_C(i))
573 16074 : dojump(L, pc, GETARG_sBx(*pc));
574 17766 : pc++;
575 17766 : continue;
576 : }
577 10 : case OP_TESTSET: {
578 5 : TValue *rb = RB(i);
579 5 : if (l_isfalse(rb) != GETARG_C(i)) {
580 4 : setobjs2s(L, ra, rb);
581 4 : dojump(L, pc, GETARG_sBx(*pc));
582 : }
583 5 : pc++;
584 5 : continue;
585 : }
586 70450 : case OP_CALL: {
587 70450 : int b = GETARG_B(i);
588 70450 : int nresults = GETARG_C(i) - 1;
589 70450 : if (b != 0) L->top = ra+b; /* else previous instruction set top */
590 70450 : L->savedpc = pc;
591 70450 : switch (luaD_precall(L, ra, nresults)) {
592 15534 : case PCRLUA: {
593 15534 : nexeccalls++;
594 15534 : goto reentry; /* restart luaV_execute over new Lua function */
595 : }
596 48859 : case PCRC: {
597 : /* it was a C function (`precall' called it); adjust results */
598 48859 : if (nresults >= 0) L->top = L->ci->top;
599 48859 : base = L->base;
600 48859 : continue;
601 : }
602 5947 : default: {
603 5947 : return; /* yield */
604 : }
605 : }
606 : }
607 1262 : case OP_TAILCALL: {
608 1262 : int b = GETARG_B(i);
609 1262 : if (b != 0) L->top = ra+b; /* else previous instruction set top */
610 1262 : L->savedpc = pc;
611 : lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
612 1262 : switch (luaD_precall(L, ra, LUA_MULTRET)) {
613 1151 : case PCRLUA: {
614 : /* tail call: put new frame in place of previous one */
615 1151 : CallInfo *ci = L->ci - 1; /* previous frame */
616 : int aux;
617 1151 : StkId func = ci->func;
618 1151 : StkId pfunc = (ci+1)->func; /* previous function index */
619 1151 : if (L->openupval) luaF_close(L, ci->base);
620 1151 : L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
621 11773 : for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
622 10622 : setobjs2s(L, func+aux, pfunc+aux);
623 1151 : ci->top = L->top = func+aux; /* correct top */
624 : lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
625 1151 : ci->savedpc = L->savedpc;
626 1151 : ci->tailcalls++; /* one more call lost */
627 1151 : L->ci--; /* remove new frame */
628 1151 : goto reentry;
629 : }
630 108 : case PCRC: { /* it was a C function (`precall' called it) */
631 108 : base = L->base;
632 108 : continue;
633 : }
634 1 : default: {
635 1 : return; /* yield */
636 : }
637 : }
638 : }
639 22257 : case OP_RETURN: {
640 22257 : int b = GETARG_B(i);
641 22257 : if (b != 0) L->top = ra+b-1;
642 22257 : if (L->openupval) luaF_close(L, base);
643 22257 : L->savedpc = pc;
644 22257 : b = luaD_poscall(L, ra);
645 22257 : if (--nexeccalls == 0) /* was previous function running `here'? */
646 6732 : return; /* no: return */
647 : else { /* yes: continue its execution */
648 15525 : if (b) L->top = L->ci->top;
649 : lua_assert(isLua(L->ci));
650 : lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
651 15525 : goto reentry;
652 : }
653 : }
654 32106 : case OP_FORLOOP: {
655 16053 : lua_Number step = nvalue(ra+2);
656 16053 : lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
657 16053 : lua_Number limit = nvalue(ra+1);
658 16053 : if (luai_numlt(0, step) ? luai_numle(idx, limit)
659 : : luai_numle(limit, idx)) {
660 11601 : dojump(L, pc, GETARG_sBx(i)); /* jump back */
661 11601 : setnvalue(ra, idx); /* update internal index... */
662 11601 : setnvalue(ra+3, idx); /* ...and external index */
663 : }
664 16053 : continue;
665 : }
666 8921 : case OP_FORPREP: {
667 4462 : const TValue *init = ra;
668 4462 : const TValue *plimit = ra+1;
669 4462 : const TValue *pstep = ra+2;
670 4462 : L->savedpc = pc; /* next steps may throw errors */
671 4462 : if (!tonumber(init, ra))
672 1 : luaG_runerror(L, LUA_QL("for") " initial value must be a number");
673 4461 : else if (!tonumber(plimit, ra+1))
674 1 : luaG_runerror(L, LUA_QL("for") " limit must be a number");
675 4460 : else if (!tonumber(pstep, ra+2))
676 1 : luaG_runerror(L, LUA_QL("for") " step must be a number");
677 4459 : setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
678 4459 : dojump(L, pc, GETARG_sBx(i));
679 4459 : continue;
680 : }
681 104914 : case OP_TFORLOOP: {
682 52457 : StkId cb = ra + 3; /* call base */
683 52457 : setobjs2s(L, cb+2, ra+2);
684 52457 : setobjs2s(L, cb+1, ra+1);
685 52457 : setobjs2s(L, cb, ra);
686 52457 : L->top = cb+3; /* func. + 2 args (state and index) */
687 52457 : Protect(luaD_call(L, cb, GETARG_C(i)));
688 52457 : L->top = L->ci->top;
689 52457 : cb = RA(i) + 3; /* previous call may change the stack */
690 52457 : if (!ttisnil(cb)) { /* continue loop? */
691 46505 : setobjs2s(L, cb-1, cb); /* save control variable */
692 46505 : dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
693 : }
694 52457 : pc++;
695 52457 : continue;
696 : }
697 714 : case OP_SETLIST: {
698 357 : int n = GETARG_B(i);
699 357 : int c = GETARG_C(i);
700 : int last;
701 : Table *h;
702 357 : if (n == 0) {
703 220 : n = cast_int(L->top - ra) - 1;
704 220 : L->top = L->ci->top;
705 : }
706 357 : if (c == 0) c = cast_int(*pc++);
707 357 : runtime_check(L, ttistable(ra));
708 357 : h = hvalue(ra);
709 357 : last = ((c-1)*LFIELDS_PER_FLUSH) + n;
710 357 : if (last > h->sizearray) /* needs more space? */
711 213 : luaH_resizearray(L, h, last); /* pre-alloc it at once */
712 1377 : for (; n > 0; n--) {
713 1020 : TValue *val = ra+n;
714 1020 : setobj2t(L, luaH_setnum(L, h, last--), val);
715 1020 : luaC_barriert(L, h, val);
716 : }
717 357 : continue;
718 : }
719 401 : case OP_CLOSE: {
720 401 : luaF_close(L, ra);
721 401 : continue;
722 : }
723 5800 : case OP_CLOSURE: {
724 : Proto *p;
725 : Closure *ncl;
726 : int nup, j;
727 2900 : p = cl->p->p[GETARG_Bx(i)];
728 2900 : nup = p->nups;
729 2900 : ncl = luaF_newLclosure(L, nup, cl->env);
730 2900 : ncl->l.p = p;
731 11325 : for (j=0; j<nup; j++, pc++) {
732 8425 : if (GET_OPCODE(*pc) == OP_GETUPVAL)
733 1551 : ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
734 : else {
735 : lua_assert(GET_OPCODE(*pc) == OP_MOVE);
736 6874 : ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
737 : }
738 : }
739 2900 : setclvalue(L, ra, ncl);
740 2900 : Protect(luaC_checkGC(L));
741 2900 : continue;
742 : }
743 32 : case OP_VARARG: {
744 16 : int b = GETARG_B(i) - 1;
745 : int j;
746 16 : CallInfo *ci = L->ci;
747 16 : int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
748 16 : if (b == LUA_MULTRET) {
749 12 : Protect(luaD_checkstack(L, n));
750 12 : ra = RA(i); /* previous call may change the stack */
751 12 : b = n;
752 12 : L->top = ra + n;
753 : }
754 39 : for (j = 0; j < b; j++) {
755 23 : if (j < n) {
756 16 : setobjs2s(L, ra + j, ci->base - n + j);
757 : }
758 : else {
759 7 : setnilvalue(ra + j);
760 : }
761 : }
762 16 : continue;
763 : }
764 : }
765 : }
766 : }
767 :
|