diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 476 |
1 files changed, 231 insertions, 245 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.177 2001/03/26 14:31:49 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.178 2001/04/06 18:25:00 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -28,15 +28,14 @@ | |||
28 | 28 | ||
29 | 29 | ||
30 | 30 | ||
31 | int luaV_tonumber (TObject *obj) { | 31 | const TObject *luaV_tonumber (const TObject *obj, TObject *n) { |
32 | if (ttype(obj) != LUA_TSTRING) | 32 | if (ttype(obj) == LUA_TNUMBER) return obj; |
33 | return 1; | 33 | if (ttype(obj) == LUA_TSTRING && luaO_str2d(svalue(obj), &nvalue(n))) { |
34 | else { | 34 | ttype(n) = LUA_TNUMBER; |
35 | if (!luaO_str2d(svalue(obj), &nvalue(obj))) | 35 | return n; |
36 | return 2; | ||
37 | ttype(obj) = LUA_TNUMBER; | ||
38 | return 0; | ||
39 | } | 36 | } |
37 | else | ||
38 | return NULL; | ||
40 | } | 39 | } |
41 | 40 | ||
42 | 41 | ||
@@ -148,8 +147,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { | |||
148 | } | 147 | } |
149 | } | 148 | } |
150 | /* else will call the tag method */ | 149 | /* else will call the tag method */ |
151 | } | 150 | } else { /* not a table; try a `gettable' tag method */ |
152 | else { /* not a table; try a `gettable' tag method */ | ||
153 | tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); | 151 | tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); |
154 | if (tm == NULL) /* no tag method? */ | 152 | if (tm == NULL) /* no tag method? */ |
155 | luaG_typeerror(L, t, l_s("index")); | 153 | luaG_typeerror(L, t, l_s("index")); |
@@ -162,7 +160,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { | |||
162 | /* | 160 | /* |
163 | ** Receives table at `t', key at `key' and value at `val'. | 161 | ** Receives table at `t', key at `key' and value at `val'. |
164 | */ | 162 | */ |
165 | void luaV_settable (lua_State *L, StkId t, StkId key, StkId val) { | 163 | void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { |
166 | Closure *tm; | 164 | Closure *tm; |
167 | if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ | 165 | if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ |
168 | int tg = hvalue(t)->htag; | 166 | int tg = hvalue(t)->htag; |
@@ -172,8 +170,7 @@ void luaV_settable (lua_State *L, StkId t, StkId key, StkId val) { | |||
172 | return; | 170 | return; |
173 | } | 171 | } |
174 | /* else will call the tag method */ | 172 | /* else will call the tag method */ |
175 | } | 173 | } else { /* not a table; try a `settable' tag method */ |
176 | else { /* not a table; try a `settable' tag method */ | ||
177 | tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); | 174 | tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); |
178 | if (tm == NULL) /* no tag method? */ | 175 | if (tm == NULL) /* no tag method? */ |
179 | luaG_typeerror(L, t, l_s("index")); | 176 | luaG_typeerror(L, t, l_s("index")); |
@@ -188,8 +185,7 @@ void luaV_getglobal (lua_State *L, TString *name, StkId res) { | |||
188 | if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */ | 185 | if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */ |
189 | (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) { | 186 | (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) { |
190 | setobj(res, value); /* default behavior */ | 187 | setobj(res, value); /* default behavior */ |
191 | } | 188 | } else |
192 | else | ||
193 | callTM(L, l_s("csor"), tm, name, value, res); | 189 | callTM(L, l_s("csor"), tm, name, value, res); |
194 | } | 190 | } |
195 | 191 | ||
@@ -200,8 +196,7 @@ void luaV_setglobal (lua_State *L, TString *name, StkId val) { | |||
200 | if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */ | 196 | if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */ |
201 | (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) { | 197 | (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) { |
202 | setobj(oldvalue, val); /* raw set */ | 198 | setobj(oldvalue, val); /* raw set */ |
203 | } | 199 | } else |
204 | else | ||
205 | callTM(L, l_s("csoo"), tm, name, oldvalue, val); | 200 | callTM(L, l_s("csoo"), tm, name, oldvalue, val); |
206 | } | 201 | } |
207 | 202 | ||
@@ -224,9 +219,10 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, | |||
224 | } | 219 | } |
225 | 220 | ||
226 | 221 | ||
227 | static void call_arith (lua_State *L, StkId p1, TMS event) { | 222 | static void call_arith (lua_State *L, StkId p1, TObject *p2, |
228 | if (!call_binTM(L, p1, p1+1, p1, event)) | 223 | StkId res, TMS event) { |
229 | luaG_binerror(L, p1, LUA_TNUMBER, l_s("perform arithmetic on")); | 224 | if (!call_binTM(L, p1, p2, res, event)) |
225 | luaG_aritherror(L, p1, p2); | ||
230 | } | 226 | } |
231 | 227 | ||
232 | 228 | ||
@@ -270,9 +266,8 @@ void luaV_strconc (lua_State *L, int total, StkId top) { | |||
270 | int n = 2; /* number of elements handled in this pass (at least 2) */ | 266 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
271 | if (tostring(L, top-2) || tostring(L, top-1)) { | 267 | if (tostring(L, top-2) || tostring(L, top-1)) { |
272 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) | 268 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) |
273 | luaG_binerror(L, top-2, LUA_TSTRING, l_s("concat")); | 269 | luaG_concaterror(L, top-2, top-1); |
274 | } | 270 | } else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ |
275 | else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ | ||
276 | /* at least two string values; get as many as possible */ | 271 | /* at least two string values; get as many as possible */ |
277 | lu_mem tl = (lu_mem)tsvalue(top-1)->len + (lu_mem)tsvalue(top-2)->len; | 272 | lu_mem tl = (lu_mem)tsvalue(top-1)->len + (lu_mem)tsvalue(top-2)->len; |
278 | l_char *buffer; | 273 | l_char *buffer; |
@@ -321,7 +316,32 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | |||
321 | 316 | ||
322 | 317 | ||
323 | 318 | ||
324 | #define dojump(pc, i) ((pc) += GETARG_S(i)) | 319 | /* |
320 | ** some macros for common tasks in `luaV_execute' | ||
321 | */ | ||
322 | |||
323 | #define runtime_check(L, c) { if (!(c)) return L->top; } | ||
324 | |||
325 | #define RA(i) (base+GETARG_A(i)) | ||
326 | #define RB(i) (base+GETARG_B(i)) | ||
327 | #define RC(i) (base+GETARG_C(i)) | ||
328 | #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \ | ||
329 | base+GETARG_C(i) : \ | ||
330 | tf->k+GETARG_C(i)-MAXSTACK) | ||
331 | #define KBc(i) (tf->k+GETARG_Bc(i)) | ||
332 | |||
333 | #define Arith(op, optm) { \ | ||
334 | const TObject *b = RB(i); const TObject *c = RKC(i); \ | ||
335 | TObject tempb, tempc; \ | ||
336 | if ((ttype(b) == LUA_TNUMBER || (b = luaV_tonumber(b, &tempb)) != NULL) && \ | ||
337 | (ttype(c) == LUA_TNUMBER || (c = luaV_tonumber(c, &tempc)) != NULL)) { \ | ||
338 | setnvalue(RA(i), nvalue(b) op nvalue(c)); \ | ||
339 | } else \ | ||
340 | call_arith(L, RB(i), RKC(i), RA(i), optm); \ | ||
341 | } | ||
342 | |||
343 | |||
344 | #define dojump(pc, i) ((pc) += GETARG_sBc(i)) | ||
325 | 345 | ||
326 | /* | 346 | /* |
327 | ** Executes the given Lua function. Parameters are between [base,top). | 347 | ** Executes the given Lua function. Parameters are between [base,top). |
@@ -329,328 +349,294 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | |||
329 | */ | 349 | */ |
330 | StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | 350 | StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { |
331 | const Proto *const tf = cl->f.l; | 351 | const Proto *const tf = cl->f.l; |
332 | StkId top; /* keep top local, for performance */ | 352 | const Instruction *pc; |
333 | const Instruction *pc = tf->code; | 353 | lua_Hook linehook; |
334 | const lua_Hook linehook = L->linehook; | ||
335 | L->ci->pc = &pc; | ||
336 | if (tf->is_vararg) /* varargs? */ | 354 | if (tf->is_vararg) /* varargs? */ |
337 | adjust_varargs(L, base, tf->numparams); | 355 | adjust_varargs(L, base, tf->numparams); |
338 | luaD_adjusttop(L, base, tf->maxstacksize); | 356 | luaD_adjusttop(L, base, tf->maxstacksize); |
339 | top = base+tf->numparams+tf->is_vararg; | 357 | pc = tf->code; |
358 | L->ci->pc = &pc; | ||
359 | linehook = L->linehook; | ||
340 | /* main loop of interpreter */ | 360 | /* main loop of interpreter */ |
341 | for (;;) { | 361 | for (;;) { |
342 | const Instruction i = *pc++; | 362 | const Instruction i = *pc++; |
343 | lua_assert(L->top == base+tf->maxstacksize); | ||
344 | if (linehook) | 363 | if (linehook) |
345 | traceexec(L, linehook); | 364 | traceexec(L, linehook); |
346 | switch (GET_OPCODE(i)) { | 365 | switch (GET_OPCODE(i)) { |
347 | case OP_RETURN: { | 366 | case OP_MOVE: { |
348 | L->top = top; | 367 | setobj(RA(i), RB(i)); |
349 | return base+GETARG_U(i); | ||
350 | } | ||
351 | case OP_CALL: { | ||
352 | int nres = GETARG_B(i); | ||
353 | if (nres == MULT_RET) nres = LUA_MULTRET; | ||
354 | L->top = top; | ||
355 | luaD_call(L, base+GETARG_A(i), nres); | ||
356 | top = L->top; | ||
357 | L->top = base+tf->maxstacksize; | ||
358 | break; | ||
359 | } | ||
360 | case OP_PUSHNIL: { | ||
361 | int n = GETARG_U(i); | ||
362 | lua_assert(n>0); | ||
363 | do { | ||
364 | setnilvalue(top++); | ||
365 | } while (--n > 0); | ||
366 | break; | ||
367 | } | ||
368 | case OP_POP: { | ||
369 | top -= GETARG_U(i); | ||
370 | break; | ||
371 | } | ||
372 | case OP_PUSHINT: { | ||
373 | setnvalue(top, (lua_Number)GETARG_S(i)); | ||
374 | top++; | ||
375 | break; | ||
376 | } | ||
377 | case OP_PUSHSTRING: { | ||
378 | setsvalue(top, tf->kstr[GETARG_U(i)]); | ||
379 | top++; | ||
380 | break; | 368 | break; |
381 | } | 369 | } |
382 | case OP_PUSHNUM: { | 370 | case OP_LOADK: { |
383 | setnvalue(top, tf->knum[GETARG_U(i)]); | 371 | setobj(RA(i), KBc(i)); |
384 | top++; | ||
385 | break; | 372 | break; |
386 | } | 373 | } |
387 | case OP_PUSHNEGNUM: { | 374 | case OP_LOADINT: { |
388 | setnvalue(top, -tf->knum[GETARG_U(i)]); | 375 | setnvalue(RA(i), (lua_Number)GETARG_sBc(i)); |
389 | top++; | ||
390 | break; | 376 | break; |
391 | } | 377 | } |
392 | case OP_PUSHUPVALUE: { | 378 | case OP_LOADUPVAL: { |
393 | setobj(top++, &cl->upvalue[GETARG_U(i)]); | 379 | setobj(RA(i), cl->upvalue+GETARG_Bc(i)); |
394 | break; | 380 | break; |
395 | } | 381 | } |
396 | case OP_GETLOCAL: { | 382 | case OP_LOADNIL: { |
397 | setobj(top++, base+GETARG_U(i)); | 383 | TObject *ra = RA(i); |
384 | TObject *rb = RB(i); | ||
385 | do { | ||
386 | setnilvalue(ra++); | ||
387 | } while (ra <= rb); | ||
398 | break; | 388 | break; |
399 | } | 389 | } |
400 | case OP_GETGLOBAL: { | 390 | case OP_GETGLOBAL: { |
401 | luaV_getglobal(L, tf->kstr[GETARG_U(i)], top); | 391 | lua_assert(ttype(KBc(i)) == LUA_TSTRING); |
402 | top++; | 392 | luaV_getglobal(L, tsvalue(KBc(i)), RA(i)); |
403 | break; | 393 | break; |
404 | } | 394 | } |
405 | case OP_GETTABLE: { | 395 | case OP_GETTABLE: { |
406 | top--; | 396 | luaV_gettable(L, RB(i), RKC(i), RA(i)); |
407 | luaV_gettable(L, top-1, top, top-1); | ||
408 | break; | ||
409 | } | ||
410 | case OP_GETDOTTED: { | ||
411 | setsvalue(top, tf->kstr[GETARG_U(i)]); | ||
412 | luaV_gettable(L, top-1, top, top-1); | ||
413 | break; | ||
414 | } | ||
415 | case OP_GETINDEXED: { | ||
416 | luaV_gettable(L, top-1, base+GETARG_U(i), top-1); | ||
417 | break; | ||
418 | } | ||
419 | case OP_PUSHSELF: { | ||
420 | setobj(top, top-1); | ||
421 | setsvalue(top+1, tf->kstr[GETARG_U(i)]); | ||
422 | luaV_gettable(L, top-1, top+1, top-1); | ||
423 | top++; | ||
424 | break; | ||
425 | } | ||
426 | case OP_CREATETABLE: { | ||
427 | luaC_checkGC(L); | ||
428 | sethvalue(top, luaH_new(L, GETARG_U(i))); | ||
429 | top++; | ||
430 | break; | ||
431 | } | ||
432 | case OP_SETLOCAL: { | ||
433 | setobj(base+GETARG_U(i), --top); | ||
434 | break; | 397 | break; |
435 | } | 398 | } |
436 | case OP_SETGLOBAL: { | 399 | case OP_SETGLOBAL: { |
437 | top--; | 400 | lua_assert(ttype(KBc(i)) == LUA_TSTRING); |
438 | luaV_setglobal(L, tf->kstr[GETARG_U(i)], top); | 401 | luaV_setglobal(L, tsvalue(KBc(i)), RA(i)); |
439 | break; | 402 | break; |
440 | } | 403 | } |
441 | case OP_SETTABLE: { | 404 | case OP_SETTABLE: { |
442 | StkId t = top-GETARG_A(i); | 405 | luaV_settable(L, RB(i), RKC(i), RA(i)); |
443 | luaV_settable(L, t, t+1, top-1); | ||
444 | top -= GETARG_B(i); /* pop values */ | ||
445 | break; | 406 | break; |
446 | } | 407 | } |
447 | case OP_SETLIST: { | 408 | case OP_NEWTABLE: { |
448 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; | 409 | luaC_checkGC(L); |
449 | TObject *t = base+GETARG_B(i); | 410 | sethvalue(RA(i), luaH_new(L, GETARG_Bc(i))); |
450 | Hash *h = hvalue(t); | ||
451 | int n; | ||
452 | for (n = top-t-1; n; n--) | ||
453 | setobj(luaH_setnum(L, h, n+aux), --top); | ||
454 | break; | 411 | break; |
455 | } | 412 | } |
456 | case OP_SETMAP: { | 413 | case OP_SELF: { |
457 | TObject *t = base+GETARG_U(i); | 414 | StkId ra = RA(i); |
458 | Hash *h = hvalue(t); | 415 | StkId rb = RB(i); |
459 | while (top-1 > t) { | 416 | setobj(ra+1, rb); |
460 | top-=2; | 417 | luaV_gettable(L, rb, RKC(i), ra); |
461 | setobj(luaH_set(L, h, top), top+1); | ||
462 | } | ||
463 | break; | 418 | break; |
464 | } | 419 | } |
465 | case OP_ADD: { | 420 | case OP_ADD: { |
466 | if (tonumber(top-2) || tonumber(top-1)) | 421 | Arith( + , TM_ADD); |
467 | call_arith(L, top-2, TM_ADD); | ||
468 | else | ||
469 | nvalue(top-2) += nvalue(top-1); | ||
470 | top--; | ||
471 | break; | ||
472 | } | ||
473 | case OP_ADDI: { | ||
474 | if (tonumber(top-1)) { | ||
475 | setnvalue(top, (lua_Number)GETARG_S(i)); | ||
476 | call_arith(L, top-1, TM_ADD); | ||
477 | } | ||
478 | else | ||
479 | nvalue(top-1) += (lua_Number)GETARG_S(i); | ||
480 | break; | 422 | break; |
481 | } | 423 | } |
482 | case OP_SUB: { | 424 | case OP_SUB: { |
483 | if (tonumber(top-2) || tonumber(top-1)) | 425 | Arith( - , TM_SUB); |
484 | call_arith(L, top-2, TM_SUB); | ||
485 | else | ||
486 | nvalue(top-2) -= nvalue(top-1); | ||
487 | top--; | ||
488 | break; | 426 | break; |
489 | } | 427 | } |
490 | case OP_MULT: { | 428 | case OP_MUL: { |
491 | if (tonumber(top-2) || tonumber(top-1)) | 429 | Arith( * , TM_MUL); |
492 | call_arith(L, top-2, TM_MUL); | ||
493 | else | ||
494 | nvalue(top-2) *= nvalue(top-1); | ||
495 | top--; | ||
496 | break; | 430 | break; |
497 | } | 431 | } |
498 | case OP_DIV: { | 432 | case OP_DIV: { |
499 | if (tonumber(top-2) || tonumber(top-1)) | 433 | Arith( / , TM_DIV); |
500 | call_arith(L, top-2, TM_DIV); | ||
501 | else | ||
502 | nvalue(top-2) /= nvalue(top-1); | ||
503 | top--; | ||
504 | break; | 434 | break; |
505 | } | 435 | } |
506 | case OP_POW: { | 436 | case OP_POW: { |
507 | if (!call_binTM(L, top-2, top-1, top-2, TM_POW)) | 437 | call_arith(L, RB(i), RKC(i), RA(i), TM_POW); |
508 | luaD_error(L, l_s("undefined operation")); | ||
509 | top--; | ||
510 | break; | 438 | break; |
511 | } | 439 | } |
512 | case OP_CONCAT: { | 440 | case OP_UNM: { |
513 | int n = GETARG_U(i); | 441 | const TObject *rb = RB(i); |
514 | luaV_strconc(L, n, top); | 442 | StkId ra = RA(i); |
515 | top -= n-1; | 443 | if (ttype(rb) == LUA_TNUMBER || (rb=luaV_tonumber(rb, ra)) != NULL) { |
516 | luaC_checkGC(L); | 444 | setnvalue(ra, -nvalue(rb)); |
517 | break; | 445 | } |
518 | } | 446 | else { |
519 | case OP_MINUS: { | 447 | TObject temp; |
520 | if (tonumber(top-1)) { | 448 | setnilvalue(&temp); |
521 | setnilvalue(top); | 449 | call_arith(L, RB(i), &temp, ra, TM_UNM); |
522 | call_arith(L, top-1, TM_UNM); | ||
523 | } | 450 | } |
524 | else | ||
525 | nvalue(top-1) = -nvalue(top-1); | ||
526 | break; | 451 | break; |
527 | } | 452 | } |
528 | case OP_NOT: { | 453 | case OP_NOT: { |
529 | ttype(top-1) = | 454 | if (ttype(RB(i)) == LUA_TNIL) { |
530 | (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL; | 455 | setnvalue(RA(i), 1); |
531 | nvalue(top-1) = 1; | 456 | } else { |
457 | setnilvalue(RA(i)); | ||
458 | } | ||
532 | break; | 459 | break; |
533 | } | 460 | } |
534 | case OP_JMPNE: { | 461 | case OP_CONCAT: { |
535 | top -= 2; | 462 | StkId top = RC(i)+1; |
536 | if (!luaO_equalObj(top, top+1)) dojump(pc, i); | 463 | StkId rb = RB(i); |
464 | luaV_strconc(L, top-rb, top); | ||
465 | setobj(RA(i), rb); | ||
466 | luaC_checkGC(L); | ||
537 | break; | 467 | break; |
538 | } | 468 | } |
539 | case OP_JMPEQ: { | 469 | case OP_CJMP: |
540 | top -= 2; | 470 | case OP_JMP: { |
541 | if (luaO_equalObj(top, top+1)) dojump(pc, i); | 471 | dojump(pc, i); |
542 | break; | 472 | break; |
543 | } | 473 | } |
544 | case OP_JMPLT: { | 474 | case OP_TESTEQ: { |
545 | top -= 2; | 475 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); |
546 | if (luaV_lessthan(L, top, top+1)) dojump(pc, i); | 476 | if (luaO_equalObj(RB(i), RKC(i))) dojump(pc, *pc); |
477 | pc++; | ||
547 | break; | 478 | break; |
548 | } | 479 | } |
549 | case OP_JMPLE: { /* a <= b === !(b<a) */ | 480 | case OP_TESTNE: { |
550 | top -= 2; | 481 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); |
551 | if (!luaV_lessthan(L, top+1, top)) dojump(pc, i); | 482 | if (!luaO_equalObj(RB(i), RKC(i))) dojump(pc, *pc); |
483 | pc++; | ||
552 | break; | 484 | break; |
553 | } | 485 | } |
554 | case OP_JMPGT: { /* a > b === (b<a) */ | 486 | case OP_TESTLT: { |
555 | top -= 2; | 487 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); |
556 | if (luaV_lessthan(L, top+1, top)) dojump(pc, i); | 488 | if (luaV_lessthan(L, RB(i), RKC(i))) dojump(pc, *pc); |
489 | pc++; | ||
557 | break; | 490 | break; |
558 | } | 491 | } |
559 | case OP_JMPGE: { /* a >= b === !(a<b) */ | 492 | case OP_TESTLE: { /* b <= c === !(c<b) */ |
560 | top -= 2; | 493 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); |
561 | if (!luaV_lessthan(L, top, top+1)) dojump(pc, i); | 494 | if (!luaV_lessthan(L, RKC(i), RB(i))) dojump(pc, *pc); |
495 | pc++; | ||
562 | break; | 496 | break; |
563 | } | 497 | } |
564 | case OP_JMPT: { | 498 | case OP_TESTGT: { /* b > c === (c<b) */ |
565 | if (ttype(--top) != LUA_TNIL) dojump(pc, i); | 499 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); |
500 | if (luaV_lessthan(L, RKC(i), RB(i))) dojump(pc, *pc); | ||
501 | pc++; | ||
566 | break; | 502 | break; |
567 | } | 503 | } |
568 | case OP_JMPF: { | 504 | case OP_TESTGE: { /* b >= c === !(b<c) */ |
569 | if (ttype(--top) == LUA_TNIL) dojump(pc, i); | 505 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); |
506 | if (!luaV_lessthan(L, RB(i), RKC(i))) dojump(pc, *pc); | ||
507 | pc++; | ||
570 | break; | 508 | break; |
571 | } | 509 | } |
572 | case OP_JMPONT: { | 510 | case OP_TESTT: { |
573 | if (ttype(top-1) == LUA_TNIL) top--; | 511 | StkId rb = RB(i); |
574 | else dojump(pc, i); | 512 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); |
513 | if (ttype(rb) != LUA_TNIL) { | ||
514 | int a = GETARG_A(i); | ||
515 | if (a != NO_REG) setobj(base+a, rb); | ||
516 | dojump(pc, *pc); | ||
517 | } | ||
518 | pc++; | ||
575 | break; | 519 | break; |
576 | } | 520 | } |
577 | case OP_JMPONF: { | 521 | case OP_TESTF: { |
578 | if (ttype(top-1) != LUA_TNIL) top--; | 522 | lua_assert(GET_OPCODE(*pc) == OP_CJMP); |
579 | else dojump(pc, i); | 523 | if (ttype(RB(i)) == LUA_TNIL) { |
524 | int a = GETARG_A(i); | ||
525 | if (a != NO_REG) setnilvalue(base+a); | ||
526 | dojump(pc, *pc); | ||
527 | } | ||
528 | pc++; | ||
580 | break; | 529 | break; |
581 | } | 530 | } |
582 | case OP_JMP: { | 531 | case OP_NILJMP: { |
583 | dojump(pc, i); | 532 | setnilvalue(RA(i)); |
533 | pc++; | ||
584 | break; | 534 | break; |
585 | } | 535 | } |
586 | case OP_PUSHNILJMP: { | 536 | case OP_CALL: { |
587 | setnilvalue(top++); | 537 | int nres; |
588 | pc++; | 538 | int b = GETARG_B(i); |
539 | if (b != NO_REG) | ||
540 | L->top = base+b; | ||
541 | nres = GETARG_C(i); | ||
542 | if (nres == NO_REG) nres = LUA_MULTRET; | ||
543 | luaD_call(L, RA(i), nres); | ||
544 | if (nres != LUA_MULTRET) { | ||
545 | lua_assert(L->top == RA(i)+nres); | ||
546 | L->top = base+tf->maxstacksize; | ||
547 | } | ||
589 | break; | 548 | break; |
590 | } | 549 | } |
550 | case OP_RETURN: { | ||
551 | int b = GETARG_B(i); | ||
552 | if (b != NO_REG) | ||
553 | L->top = base+b; | ||
554 | return RA(i); | ||
555 | } | ||
591 | case OP_FORPREP: { | 556 | case OP_FORPREP: { |
592 | int jmp = GETARG_S(i); | 557 | int jmp = GETARG_sBc(i); |
593 | if (tonumber(top-1)) | 558 | StkId breg = RA(i); |
594 | luaD_error(L, l_s("`for' step must be a number")); | 559 | if (luaV_tonumber(breg, breg) == NULL) |
595 | if (tonumber(top-2)) | ||
596 | luaD_error(L, l_s("`for' limit must be a number")); | ||
597 | if (tonumber(top-3)) | ||
598 | luaD_error(L, l_s("`for' initial value must be a number")); | 560 | luaD_error(L, l_s("`for' initial value must be a number")); |
561 | if (luaV_tonumber(breg+1, breg+1) == NULL) | ||
562 | luaD_error(L, l_s("`for' limit must be a number")); | ||
563 | if (luaV_tonumber(breg+2, breg+2) == NULL) | ||
564 | luaD_error(L, l_s("`for' step must be a number")); | ||
599 | pc += -jmp; /* `jump' to loop end (delta is negated here) */ | 565 | pc += -jmp; /* `jump' to loop end (delta is negated here) */ |
600 | goto forloop; /* do not increment index */ | 566 | nvalue(breg) -= nvalue(breg+2);/* decrement index (to be incremented) */ |
567 | /* go through */ | ||
601 | } | 568 | } |
602 | case OP_FORLOOP: { | 569 | case OP_FORLOOP: { |
603 | lua_assert(ttype(top-1) == LUA_TNUMBER); | 570 | StkId breg = RA(i); |
604 | lua_assert(ttype(top-2) == LUA_TNUMBER); | 571 | if (ttype(breg) != LUA_TNUMBER) |
605 | if (ttype(top-3) != LUA_TNUMBER) | ||
606 | luaD_error(L, l_s("`for' index must be a number")); | 572 | luaD_error(L, l_s("`for' index must be a number")); |
607 | nvalue(top-3) += nvalue(top-1); /* increment index */ | 573 | runtime_check(L, ttype(breg+1) == LUA_TNUMBER && |
608 | forloop: | 574 | ttype(breg+2) == LUA_TNUMBER); |
609 | if (nvalue(top-1) > 0 ? | 575 | nvalue(breg) += nvalue(breg+2); /* increment index */ |
610 | nvalue(top-3) > nvalue(top-2) : | 576 | if (nvalue(breg+2) > 0 ? |
611 | nvalue(top-3) < nvalue(top-2)) | 577 | nvalue(breg) <= nvalue(breg+1) : |
612 | top -= 3; /* end loop: remove control variables */ | 578 | nvalue(breg) >= nvalue(breg+1)) |
613 | else | ||
614 | dojump(pc, i); /* repeat loop */ | 579 | dojump(pc, i); /* repeat loop */ |
615 | break; | 580 | break; |
616 | } | 581 | } |
617 | case OP_LFORPREP: { | 582 | case OP_TFORPREP: { |
618 | int jmp = GETARG_S(i); | 583 | int jmp = GETARG_sBc(i); |
619 | if (ttype(top-1) != LUA_TTABLE) | 584 | StkId breg = RA(i); |
585 | if (ttype(breg) != LUA_TTABLE) | ||
620 | luaD_error(L, l_s("`for' table must be a table")); | 586 | luaD_error(L, l_s("`for' table must be a table")); |
621 | top += 3; /* index,key,value */ | 587 | setnvalue(breg+1, -1); /* initial index */ |
622 | setnvalue(top-3, -1); /* initial index */ | 588 | setnilvalue(breg+2); |
623 | setnilvalue(top-2); | 589 | setnilvalue(breg+3); |
624 | setnilvalue(top-1); | ||
625 | pc += -jmp; /* `jump' to loop end (delta is negated here) */ | 590 | pc += -jmp; /* `jump' to loop end (delta is negated here) */ |
626 | /* go through */ | 591 | /* go through */ |
627 | } | 592 | } |
628 | case OP_LFORLOOP: { | 593 | case OP_TFORLOOP: { |
629 | Hash *t = hvalue(top-4); | 594 | StkId breg = RA(i); |
630 | int n = (int)nvalue(top-3); | 595 | Hash *t; |
631 | lua_assert(ttype(top-3) == LUA_TNUMBER); | 596 | int n; |
632 | lua_assert(ttype(top-4) == LUA_TTABLE); | 597 | runtime_check(L, ttype(breg) == LUA_TTABLE); |
598 | runtime_check(L, ttype(breg+1) == LUA_TNUMBER); | ||
599 | t = hvalue(breg); | ||
600 | n = (int)nvalue(breg+1); | ||
633 | n = luaH_nexti(t, n); | 601 | n = luaH_nexti(t, n); |
634 | if (n == -1) /* end loop? */ | 602 | if (n != -1) { /* repeat loop? */ |
635 | top -= 4; /* remove table, index, key, and value */ | ||
636 | else { | ||
637 | Node *node = node(t, n); | 603 | Node *node = node(t, n); |
638 | setnvalue(top-3, n); /* index */ | 604 | setnvalue(breg+1, n); /* index */ |
639 | setkey2obj(top-2, node); | 605 | setkey2obj(breg+2, node); |
640 | setobj(top-1, val(node)); | 606 | setobj(breg+3, val(node)); |
641 | dojump(pc, i); /* repeat loop */ | 607 | dojump(pc, i); /* repeat loop */ |
642 | } | 608 | } |
643 | break; | 609 | break; |
644 | } | 610 | } |
611 | case OP_SETLIST: | ||
612 | case OP_SETLISTO: { | ||
613 | int bc; | ||
614 | int n; | ||
615 | Hash *h; | ||
616 | StkId ra = RA(i); | ||
617 | runtime_check(L, ttype(ra) == LUA_TTABLE); | ||
618 | h = hvalue(ra); | ||
619 | bc = GETARG_Bc(i); | ||
620 | if (GET_OPCODE(i) == OP_SETLIST) | ||
621 | n = (bc&(LFIELDS_PER_FLUSH-1)) + 1; | ||
622 | else | ||
623 | n = L->top - ra - 1; | ||
624 | bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */ | ||
625 | for (; n > 0; n--) | ||
626 | setobj(luaH_setnum(L, h, bc+n), ra+n); | ||
627 | break; | ||
628 | } | ||
645 | case OP_CLOSURE: { | 629 | case OP_CLOSURE: { |
646 | int nup = GETARG_B(i); | 630 | Proto *p = tf->kproto[GETARG_Bc(i)]; |
647 | luaC_checkGC(L); | 631 | int nup = p->nupvalues; |
648 | L->top = top; | 632 | StkId ra = RA(i); |
649 | luaV_Lclosure(L, tf->kproto[GETARG_A(i)], nup); | 633 | L->top = ra+nup; |
650 | top -= (nup-1); | 634 | luaV_Lclosure(L, p, nup); |
651 | L->top = base+tf->maxstacksize; | 635 | L->top = base+tf->maxstacksize; |
636 | luaC_checkGC(L); | ||
652 | break; | 637 | break; |
653 | } | 638 | } |
654 | } | 639 | } |
655 | } | 640 | } |
656 | } | 641 | } |
642 | |||