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 */ |