Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ceguilua/src/lua/lvm.c @ 2068

Last change on this file since 2068 was 1806, checked in by rgrieder, 16 years ago

added single 5.1.3 directory for lua since CEGUILua 0.5 can also build against lua 5.1

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