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