diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-12-30 18:47:58 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-12-30 18:47:58 -0200 |
| commit | 1ea2d20f74cea9c61817d4a5ed67c4fc47cafb51 (patch) | |
| tree | bdedb3205963f8db43391aaef5be853cdeb59df4 /lvm.c | |
| parent | f5133aa1a55cee96b535ff788764437deacdc26a (diff) | |
| download | lua-1ea2d20f74cea9c61817d4a5ed67c4fc47cafb51.tar.gz lua-1ea2d20f74cea9c61817d4a5ed67c4fc47cafb51.tar.bz2 lua-1ea2d20f74cea9c61817d4a5ed67c4fc47cafb51.zip | |
first implementation of '<<', '>>', and '~' (bitwise not)
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 51 |
1 files changed, 48 insertions, 3 deletions
| @@ -1,10 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.181 2013/12/16 14:30:22 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.182 2013/12/18 14:12:03 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 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | #include <limits.h> | ||
| 8 | #include <stdio.h> | 9 | #include <stdio.h> |
| 9 | #include <stdlib.h> | 10 | #include <stdlib.h> |
| 10 | #include <string.h> | 11 | #include <string.h> |
| @@ -379,6 +380,21 @@ lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y) { | |||
| 379 | } | 380 | } |
| 380 | 381 | ||
| 381 | 382 | ||
| 383 | /* number of bits in an integer */ | ||
| 384 | #define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) | ||
| 385 | |||
| 386 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { | ||
| 387 | if (y < 0) { /* shift right? */ | ||
| 388 | if (y <= -NBITS) return 0; | ||
| 389 | else return cast_integer(cast_unsigned(x) >> (-y)); | ||
| 390 | } | ||
| 391 | else { /* shift left */ | ||
| 392 | if (y >= NBITS) return 0; | ||
| 393 | else return x << y; | ||
| 394 | } | ||
| 395 | } | ||
| 396 | |||
| 397 | |||
| 382 | /* | 398 | /* |
| 383 | ** check whether cached closure in prototype 'p' may be reused, that is, | 399 | ** check whether cached closure in prototype 'p' may be reused, that is, |
| 384 | ** whether there is a cached closure with the same upvalues needed by | 400 | ** whether there is a cached closure with the same upvalues needed by |
| @@ -437,8 +453,9 @@ void luaV_finishOp (lua_State *L) { | |||
| 437 | OpCode op = GET_OPCODE(inst); | 453 | OpCode op = GET_OPCODE(inst); |
| 438 | switch (op) { /* finish its execution */ | 454 | switch (op) { /* finish its execution */ |
| 439 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: | 455 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: |
| 440 | case OP_BAND: case OP_BOR: case OP_BXOR: | 456 | case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: |
| 441 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | 457 | case OP_MOD: case OP_POW: |
| 458 | case OP_UNM: case OP_BNOT: case OP_LEN: | ||
| 442 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { | 459 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { |
| 443 | setobjs2s(L, base + GETARG_A(inst), --L->top); | 460 | setobjs2s(L, base + GETARG_A(inst), --L->top); |
| 444 | break; | 461 | break; |
| @@ -699,6 +716,24 @@ void luaV_execute (lua_State *L) { | |||
| 699 | } | 716 | } |
| 700 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } | 717 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } |
| 701 | ) | 718 | ) |
| 719 | vmcase(OP_SHL, | ||
| 720 | TValue *rb = RKB(i); | ||
| 721 | TValue *rc = RKC(i); | ||
| 722 | lua_Integer ib; lua_Integer ic; | ||
| 723 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 724 | setivalue(ra, luaV_shiftl(ib, ic)); | ||
| 725 | } | ||
| 726 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); } | ||
| 727 | ) | ||
| 728 | vmcase(OP_SHR, | ||
| 729 | TValue *rb = RKB(i); | ||
| 730 | TValue *rc = RKC(i); | ||
| 731 | lua_Integer ib; lua_Integer ic; | ||
| 732 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 733 | setivalue(ra, luaV_shiftl(ib, -ic)); | ||
| 734 | } | ||
| 735 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); } | ||
| 736 | ) | ||
| 702 | vmcase(OP_MOD, | 737 | vmcase(OP_MOD, |
| 703 | TValue *rb = RKB(i); | 738 | TValue *rb = RKB(i); |
| 704 | TValue *rc = RKC(i); | 739 | TValue *rc = RKC(i); |
| @@ -739,6 +774,16 @@ void luaV_execute (lua_State *L) { | |||
| 739 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); | 774 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); |
| 740 | } | 775 | } |
| 741 | ) | 776 | ) |
| 777 | vmcase(OP_BNOT, | ||
| 778 | TValue *rb = RB(i); | ||
| 779 | lua_Integer ib; | ||
| 780 | if (tointeger(rb, &ib)) { | ||
| 781 | setivalue(ra, intop(^, cast_integer(-1), ib)); | ||
| 782 | } | ||
| 783 | else { | ||
| 784 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); | ||
| 785 | } | ||
| 786 | ) | ||
| 742 | vmcase(OP_NOT, | 787 | vmcase(OP_NOT, |
| 743 | TValue *rb = RB(i); | 788 | TValue *rb = RB(i); |
| 744 | int res = l_isfalse(rb); /* next assignment may change this value */ | 789 | int res = l_isfalse(rb); /* next assignment may change this value */ |
