]> git.proxmox.com Git - mirror_zfs.git/blob - module/lua/lvm.c
OpenZFS 7431 - ZFS Channel Programs
[mirror_zfs.git] / module / lua / lvm.c
1 /* BEGIN CSTYLED */
2 /*
3 ** $Id: lvm.c,v 2.155.1.1 2013/04/12 18:48:47 roberto Exp $
4 ** Lua virtual machine
5 ** See Copyright Notice in lua.h
6 */
7
8
9 #define lvm_c
10 #define LUA_CORE
11
12 #include <sys/lua/lua.h>
13
14 #include "ldebug.h"
15 #include "ldo.h"
16 #include "lfunc.h"
17 #include "lgc.h"
18 #include "lobject.h"
19 #include "lopcodes.h"
20 #include "lstate.h"
21 #include "lstring.h"
22 #include "ltable.h"
23 #include "ltm.h"
24 #include "lvm.h"
25
26 #ifdef _KERNEL
27 #define strcoll(l,r) (strcmp((l),(r)))
28 #endif
29
30 /* limit for table tag-method chains (to avoid loops) */
31 #define MAXTAGLOOP 100
32
33
34 const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
35 lua_Number num;
36 if (ttisnumber(obj)) return obj;
37 if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) {
38 setnvalue(n, num);
39 return n;
40 }
41 else
42 return NULL;
43 }
44
45
46 int luaV_tostring (lua_State *L, StkId obj) {
47 if (!ttisnumber(obj))
48 return 0;
49 else {
50 char s[LUAI_MAXNUMBER2STR];
51 lua_Number n = nvalue(obj);
52 int l = lua_number2str(s, n);
53 setsvalue2s(L, obj, luaS_newlstr(L, s, l));
54 return 1;
55 }
56 }
57
58
59 static void traceexec (lua_State *L) {
60 CallInfo *ci = L->ci;
61 lu_byte mask = L->hookmask;
62 int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
63 if (counthook)
64 resethookcount(L); /* reset count */
65 if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
66 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
67 return; /* do not call hook again (VM yielded, so it did not move) */
68 }
69 if (counthook)
70 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
71 if (mask & LUA_MASKLINE) {
72 Proto *p = ci_func(ci)->p;
73 int npc = pcRel(ci->u.l.savedpc, p);
74 int newline = getfuncline(p, npc);
75 if (npc == 0 || /* call linehook when enter a new function, */
76 ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
77 newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */
78 luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
79 }
80 L->oldpc = ci->u.l.savedpc;
81 if (L->status == LUA_YIELD) { /* did hook yield? */
82 if (counthook)
83 L->hookcount = 1; /* undo decrement to zero */
84 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
85 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
86 ci->func = L->top - 1; /* protect stack below results */
87 luaD_throw(L, LUA_YIELD);
88 }
89 }
90
91
92 static void callTM (lua_State *L, const TValue *f, const TValue *p1,
93 const TValue *p2, TValue *p3, int hasres) {
94 if (L == NULL) return;
95
96 ptrdiff_t result = savestack(L, p3);
97 setobj2s(L, L->top++, f); /* push function */
98 setobj2s(L, L->top++, p1); /* 1st argument */
99 setobj2s(L, L->top++, p2); /* 2nd argument */
100 if (!hasres) /* no result? 'p3' is third argument */
101 setobj2s(L, L->top++, p3); /* 3rd argument */
102 /* metamethod may yield only when called from Lua code */
103 luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci));
104 if (hasres) { /* if has result, move it to its place */
105 p3 = restorestack(L, result);
106 setobjs2s(L, p3, --L->top);
107 }
108 }
109
110
111 void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
112 int loop;
113 for (loop = 0; loop < MAXTAGLOOP; loop++) {
114 const TValue *tm;
115 if (ttistable(t)) { /* `t' is a table? */
116 Table *h = hvalue(t);
117 const TValue *res = luaH_get(h, key); /* do a primitive get */
118 if (!ttisnil(res) || /* result is not nil? */
119 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
120 setobj2s(L, val, res);
121 return;
122 }
123 /* else will try the tag method */
124 }
125 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
126 luaG_typeerror(L, t, "index");
127 if (ttisfunction(tm)) {
128 callTM(L, tm, t, key, val, 1);
129 return;
130 }
131 t = tm; /* else repeat with 'tm' */
132 }
133 luaG_runerror(L, "loop in gettable");
134 }
135
136
137 void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
138 int loop;
139 for (loop = 0; loop < MAXTAGLOOP; loop++) {
140 const TValue *tm;
141 if (ttistable(t)) { /* `t' is a table? */
142 Table *h = hvalue(t);
143 TValue *oldval = cast(TValue *, luaH_get(h, key));
144 /* if previous value is not nil, there must be a previous entry
145 in the table; moreover, a metamethod has no relevance */
146 if (!ttisnil(oldval) ||
147 /* previous value is nil; must check the metamethod */
148 ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
149 /* no metamethod; is there a previous entry in the table? */
150 (oldval != luaO_nilobject ||
151 /* no previous entry; must create one. (The next test is
152 always true; we only need the assignment.) */
153 (oldval = luaH_newkey(L, h, key), 1)))) {
154 /* no metamethod and (now) there is an entry with given key */
155 setobj2t(L, oldval, val); /* assign new value to that entry */
156 invalidateTMcache(h);
157 luaC_barrierback(L, obj2gco(h), val);
158 return;
159 }
160 /* else will try the metamethod */
161 }
162 else /* not a table; check metamethod */
163 if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
164 luaG_typeerror(L, t, "index");
165 /* there is a metamethod */
166 if (ttisfunction(tm)) {
167 callTM(L, tm, t, key, val, 0);
168 return;
169 }
170 t = tm; /* else repeat with 'tm' */
171 }
172 luaG_runerror(L, "loop in settable");
173 }
174
175
176 static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
177 StkId res, TMS event) {
178 const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
179 if (ttisnil(tm))
180 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
181 if (ttisnil(tm)) return 0;
182 callTM(L, tm, p1, p2, res, 1);
183 return 1;
184 }
185
186
187 static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2,
188 TMS event) {
189 const TValue *tm1 = fasttm(L, mt1, event);
190 const TValue *tm2;
191 if (tm1 == NULL) return NULL; /* no metamethod */
192 if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
193 tm2 = fasttm(L, mt2, event);
194 if (tm2 == NULL) return NULL; /* no metamethod */
195 if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */
196 return tm1;
197 return NULL;
198 }
199
200
201 static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
202 TMS event) {
203 if (!call_binTM(L, p1, p2, L->top, event))
204 return -1; /* no metamethod */
205 else
206 return !l_isfalse(L->top);
207 }
208
209
210 static int l_strcmp (const TString *ls, const TString *rs) {
211 const char *l = getstr(ls);
212 size_t ll = ls->tsv.len;
213 const char *r = getstr(rs);
214 size_t lr = rs->tsv.len;
215 for (;;) {
216 int temp = strcoll(l, r);
217 if (temp != 0) return temp;
218 else { /* strings are equal up to a `\0' */
219 size_t len = strlen(l); /* index of first `\0' in both strings */
220 if (len == lr) /* r is finished? */
221 return (len == ll) ? 0 : 1;
222 else if (len == ll) /* l is finished? */
223 return -1; /* l is smaller than r (because r is not finished) */
224 /* both strings longer than `len'; go on comparing (after the `\0') */
225 len++;
226 l += len; ll -= len; r += len; lr -= len;
227 }
228 }
229 }
230
231
232 int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
233 int res;
234 if (ttisnumber(l) && ttisnumber(r))
235 return luai_numlt(L, nvalue(l), nvalue(r));
236 else if (ttisstring(l) && ttisstring(r))
237 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
238 else if ((res = call_orderTM(L, l, r, TM_LT)) < 0)
239 luaG_ordererror(L, l, r);
240 return res;
241 }
242
243
244 int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
245 int res;
246 if (ttisnumber(l) && ttisnumber(r))
247 return luai_numle(L, nvalue(l), nvalue(r));
248 else if (ttisstring(l) && ttisstring(r))
249 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
250 else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
251 return res;
252 else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */
253 luaG_ordererror(L, l, r);
254 return !res;
255 }
256
257
258 /*
259 ** equality of Lua values. L == NULL means raw equality (no metamethods)
260 */
261 int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) {
262 const TValue *tm;
263 lua_assert(ttisequal(t1, t2));
264 switch (ttype(t1)) {
265 case LUA_TNIL: return 1;
266 case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
267 case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
268 case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
269 case LUA_TLCF: return fvalue(t1) == fvalue(t2);
270 case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
271 case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
272 case LUA_TUSERDATA: {
273 if (uvalue(t1) == uvalue(t2)) return 1;
274 else if (L == NULL) return 0;
275 tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ);
276 break; /* will try TM */
277 }
278 case LUA_TTABLE: {
279 if (hvalue(t1) == hvalue(t2)) return 1;
280 else if (L == NULL) return 0;
281 tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
282 break; /* will try TM */
283 }
284 default:
285 lua_assert(iscollectable(t1));
286 return gcvalue(t1) == gcvalue(t2);
287 }
288 if (tm == NULL || L == NULL) return 0; /* no TM? */
289 callTM(L, tm, t1, t2, L->top, 1); /* call TM */
290 return !l_isfalse(L->top);
291 }
292
293
294 void luaV_concat (lua_State *L, int total) {
295 lua_assert(total >= 2);
296 do {
297 StkId top = L->top;
298 int n = 2; /* number of elements handled in this pass (at least 2) */
299 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
300 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
301 luaG_concaterror(L, top-2, top-1);
302 }
303 else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
304 (void)tostring(L, top - 2); /* result is first operand */
305 else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
306 setobjs2s(L, top - 2, top - 1); /* result is second op. */
307 }
308 else {
309 /* at least two non-empty string values; get as many as possible */
310 size_t tl = tsvalue(top-1)->len;
311 char *buffer;
312 int i;
313 /* collect total length */
314 for (i = 1; i < total && tostring(L, top-i-1); i++) {
315 size_t l = tsvalue(top-i-1)->len;
316 if (l >= (MAX_SIZET/sizeof(char)) - tl)
317 luaG_runerror(L, "string length overflow");
318 tl += l;
319 }
320 buffer = luaZ_openspace(L, &G(L)->buff, tl);
321 tl = 0;
322 n = i;
323 do { /* concat all strings */
324 size_t l = tsvalue(top-i)->len;
325 memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
326 tl += l;
327 } while (--i > 0);
328 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
329 }
330 total -= n-1; /* got 'n' strings to create 1 new */
331 L->top -= n-1; /* popped 'n' strings and pushed one */
332 } while (total > 1); /* repeat until only 1 result left */
333 }
334
335
336 void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
337 const TValue *tm;
338 switch (ttypenv(rb)) {
339 case LUA_TTABLE: {
340 Table *h = hvalue(rb);
341 tm = fasttm(L, h->metatable, TM_LEN);
342 if (tm) break; /* metamethod? break switch to call it */
343 setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */
344 return;
345 }
346 case LUA_TSTRING: {
347 setnvalue(ra, cast_num(tsvalue(rb)->len));
348 return;
349 }
350 default: { /* try metamethod */
351 tm = luaT_gettmbyobj(L, rb, TM_LEN);
352 if (ttisnil(tm)) /* no metamethod? */
353 luaG_typeerror(L, rb, "get length of");
354 break;
355 }
356 }
357 callTM(L, tm, rb, rb, ra, 1);
358 }
359
360 /*
361 * luaV_div and luaV_mod patched in from Lua 5.3.2 in order to properly handle
362 * div/mod by zero (instead of crashing, which is the default behavior in
363 * Lua 5.2)
364 */
365
366 /*
367 ** Integer division; return 'm // n', that is, floor(m/n).
368 ** C division truncates its result (rounds towards zero).
369 ** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer,
370 ** otherwise 'floor(q) == trunc(q) - 1'.
371 */
372 static lua_Number luaV_div (lua_State *L, lua_Number m, lua_Number n) {
373 if ((lua_Unsigned)(n) + 1u <= 1u) { /* special cases: -1 or 0 */
374 if (n == 0)
375 luaG_runerror(L, "attempt to divide by zero");
376 return (0 - m); /* n==-1; avoid overflow with 0x80000...//-1 */
377 }
378 else {
379 lua_Number q = m / n; /* perform C division */
380 if ((m ^ n) < 0 && m % n != 0) /* 'm/n' would be negative non-integer? */
381 q -= 1; /* correct result for different rounding */
382 return q;
383 }
384 }
385
386
387 /*
388 ** Integer modulus; return 'm % n'. (Assume that C '%' with
389 ** negative operands follows C99 behavior. See previous comment
390 ** about luaV_div.)
391 */
392 static lua_Number luaV_mod (lua_State *L, lua_Number m, lua_Number n) {
393 if ((lua_Unsigned)(n) + 1u <= 1u) { /* special cases: -1 or 0 */
394 if (n == 0)
395 luaG_runerror(L, "attempt to perform 'n%%0'");
396 return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */
397 }
398 else {
399 lua_Number r = m % n;
400 if (r != 0 && (m ^ n) < 0) /* 'm/n' would be non-integer negative? */
401 r += n; /* correct result for different rounding */
402 return r;
403 }
404 }
405
406 /*
407 * End patch from 5.3.2
408 */
409
410 void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
411 const TValue *rc, TMS op) {
412 TValue tempb, tempc;
413 const TValue *b, *c;
414 if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
415 (c = luaV_tonumber(rc, &tempc)) != NULL) {
416 /*
417 * Patched: if dividing or modding, use patched functions from 5.3
418 */
419 lua_Number res;
420 int lop = op - TM_ADD + LUA_OPADD;
421 if (lop == LUA_OPDIV) {
422 res = luaV_div(L, nvalue(b), nvalue(c));
423 } else if (lop == LUA_OPMOD) {
424 res = luaV_mod(L, nvalue(b), nvalue(c));
425 } else {
426 res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c));
427 }
428 setnvalue(ra, res);
429 }
430 else if (!call_binTM(L, rb, rc, ra, op))
431 luaG_aritherror(L, rb, rc);
432 }
433
434
435 /*
436 ** check whether cached closure in prototype 'p' may be reused, that is,
437 ** whether there is a cached closure with the same upvalues needed by
438 ** new closure to be created.
439 */
440 static Closure *getcached (Proto *p, UpVal **encup, StkId base) {
441 Closure *c = p->cache;
442 if (c != NULL) { /* is there a cached closure? */
443 int nup = p->sizeupvalues;
444 Upvaldesc *uv = p->upvalues;
445 int i;
446 for (i = 0; i < nup; i++) { /* check whether it has right upvalues */
447 TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
448 if (c->l.upvals[i]->v != v)
449 return NULL; /* wrong upvalue; cannot reuse closure */
450 }
451 }
452 return c; /* return cached closure (or NULL if no cached closure) */
453 }
454
455
456 /*
457 ** create a new Lua closure, push it in the stack, and initialize
458 ** its upvalues. Note that the call to 'luaC_barrierproto' must come
459 ** before the assignment to 'p->cache', as the function needs the
460 ** original value of that field.
461 */
462 static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
463 StkId ra) {
464 int nup = p->sizeupvalues;
465 Upvaldesc *uv = p->upvalues;
466 int i;
467 Closure *ncl = luaF_newLclosure(L, nup);
468 ncl->l.p = p;
469 setclLvalue(L, ra, ncl); /* anchor new closure in stack */
470 for (i = 0; i < nup; i++) { /* fill in its upvalues */
471 if (uv[i].instack) /* upvalue refers to local variable? */
472 ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);
473 else /* get upvalue from enclosing function */
474 ncl->l.upvals[i] = encup[uv[i].idx];
475 }
476 luaC_barrierproto(L, p, ncl);
477 p->cache = ncl; /* save it on cache for reuse */
478 }
479
480
481 /*
482 ** finish execution of an opcode interrupted by an yield
483 */
484 void luaV_finishOp (lua_State *L) {
485 CallInfo *ci = L->ci;
486 StkId base = ci->u.l.base;
487 Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
488 OpCode op = GET_OPCODE(inst);
489 switch (op) { /* finish its execution */
490 case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
491 case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
492 case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
493 setobjs2s(L, base + GETARG_A(inst), --L->top);
494 break;
495 }
496 case OP_LE: case OP_LT: case OP_EQ: {
497 int res = !l_isfalse(L->top - 1);
498 L->top--;
499 /* metamethod should not be called when operand is K */
500 lua_assert(!ISK(GETARG_B(inst)));
501 if (op == OP_LE && /* "<=" using "<" instead? */
502 ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
503 res = !res; /* invert result */
504 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
505 if (res != GETARG_A(inst)) /* condition failed? */
506 ci->u.l.savedpc++; /* skip jump instruction */
507 break;
508 }
509 case OP_CONCAT: {
510 StkId top = L->top - 1; /* top when 'call_binTM' was called */
511 int b = GETARG_B(inst); /* first element to concatenate */
512 int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */
513 setobj2s(L, top - 2, top); /* put TM result in proper position */
514 if (total > 1) { /* are there elements to concat? */
515 L->top = top - 1; /* top is one after last element (at top-2) */
516 luaV_concat(L, total); /* concat them (may yield again) */
517 }
518 /* move final result to final position */
519 setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1);
520 L->top = ci->top; /* restore top */
521 break;
522 }
523 case OP_TFORCALL: {
524 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
525 L->top = ci->top; /* correct top */
526 break;
527 }
528 case OP_CALL: {
529 if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */
530 L->top = ci->top; /* adjust results */
531 break;
532 }
533 case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
534 break;
535 default: lua_assert(0);
536 }
537 }
538
539
540
541 /*
542 ** some macros for common tasks in `luaV_execute'
543 */
544
545 #if !defined luai_runtimecheck
546 #define luai_runtimecheck(L, c) /* void */
547 #endif
548
549
550 #define RA(i) (base+GETARG_A(i))
551 /* to be used after possible stack reallocation */
552 #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
553 #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
554 #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
555 ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
556 #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
557 ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
558 #define KBx(i) \
559 (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++)))
560
561
562 /* execute a jump instruction */
563 #define dojump(ci,i,e) \
564 { int a = GETARG_A(i); \
565 if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \
566 ci->u.l.savedpc += GETARG_sBx(i) + e; }
567
568 /* for test instructions, execute the jump instruction that follows it */
569 #define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); }
570
571
572 #define Protect(x) { {x;}; base = ci->u.l.base; }
573
574 #define checkGC(L,c) \
575 Protect( luaC_condGC(L,{L->top = (c); /* limit of live values */ \
576 luaC_step(L); \
577 L->top = ci->top;}) /* restore top */ \
578 luai_threadyield(L); )
579
580
581 #define arith_op(op,tm) { \
582 TValue *rb = RKB(i); \
583 TValue *rc = RKC(i); \
584 if (ttisnumber(rb) && ttisnumber(rc)) { \
585 lua_Number nb = nvalue(rb), nc = nvalue(rc); \
586 setnvalue(ra, op(L, nb, nc)); \
587 } \
588 else { Protect(luaV_arith(L, ra, rb, rc, tm)); } }
589
590
591 #define vmdispatch(o) switch(o)
592 #define vmcase(l,b) case l: {b} break;
593 #define vmcasenb(l,b) case l: {b} /* nb = no break */
594
595 void luaV_execute (lua_State *L) {
596 CallInfo *ci = L->ci;
597 LClosure *cl;
598 TValue *k;
599 StkId base;
600 newframe: /* reentry point when frame changes (call/return) */
601 lua_assert(ci == L->ci);
602 cl = clLvalue(ci->func);
603 k = cl->p->k;
604 base = ci->u.l.base;
605 /* main loop of interpreter */
606 for (;;) {
607 Instruction i = *(ci->u.l.savedpc++);
608 StkId ra;
609 if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
610 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
611 Protect(traceexec(L));
612 }
613 /* WARNING: several calls may realloc the stack and invalidate `ra' */
614 ra = RA(i);
615 lua_assert(base == ci->u.l.base);
616 lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
617 vmdispatch (GET_OPCODE(i)) {
618 vmcase(OP_MOVE,
619 setobjs2s(L, ra, RB(i));
620 )
621 vmcase(OP_LOADK,
622 TValue *rb = k + GETARG_Bx(i);
623 setobj2s(L, ra, rb);
624 )
625 vmcase(OP_LOADKX,
626 TValue *rb;
627 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
628 rb = k + GETARG_Ax(*ci->u.l.savedpc++);
629 setobj2s(L, ra, rb);
630 )
631 vmcase(OP_LOADBOOL,
632 setbvalue(ra, GETARG_B(i));
633 if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */
634 )
635 vmcase(OP_LOADNIL,
636 int b = GETARG_B(i);
637 do {
638 setnilvalue(ra++);
639 } while (b--);
640 )
641 vmcase(OP_GETUPVAL,
642 int b = GETARG_B(i);
643 setobj2s(L, ra, cl->upvals[b]->v);
644 )
645 vmcase(OP_GETTABUP,
646 int b = GETARG_B(i);
647 Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
648 )
649 vmcase(OP_GETTABLE,
650 Protect(luaV_gettable(L, RB(i), RKC(i), ra));
651 )
652 vmcase(OP_SETTABUP,
653 int a = GETARG_A(i);
654 Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i)));
655 )
656 vmcase(OP_SETUPVAL,
657 UpVal *uv = cl->upvals[GETARG_B(i)];
658 setobj(L, uv->v, ra);
659 luaC_barrier(L, uv, ra);
660 )
661 vmcase(OP_SETTABLE,
662 Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
663 )
664 vmcase(OP_NEWTABLE,
665 int b = GETARG_B(i);
666 int c = GETARG_C(i);
667 Table *t = luaH_new(L);
668 sethvalue(L, ra, t);
669 if (b != 0 || c != 0)
670 luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
671 checkGC(L, ra + 1);
672 )
673 vmcase(OP_SELF,
674 StkId rb = RB(i);
675 setobjs2s(L, ra+1, rb);
676 Protect(luaV_gettable(L, rb, RKC(i), ra));
677 )
678 vmcase(OP_ADD,
679 arith_op(luai_numadd, TM_ADD);
680 )
681 vmcase(OP_SUB,
682 arith_op(luai_numsub, TM_SUB);
683 )
684 vmcase(OP_MUL,
685 arith_op(luai_nummul, TM_MUL);
686 )
687 /*
688 * Patched: use luaV_* instead of luai_* to handle div/mod by 0
689 */
690 vmcase(OP_DIV,
691 arith_op(luaV_div, TM_DIV);
692 )
693 vmcase(OP_MOD,
694 arith_op(luaV_mod, TM_MOD);
695 )
696 vmcase(OP_POW,
697 arith_op(luai_numpow, TM_POW);
698 )
699 vmcase(OP_UNM,
700 TValue *rb = RB(i);
701 if (ttisnumber(rb)) {
702 lua_Number nb = nvalue(rb);
703 setnvalue(ra, luai_numunm(L, nb));
704 }
705 else {
706 Protect(luaV_arith(L, ra, rb, rb, TM_UNM));
707 }
708 )
709 vmcase(OP_NOT,
710 TValue *rb = RB(i);
711 int res = l_isfalse(rb); /* next assignment may change this value */
712 setbvalue(ra, res);
713 )
714 vmcase(OP_LEN,
715 Protect(luaV_objlen(L, ra, RB(i)));
716 )
717 vmcase(OP_CONCAT,
718 int b = GETARG_B(i);
719 int c = GETARG_C(i);
720 StkId rb;
721 L->top = base + c + 1; /* mark the end of concat operands */
722 Protect(luaV_concat(L, c - b + 1));
723 ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */
724 rb = b + base;
725 setobjs2s(L, ra, rb);
726 checkGC(L, (ra >= rb ? ra + 1 : rb));
727 L->top = ci->top; /* restore top */
728 )
729 vmcase(OP_JMP,
730 dojump(ci, i, 0);
731 )
732 vmcase(OP_EQ,
733 TValue *rb = RKB(i);
734 TValue *rc = RKC(i);
735 Protect(
736 if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i))
737 ci->u.l.savedpc++;
738 else
739 donextjump(ci);
740 )
741 )
742 vmcase(OP_LT,
743 Protect(
744 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i))
745 ci->u.l.savedpc++;
746 else
747 donextjump(ci);
748 )
749 )
750 vmcase(OP_LE,
751 Protect(
752 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i))
753 ci->u.l.savedpc++;
754 else
755 donextjump(ci);
756 )
757 )
758 vmcase(OP_TEST,
759 if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra))
760 ci->u.l.savedpc++;
761 else
762 donextjump(ci);
763 )
764 vmcase(OP_TESTSET,
765 TValue *rb = RB(i);
766 if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb))
767 ci->u.l.savedpc++;
768 else {
769 setobjs2s(L, ra, rb);
770 donextjump(ci);
771 }
772 )
773 vmcase(OP_CALL,
774 int b = GETARG_B(i);
775 int nresults = GETARG_C(i) - 1;
776 if (b != 0) L->top = ra+b; /* else previous instruction set top */
777 if (luaD_precall(L, ra, nresults)) { /* C function? */
778 if (nresults >= 0) L->top = ci->top; /* adjust results */
779 base = ci->u.l.base;
780 }
781 else { /* Lua function */
782 ci = L->ci;
783 ci->callstatus |= CIST_REENTRY;
784 goto newframe; /* restart luaV_execute over new Lua function */
785 }
786 )
787 vmcase(OP_TAILCALL,
788 int b = GETARG_B(i);
789 if (b != 0) L->top = ra+b; /* else previous instruction set top */
790 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
791 if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */
792 base = ci->u.l.base;
793 else {
794 /* tail call: put called frame (n) in place of caller one (o) */
795 CallInfo *nci = L->ci; /* called frame */
796 CallInfo *oci = nci->previous; /* caller frame */
797 StkId nfunc = nci->func; /* called function */
798 StkId ofunc = oci->func; /* caller function */
799 /* last stack slot filled by 'precall' */
800 StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
801 int aux;
802 /* close all upvalues from previous call */
803 if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
804 /* move new frame into old one */
805 for (aux = 0; nfunc + aux < lim; aux++)
806 setobjs2s(L, ofunc + aux, nfunc + aux);
807 oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */
808 oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */
809 oci->u.l.savedpc = nci->u.l.savedpc;
810 oci->callstatus |= CIST_TAIL; /* function was tail called */
811 ci = L->ci = oci; /* remove new frame */
812 lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
813 goto newframe; /* restart luaV_execute over new Lua function */
814 }
815 )
816 vmcasenb(OP_RETURN,
817 int b = GETARG_B(i);
818 if (b != 0) L->top = ra+b-1;
819 if (cl->p->sizep > 0) luaF_close(L, base);
820 b = luaD_poscall(L, ra);
821 if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */
822 return; /* external invocation: return */
823 else { /* invocation via reentry: continue execution */
824 ci = L->ci;
825 if (b) L->top = ci->top;
826 lua_assert(isLua(ci));
827 lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
828 goto newframe; /* restart luaV_execute over new Lua function */
829 }
830 )
831 vmcase(OP_FORLOOP,
832 lua_Number step = nvalue(ra+2);
833 lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
834 lua_Number limit = nvalue(ra+1);
835 if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
836 : luai_numle(L, limit, idx)) {
837 ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
838 setnvalue(ra, idx); /* update internal index... */
839 setnvalue(ra+3, idx); /* ...and external index */
840 }
841 )
842 vmcase(OP_FORPREP,
843 const TValue *init = ra;
844 const TValue *plimit = ra+1;
845 const TValue *pstep = ra+2;
846 if (!tonumber(init, ra))
847 luaG_runerror(L, LUA_QL("for") " initial value must be a number");
848 else if (!tonumber(plimit, ra+1))
849 luaG_runerror(L, LUA_QL("for") " limit must be a number");
850 else if (!tonumber(pstep, ra+2))
851 luaG_runerror(L, LUA_QL("for") " step must be a number");
852 setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
853 ci->u.l.savedpc += GETARG_sBx(i);
854 )
855 vmcasenb(OP_TFORCALL,
856 StkId cb = ra + 3; /* call base */
857 setobjs2s(L, cb+2, ra+2);
858 setobjs2s(L, cb+1, ra+1);
859 setobjs2s(L, cb, ra);
860 L->top = cb + 3; /* func. + 2 args (state and index) */
861 Protect(luaD_call(L, cb, GETARG_C(i), 1));
862 L->top = ci->top;
863 i = *(ci->u.l.savedpc++); /* go to next instruction */
864 ra = RA(i);
865 lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
866 goto l_tforloop;
867 )
868 vmcase(OP_TFORLOOP,
869 l_tforloop:
870 if (!ttisnil(ra + 1)) { /* continue loop? */
871 setobjs2s(L, ra, ra + 1); /* save control variable */
872 ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
873 }
874 )
875 vmcase(OP_SETLIST,
876 int n = GETARG_B(i);
877 int c = GETARG_C(i);
878 int last;
879 Table *h;
880 if (n == 0) n = cast_int(L->top - ra) - 1;
881 if (c == 0) {
882 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
883 c = GETARG_Ax(*ci->u.l.savedpc++);
884 }
885 luai_runtimecheck(L, ttistable(ra));
886 h = hvalue(ra);
887 last = ((c-1)*LFIELDS_PER_FLUSH) + n;
888 if (last > h->sizearray) /* needs more space? */
889 luaH_resizearray(L, h, last); /* pre-allocate it at once */
890 for (; n > 0; n--) {
891 TValue *val = ra+n;
892 luaH_setint(L, h, last--, val);
893 luaC_barrierback(L, obj2gco(h), val);
894 }
895 L->top = ci->top; /* correct top (in case of previous open call) */
896 )
897 vmcase(OP_CLOSURE,
898 Proto *p = cl->p->p[GETARG_Bx(i)];
899 Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */
900 if (ncl == NULL) /* no match? */
901 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
902 else
903 setclLvalue(L, ra, ncl); /* push cashed closure */
904 checkGC(L, ra + 1);
905 )
906 vmcase(OP_VARARG,
907 int b = GETARG_B(i) - 1;
908 int j;
909 int n = cast_int(base - ci->func) - cl->p->numparams - 1;
910 if (b < 0) { /* B == 0? */
911 b = n; /* get all var. arguments */
912 Protect(luaD_checkstack(L, n));
913 ra = RA(i); /* previous call may change the stack */
914 L->top = ra + n;
915 }
916 for (j = 0; j < b; j++) {
917 if (j < n) {
918 setobjs2s(L, ra + j, base - n + j);
919 }
920 else {
921 setnilvalue(ra + j);
922 }
923 }
924 )
925 vmcase(OP_EXTRAARG,
926 lua_assert(0);
927 )
928 }
929 }
930 }
931
932 /*
933 * this can live in SPL
934 */
935 #if BITS_PER_LONG == 32
936 #if defined(_KERNEL) && !defined(SPL_HAS_MODDI3)
937 extern uint64_t __umoddi3(uint64_t dividend, uint64_t divisor);
938
939 /* 64-bit signed modulo for 32-bit machines. */
940 int64_t
941 __moddi3(int64_t n, int64_t d)
942 {
943 int64_t q;
944 boolean_t nn = B_FALSE;
945
946 if (n < 0) {
947 nn = B_TRUE;
948 n = -n;
949 }
950 if (d < 0)
951 d = -d;
952
953 q = __umoddi3(n, d);
954
955 return (nn ? -q : q);
956 }
957 EXPORT_SYMBOL(__moddi3);
958 #endif
959 #endif
960 /* END CSTYLED */