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