diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-08 21:19:22 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-08 21:19:22 -0300 |
commit | 88b306f495fa7034c708c6b75a355a6deee51c58 (patch) | |
tree | 7d8faaacd1f5c753ed9e77f0e2c8e27b9a002635 | |
parent | 563de491be90601f23a735aede89ea9a3ef86ee9 (diff) | |
download | lua-88b306f495fa7034c708c6b75a355a6deee51c58.tar.gz lua-88b306f495fa7034c708c6b75a355a6deee51c58.tar.bz2 lua-88b306f495fa7034c708c6b75a355a6deee51c58.zip |
some optimizations
-rw-r--r-- | lbuiltin.c | 11 | ||||
-rw-r--r-- | lcode.c | 12 | ||||
-rw-r--r-- | lopcodes.h | 57 | ||||
-rw-r--r-- | lparser.c | 20 | ||||
-rw-r--r-- | lvm.c | 76 | ||||
-rw-r--r-- | lvm.h | 4 |
6 files changed, 105 insertions, 75 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbuiltin.c,v 1.93 2000/02/22 18:12:46 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.94 2000/03/03 14:58:26 roberto Exp $ |
3 | ** Built-in functions | 3 | ** Built-in functions |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -553,13 +553,8 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a, | |||
553 | L->top--; | 553 | L->top--; |
554 | return (ttype(L->top) != LUA_T_NIL); | 554 | return (ttype(L->top) != LUA_T_NIL); |
555 | } | 555 | } |
556 | else { /* a < b? */ | 556 | else /* a < b? */ |
557 | int res; | 557 | return luaV_lessthan(L, a, b, L->top); |
558 | *(L->top) = *a; | ||
559 | *(L->top+1) = *b; | ||
560 | res = luaV_lessthan(L, L->top, L->top+1); | ||
561 | return res; | ||
562 | } | ||
563 | } | 558 | } |
564 | 559 | ||
565 | static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { | 560 | static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { |
@@ -88,6 +88,16 @@ static void luaK_sub (LexState *ls) { | |||
88 | } | 88 | } |
89 | 89 | ||
90 | 90 | ||
91 | static void luaK_conc (LexState *ls) { | ||
92 | Instruction *previous = previous_instruction(ls); | ||
93 | luaK_deltastack(ls, -1); | ||
94 | switch(GET_OPCODE(*previous)) { | ||
95 | case CONCOP: *previous = SETARG_U(*previous, GETARG_U(*previous)+1); break; | ||
96 | default: luaK_primitivecode(ls, CREATE_U(CONCOP, 2)); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | |||
91 | void luaK_retcode (LexState *ls, int nlocals, int nexps) { | 101 | void luaK_retcode (LexState *ls, int nlocals, int nexps) { |
92 | Instruction *previous = previous_instruction(ls); | 102 | Instruction *previous = previous_instruction(ls); |
93 | if (nexps > 0 && GET_OPCODE(*previous) == CALL) { | 103 | if (nexps > 0 && GET_OPCODE(*previous) == CALL) { |
@@ -286,7 +296,7 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) { | |||
286 | case '*': luaK_0(ls, MULTOP, -1); break; | 296 | case '*': luaK_0(ls, MULTOP, -1); break; |
287 | case '/': luaK_0(ls, DIVOP, -1); break; | 297 | case '/': luaK_0(ls, DIVOP, -1); break; |
288 | case '^': luaK_0(ls, POWOP, -1); break; | 298 | case '^': luaK_0(ls, POWOP, -1); break; |
289 | case CONC: luaK_0(ls, CONCOP, -1); break; | 299 | case CONC: luaK_conc(ls); break; |
290 | case EQ: luaK_0(ls, EQOP, -1); break; | 300 | case EQ: luaK_0(ls, EQOP, -1); break; |
291 | case NE: luaK_0(ls, NEQOP, -1); break; | 301 | case NE: luaK_0(ls, NEQOP, -1); break; |
292 | case '>': luaK_0(ls, GTOP, -1); break; | 302 | case '>': luaK_0(ls, GTOP, -1); break; |
@@ -24,34 +24,51 @@ | |||
24 | is the usigned value minus 2^23. | 24 | is the usigned value minus 2^23. |
25 | ===========================================================================*/ | 25 | ===========================================================================*/ |
26 | 26 | ||
27 | #define EXCESS_S (1<<23) /* == 2^23 */ | 27 | #define SIZE_OP 8 |
28 | #define SIZE_U 24 | ||
29 | #define POS_U 8 | ||
30 | #define SIZE_S 24 | ||
31 | #define POS_S 8 | ||
32 | #define SIZE_A 16 | ||
33 | #define POS_A 16 | ||
34 | #define SIZE_B 8 | ||
35 | #define POS_B 8 | ||
36 | |||
37 | #define EXCESS_S (1<<(SIZE_S-1)) /* == 2^23 */ | ||
38 | |||
39 | |||
40 | /* creates a mask with `n' 1 bits at position `p' */ | ||
41 | #define MASK1(n,p) ((~((~0ul)<<n))<<p) | ||
42 | |||
43 | /* creates a mask with `n' 0 bits at position `p' */ | ||
44 | #define MASK0(n,p) (~MASK1(n,p)) | ||
28 | 45 | ||
29 | /* | 46 | /* |
30 | ** the following macros help to manipulate instructions | 47 | ** the following macros help to manipulate instructions |
31 | */ | 48 | */ |
32 | 49 | ||
33 | #define MAXARG_U ((1<<24)-1) | 50 | #define MAXARG_U ((1<<SIZE_U)-1) |
34 | #define MAXARG_S ((1<<23)-1) | 51 | #define MAXARG_S ((1<<(SIZE_S-1))-1) /* `S' is signed */ |
35 | #define MAXARG_A ((1<<16)-1) | 52 | #define MAXARG_A ((1<<SIZE_A)-1) |
36 | #define MAXARG_B ((1<<8)-1) | 53 | #define MAXARG_B ((1<<SIZE_B)-1) |
37 | 54 | ||
38 | #define GET_OPCODE(i) ((OpCode)((i)&0xFF)) | 55 | #define GET_OPCODE(i) ((OpCode)((i)&MASK1(SIZE_OP,0))) |
39 | #define GETARG_U(i) ((int)((i)>>8)) | 56 | #define GETARG_U(i) ((int)((i)>>POS_U)) |
40 | #define GETARG_S(i) ((int)((i)>>8)-EXCESS_S) | 57 | #define GETARG_S(i) ((int)((i)>>POS_S)-EXCESS_S) |
41 | #define GETARG_A(i) ((int)((i)>>16)) | 58 | #define GETARG_A(i) ((int)((i)>>POS_A)) |
42 | #define GETARG_B(i) ((int)(((i)>>8) & 0xFF)) | 59 | #define GETARG_B(i) ((int)(((i)>>POS_B) & MASK1(SIZE_B,0))) |
43 | 60 | ||
44 | #define SET_OPCODE(i,o) (((i)&0xFFFFFF00u) | (Instruction)(o)) | 61 | #define SET_OPCODE(i,o) (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o)) |
45 | #define SETARG_U(i,u) (((i)&0x000000FFu) | ((Instruction)(u)<<8)) | 62 | #define SETARG_U(i,u) (((i)&MASK0(SIZE_U,POS_U)) | ((Instruction)(u)<<POS_U)) |
46 | #define SETARG_S(i,s) (((i)&0x000000FFu) | ((Instruction)((s)+EXCESS_S)<<8)) | 63 | #define SETARG_S(i,s) (((i)&MASK0(SIZE_S,POS_S)) | ((Instruction)((s)+EXCESS_S)<<POS_S)) |
47 | #define SETARG_A(i,a) (((i)&0x0000FFFFu) | ((Instruction)(a)<<16)) | 64 | #define SETARG_A(i,a) (((i)&MASK0(SIZE_A,POS_A)) | ((Instruction)(a)<<POS_A)) |
48 | #define SETARG_B(i,b) (((i)&0xFFFF00FFu) | ((Instruction)(b)<<8)) | 65 | #define SETARG_B(i,b) (((i)&MASK0(SIZE_B,POS_B)) | ((Instruction)(b)<<POS_B)) |
49 | 66 | ||
50 | #define CREATE_0(o) ((Instruction)(o)) | 67 | #define CREATE_0(o) ((Instruction)(o)) |
51 | #define CREATE_U(o,u) ((Instruction)(o) | (Instruction)(u)<<8) | 68 | #define CREATE_U(o,u) ((Instruction)(o) | (Instruction)(u)<<POS_U) |
52 | #define CREATE_S(o,s) ((Instruction)(o) | ((Instruction)(s)+EXCESS_S)<<8) | 69 | #define CREATE_S(o,s) ((Instruction)(o) | ((Instruction)(s)+EXCESS_S)<<POS_S) |
53 | #define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<16) \ | 70 | #define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<POS_A) \ |
54 | | ((Instruction)(b)<<8)) | 71 | | ((Instruction)(b)<<POS_B)) |
55 | 72 | ||
56 | 73 | ||
57 | /* | 74 | /* |
@@ -111,7 +128,7 @@ SUBOP,/* - y x x-y */ | |||
111 | MULTOP,/* - y x x*y */ | 128 | MULTOP,/* - y x x*y */ |
112 | DIVOP,/* - y x x/y */ | 129 | DIVOP,/* - y x x/y */ |
113 | POWOP,/* - y x x^y */ | 130 | POWOP,/* - y x x^y */ |
114 | CONCOP,/* - y x x..y */ | 131 | CONCOP,/* U v_u-v_1 v1..-..v_u */ |
115 | MINUSOP,/* - x -x */ | 132 | MINUSOP,/* - x -x */ |
116 | NOTOP,/* - x (x==nil)? 1 : nil */ | 133 | NOTOP,/* - x (x==nil)? 1 : nil */ |
117 | 134 | ||
@@ -716,7 +716,7 @@ static int get_priority (int op, int *rp) { | |||
716 | 716 | ||
717 | case '+': case '-': *rp = 5; return 5; | 717 | case '+': case '-': *rp = 5; return 5; |
718 | 718 | ||
719 | case CONC: *rp = 4; return 4; /* left associative (?) */ | 719 | case CONC: *rp = 3; return 4; /* right associative (?) */ |
720 | 720 | ||
721 | case EQ: case NE: case '>': case '<': case LE: case GE: | 721 | case EQ: case NE: case '>': case '<': case LE: case GE: |
722 | *rp = 2; return 2; | 722 | *rp = 2; return 2; |
@@ -941,18 +941,17 @@ static void namestat (LexState *ls) { | |||
941 | 941 | ||
942 | 942 | ||
943 | static void ifpart (LexState *ls, int line) { | 943 | static void ifpart (LexState *ls, int line) { |
944 | /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ | 944 | /* ifpart -> cond THEN block (ELSEIF ifpart | [ELSE block] END) */ |
945 | FuncState *fs = ls->fs; | 945 | FuncState *fs = ls->fs; |
946 | int c; /* address of the conditional jump */ | 946 | int c; /* address of the conditional jump */ |
947 | int je; /* address of the unconditional jump (to skip `else' part) */ | ||
948 | int elseinit; | 947 | int elseinit; |
949 | next(ls); /* skip IF or ELSEIF */ | 948 | next(ls); /* skip IF or ELSEIF */ |
950 | exp1(ls); /* cond */ | 949 | exp1(ls); /* cond */ |
951 | c = luaK_S(ls, IFFJMP, 0, -1); /* jump over `then' part if `cond' is false */ | 950 | c = luaK_S(ls, IFFJMP, 0, -1); /* 1st jump: over `then' part */ |
952 | check(ls, THEN); | 951 | check(ls, THEN); |
953 | block(ls); /* `then' part */ | 952 | block(ls); /* `then' part */ |
954 | je = luaK_S(ls, JMP, 0, 0); /* jump over `else' part after `then' */ | 953 | luaK_S(ls, JMP, 0, 0); /* 2nd jump: over `else' part */ |
955 | elseinit = luaK_getlabel(ls); | 954 | elseinit = luaK_getlabel(ls); /* address of 2nd jump == elseinit-1 */ |
956 | if (ls->token == ELSEIF) | 955 | if (ls->token == ELSEIF) |
957 | ifpart(ls, line); | 956 | ifpart(ls, line); |
958 | else { | 957 | else { |
@@ -961,13 +960,12 @@ static void ifpart (LexState *ls, int line) { | |||
961 | check_match(ls, END, IF, line); | 960 | check_match(ls, END, IF, line); |
962 | } | 961 | } |
963 | if (fs->pc > elseinit) { /* is there an `else' part? */ | 962 | if (fs->pc > elseinit) { /* is there an `else' part? */ |
964 | luaK_fixjump(ls, je, luaK_getlabel(ls)); /* last jump jumps over it */ | 963 | luaK_fixjump(ls, c, elseinit); /* fix 1st jump to `else' part */ |
965 | luaK_fixjump(ls, c, elseinit); /* fix first jump to `else' part */ | 964 | luaK_fixjump(ls, elseinit-1, luaK_getlabel(ls)); /* fix 2nd jump */ |
966 | } | 965 | } |
967 | else { /* no else part */ | 966 | else { /* no else part */ |
968 | fs->pc--; /* remove last jump */ | 967 | fs->pc--; /* remove 2nd jump */ |
969 | LUA_ASSERT(L, fs->pc == je, "jump out of place"); | 968 | luaK_fixjump(ls, c, luaK_getlabel(ls)); /* fix 1st jump to `if' end */ |
970 | luaK_fixjump(ls, c, luaK_getlabel(ls)); /* fix first jump to `if' end */ | ||
971 | } | 969 | } |
972 | } | 970 | } |
973 | 971 | ||
@@ -39,17 +39,6 @@ | |||
39 | 39 | ||
40 | 40 | ||
41 | 41 | ||
42 | static TaggedString *strconc (lua_State *L, const TaggedString *l, | ||
43 | const TaggedString *r) { | ||
44 | long nl = l->u.s.len; | ||
45 | long nr = r->u.s.len; | ||
46 | char *buffer = luaL_openspace(L, nl+nr); | ||
47 | memcpy(buffer, l->str, nl); | ||
48 | memcpy(buffer+nl, r->str, nr); | ||
49 | return luaS_newlstr(L, buffer, nl+nr); | ||
50 | } | ||
51 | |||
52 | |||
53 | int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */ | 42 | int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */ |
54 | if (ttype(obj) != LUA_T_STRING) | 43 | if (ttype(obj) != LUA_T_STRING) |
55 | return 1; | 44 | return 1; |
@@ -253,22 +242,16 @@ static int luaV_strcomp (const TaggedString *ls, const TaggedString *rs) { | |||
253 | } | 242 | } |
254 | 243 | ||
255 | 244 | ||
256 | int luaV_lessthan (lua_State *L, TObject *l, TObject *r) { | 245 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) { |
257 | if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) | 246 | if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) |
258 | return (nvalue(l) < nvalue(r)); | 247 | return (nvalue(l) < nvalue(r)); |
259 | else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING) | 248 | else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING) |
260 | return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0); | 249 | return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0); |
261 | else { | 250 | else { /* call TM */ |
262 | /* update top and put arguments in correct order to call TM */ | 251 | luaD_checkstack(L, 2); |
263 | if (l<r) /* are arguments in correct order? */ | 252 | *top++ = *l; |
264 | L->top = r+1; /* yes; 2nd is on top */ | 253 | *top++ = *r; |
265 | else { /* no; exchange them */ | 254 | call_binTM(L, top, IM_LT, "unexpected type in comparison"); |
266 | TObject temp = *r; | ||
267 | *r = *l; | ||
268 | *l = temp; | ||
269 | L->top = l+1; /* 1st is on top */ | ||
270 | } | ||
271 | call_binTM(L, L->top, IM_LT, "unexpected type in comparison"); | ||
272 | L->top--; | 255 | L->top--; |
273 | return (ttype(L->top) != LUA_T_NIL); | 256 | return (ttype(L->top) != LUA_T_NIL); |
274 | } | 257 | } |
@@ -280,6 +263,34 @@ int luaV_lessthan (lua_State *L, TObject *l, TObject *r) { | |||
280 | else ttype(o) = LUA_T_NIL | 263 | else ttype(o) = LUA_T_NIL |
281 | 264 | ||
282 | 265 | ||
266 | static void strconc (lua_State *L, int total, StkId top) { | ||
267 | do { | ||
268 | int n = 2; /* number of elements handled in this pass (at least 2) */ | ||
269 | if (tostring(L, top-2) || tostring(L, top-1)) | ||
270 | call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation"); | ||
271 | else { /* at least two string values; get as many as possible */ | ||
272 | long tl = tsvalue(top-2)->u.s.len + tsvalue(top-1)->u.s.len; | ||
273 | char *buffer; | ||
274 | int i; | ||
275 | while (n < total && !tostring(L, top-n-1)) { /* collect total length */ | ||
276 | tl += tsvalue(top-n-1)->u.s.len; | ||
277 | n++; | ||
278 | } | ||
279 | buffer = luaL_openspace(L, tl); | ||
280 | tl = 0; | ||
281 | for (i=n; i>0; i--) { /* concat all strings */ | ||
282 | long l = tsvalue(top-i)->u.s.len; | ||
283 | memcpy(buffer+tl, tsvalue(top-i)->str, l); | ||
284 | tl += l; | ||
285 | } | ||
286 | tsvalue(top-n) = luaS_newlstr(L, buffer, tl); | ||
287 | } | ||
288 | total -= n-1; /* got `n' strings to create 1 new */ | ||
289 | top -= n-1; | ||
290 | } while (total > 1); /* repeat until only 1 result left */ | ||
291 | } | ||
292 | |||
293 | |||
283 | void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { | 294 | void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { |
284 | int i; | 295 | int i; |
285 | Hash *htab; | 296 | Hash *htab; |
@@ -479,22 +490,22 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
479 | 490 | ||
480 | case LTOP: | 491 | case LTOP: |
481 | top--; | 492 | top--; |
482 | setbool(top-1, luaV_lessthan(L, top-1, top)); | 493 | setbool(top-1, luaV_lessthan(L, top-1, top, top+1)); |
483 | break; | 494 | break; |
484 | 495 | ||
485 | case LEOP: /* a <= b === !(b<a) */ | 496 | case LEOP: /* a <= b === !(b<a) */ |
486 | top--; | 497 | top--; |
487 | setbool(top-1, !luaV_lessthan(L, top, top-1)); | 498 | setbool(top-1, !luaV_lessthan(L, top, top-1, top+1)); |
488 | break; | 499 | break; |
489 | 500 | ||
490 | case GTOP: /* a > b === (b<a) */ | 501 | case GTOP: /* a > b === (b<a) */ |
491 | top--; | 502 | top--; |
492 | setbool(top-1, luaV_lessthan(L, top, top-1)); | 503 | setbool(top-1, luaV_lessthan(L, top, top-1, top+1)); |
493 | break; | 504 | break; |
494 | 505 | ||
495 | case GEOP: /* a >= b === !(a<b) */ | 506 | case GEOP: /* a >= b === !(a<b) */ |
496 | top--; | 507 | top--; |
497 | setbool(top-1, !luaV_lessthan(L, top-1, top)); | 508 | setbool(top-1, !luaV_lessthan(L, top-1, top, top+1)); |
498 | break; | 509 | break; |
499 | 510 | ||
500 | case ADDOP: | 511 | case ADDOP: |
@@ -544,15 +555,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
544 | top--; | 555 | top--; |
545 | break; | 556 | break; |
546 | 557 | ||
547 | case CONCOP: | 558 | case CONCOP: { |
548 | if (tostring(L, top-2) || tostring(L, top-1)) | 559 | int n = GETARG_U(i); |
549 | call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation"); | 560 | strconc(L, n, top); |
550 | else | 561 | top -= n-1; |
551 | tsvalue(top-2) = strconc(L, tsvalue(top-2), tsvalue(top-1)); | ||
552 | top--; | ||
553 | L->top = top; | 562 | L->top = top; |
554 | luaC_checkGC(L); | 563 | luaC_checkGC(L); |
555 | break; | 564 | break; |
565 | } | ||
556 | 566 | ||
557 | case MINUSOP: | 567 | case MINUSOP: |
558 | if (tonumber(top-1)) { | 568 | if (tonumber(top-1)) { |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.h,v 1.16 2000/02/22 18:12:46 roberto Exp roberto $ | 2 | ** $Id: lvm.h,v 1.17 2000/03/03 14:58:26 roberto Exp $ |
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,6 +28,6 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top); | |||
28 | void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top); | 28 | void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top); |
29 | StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base); | 29 | StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base); |
30 | void luaV_closure (lua_State *L, int nelems); | 30 | void luaV_closure (lua_State *L, int nelems); |
31 | int luaV_lessthan (lua_State *L, TObject *l, TObject *r); | 31 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top); |
32 | 32 | ||
33 | #endif | 33 | #endif |