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