aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-08 21:19:22 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-08 21:19:22 -0300
commit88b306f495fa7034c708c6b75a355a6deee51c58 (patch)
tree7d8faaacd1f5c753ed9e77f0e2c8e27b9a002635
parent563de491be90601f23a735aede89ea9a3ef86ee9 (diff)
downloadlua-88b306f495fa7034c708c6b75a355a6deee51c58.tar.gz
lua-88b306f495fa7034c708c6b75a355a6deee51c58.tar.bz2
lua-88b306f495fa7034c708c6b75a355a6deee51c58.zip
some optimizations
-rw-r--r--lbuiltin.c11
-rw-r--r--lcode.c12
-rw-r--r--lopcodes.h57
-rw-r--r--lparser.c20
-rw-r--r--lvm.c76
-rw-r--r--lvm.h4
6 files changed, 105 insertions, 75 deletions
diff --git a/lbuiltin.c b/lbuiltin.c
index 3a57e814..3c558886 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -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
565static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { 560static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
diff --git a/lcode.c b/lcode.c
index d43103fd..3f0418b9 100644
--- a/lcode.c
+++ b/lcode.c
@@ -88,6 +88,16 @@ static void luaK_sub (LexState *ls) {
88} 88}
89 89
90 90
91static 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
91void luaK_retcode (LexState *ls, int nlocals, int nexps) { 101void 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;
diff --git a/lopcodes.h b/lopcodes.h
index 494cb84c..1e3b9ee9 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -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 */
111MULTOP,/* - y x x*y */ 128MULTOP,/* - y x x*y */
112DIVOP,/* - y x x/y */ 129DIVOP,/* - y x x/y */
113POWOP,/* - y x x^y */ 130POWOP,/* - y x x^y */
114CONCOP,/* - y x x..y */ 131CONCOP,/* U v_u-v_1 v1..-..v_u */
115MINUSOP,/* - x -x */ 132MINUSOP,/* - x -x */
116NOTOP,/* - x (x==nil)? 1 : nil */ 133NOTOP,/* - x (x==nil)? 1 : nil */
117 134
diff --git a/lparser.c b/lparser.c
index 4c1eeb80..7fb5a0d7 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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
943static void ifpart (LexState *ls, int line) { 943static 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
diff --git a/lvm.c b/lvm.c
index 819e9a0e..4a24c43a 100644
--- a/lvm.c
+++ b/lvm.c
@@ -39,17 +39,6 @@
39 39
40 40
41 41
42static 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
53int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */ 42int 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
256int luaV_lessthan (lua_State *L, TObject *l, TObject *r) { 245int 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
266static 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
283void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { 294void 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)) {
diff --git a/lvm.h b/lvm.h
index 391d90ab..b3033200 100644
--- a/lvm.h
+++ b/lvm.h
@@ -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);
28void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top); 28void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top);
29StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base); 29StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base);
30void luaV_closure (lua_State *L, int nelems); 30void luaV_closure (lua_State *L, int nelems);
31int luaV_lessthan (lua_State *L, TObject *l, TObject *r); 31int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top);
32 32
33#endif 33#endif