aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c32
-rw-r--r--ldebug.c14
-rw-r--r--lgc.c50
-rw-r--r--lobject.c30
-rw-r--r--lobject.h26
-rw-r--r--lopcodes.c4
-rw-r--r--lopcodes.h4
-rw-r--r--lparser.c36
-rw-r--r--lstate.c10
-rw-r--r--ltable.c342
-rw-r--r--ltable.h24
-rw-r--r--ltests.c47
-rw-r--r--lvm.c17
13 files changed, 421 insertions, 215 deletions
diff --git a/lapi.c b/lapi.c
index ea50ea28..e941139a 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.155 2001/10/17 21:12:57 roberto Exp roberto $ 2** $Id: lapi.c,v 1.156 2001/10/17 21:17:45 roberto Exp $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -391,7 +391,7 @@ LUA_API void lua_getglobals (lua_State *L) {
391 391
392LUA_API void lua_newtable (lua_State *L) { 392LUA_API void lua_newtable (lua_State *L) {
393 lua_lock(L); 393 lua_lock(L);
394 sethvalue(L->top, luaH_new(L, 0)); 394 sethvalue(L->top, luaH_new(L, 0, 0));
395 api_incr_top(L); 395 api_incr_top(L);
396 lua_unlock(L); 396 lua_unlock(L);
397} 397}
@@ -647,22 +647,17 @@ LUA_API void lua_unref (lua_State *L, int ref) {
647 647
648LUA_API int lua_next (lua_State *L, int index) { 648LUA_API int lua_next (lua_State *L, int index) {
649 StkId t; 649 StkId t;
650 Node *n;
651 int more; 650 int more;
652 lua_lock(L); 651 lua_lock(L);
653 t = luaA_index(L, index); 652 t = luaA_index(L, index);
654 api_check(L, ttype(t) == LUA_TTABLE); 653 api_check(L, ttype(t) == LUA_TTABLE);
655 n = luaH_next(L, hvalue(t), luaA_index(L, -1)); 654 more = luaH_index(L, hvalue(t), luaA_index(L, -1));
656 if (n) { 655 more = (luaH_nexti(hvalue(t), more, L->top - 1) != -1);
657 setobj(L->top-1, key(n)); 656 if (more) {
658 setobj(L->top, val(n));
659 api_incr_top(L); 657 api_incr_top(L);
660 more = 1;
661 } 658 }
662 else { /* no more elements */ 659 else /* no more elements */
663 L->top -= 1; /* remove key */ 660 L->top -= 1; /* remove key */
664 more = 0;
665 }
666 lua_unlock(L); 661 lua_unlock(L);
667 return more; 662 return more;
668} 663}
@@ -679,9 +674,18 @@ LUA_API int lua_getn (lua_State *L, int index) {
679 if (ttype(value) == LUA_TNUMBER) 674 if (ttype(value) == LUA_TNUMBER)
680 n = cast(int, nvalue(value)); 675 n = cast(int, nvalue(value));
681 else { 676 else {
677 Node *nd;
678 Table *a = hvalue(t);
682 lua_Number max = 0; 679 lua_Number max = 0;
683 int i = hvalue(t)->size; 680 int i;
684 Node *nd = hvalue(t)->node; 681 i = sizearray(a);
682 while (i--) {
683 if (ttype(&a->array[i]) != LUA_TNIL)
684 break;
685 }
686 max = i+1;
687 i = sizenode(a);
688 nd = a->node;
685 while (i--) { 689 while (i--) {
686 if (ttype(key(nd)) == LUA_TNUMBER && 690 if (ttype(key(nd)) == LUA_TNUMBER &&
687 ttype(val(nd)) != LUA_TNIL && 691 ttype(val(nd)) != LUA_TNIL &&
@@ -756,7 +760,7 @@ LUA_API int lua_getweakmode (lua_State *L, int index) {
756LUA_API void lua_setweakmode (lua_State *L, int mode) { 760LUA_API void lua_setweakmode (lua_State *L, int mode) {
757 lua_lock(L); 761 lua_lock(L);
758 api_check(L, ttype(L->top-1) == LUA_TTABLE); 762 api_check(L, ttype(L->top-1) == LUA_TTABLE);
759 hvalue(L->top-1)->weakmode = mode; 763 hvalue(L->top-1)->weakmode = cast(lu_byte, mode);
760 lua_unlock(L); 764 lua_unlock(L);
761} 765}
762 766
diff --git a/ldebug.c b/ldebug.c
index 5ddf3d0a..5adab2af 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.88 2001/09/07 17:39:10 roberto Exp $ 2** $Id: ldebug.c,v 1.90 2001/10/02 16:45:03 roberto Exp $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -221,12 +221,12 @@ static const l_char *travtagmethods (global_State *G, const TObject *o) {
221 221
222 222
223static const l_char *travglobals (lua_State *L, const TObject *o) { 223static const l_char *travglobals (lua_State *L, const TObject *o) {
224 Hash *g = L->gt; 224 Table *g = L->gt;
225 int i; 225 int i = sizenode(g);
226 for (i=0; i<g->size; i++) { 226 while (i--) {
227 if (luaO_equalObj(o, val(node(g, i))) && 227 Node *n = node(g, i);
228 ttype(key(node(g, i))) == LUA_TSTRING) 228 if (luaO_equalObj(o, val(n)) && ttype(key(n)) == LUA_TSTRING)
229 return getstr(tsvalue(key(node(g, i)))); 229 return getstr(tsvalue(key(n)));
230 } 230 }
231 return NULL; 231 return NULL;
232} 232}
diff --git a/lgc.c b/lgc.c
index 35251ce3..cf9148e9 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.112 2001/10/02 16:45:03 roberto Exp $ 2** $Id: lgc.c,v 1.113 2001/10/17 21:12:57 roberto Exp $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -21,7 +21,7 @@
21 21
22 22
23typedef struct GCState { 23typedef struct GCState {
24 Hash *tmark; /* list of marked tables to be visited */ 24 Table *tmark; /* list of marked tables to be visited */
25} GCState; 25} GCState;
26 26
27 27
@@ -76,7 +76,7 @@ static void markclosure (GCState *st, Closure *cl) {
76} 76}
77 77
78 78
79static void marktable (GCState *st, Hash *h) { 79static void marktable (GCState *st, Table *h) {
80 if (!ismarked(h)) { 80 if (!ismarked(h)) {
81 h->mark = st->tmark; /* chain it for later traversal */ 81 h->mark = st->tmark; /* chain it for later traversal */
82 st->tmark = h; 82 st->tmark = h;
@@ -145,18 +145,20 @@ static void removekey (Node *n) {
145} 145}
146 146
147 147
148static void traversetable (GCState *st, Hash *h) { 148static void traversetable (GCState *st, Table *h) {
149 int i; 149 int i;
150 int mode = h->weakmode; 150 int mode = h->weakmode;
151 if (mode == (LUA_WEAK_KEY | LUA_WEAK_VALUE)) 151 if (!(mode & LUA_WEAK_VALUE)) {
152 return; /* avoid traversing if both keys and values are weak */ 152 i = sizearray(h);
153 for (i=0; i<h->size; i++) { 153 while (i--)
154 markobject(st, &h->array[i]);
155 }
156 i = sizenode(h);
157 while (i--) {
154 Node *n = node(h, i); 158 Node *n = node(h, i);
155 if (ttype(val(n)) == LUA_TNIL) 159 if (ttype(val(n)) != LUA_TNIL) {
156 removekey(n);
157 else {
158 lua_assert(ttype(key(n)) != LUA_TNIL); 160 lua_assert(ttype(key(n)) != LUA_TNIL);
159 if (ttype(key(n)) != LUA_TNUMBER && !(mode & LUA_WEAK_KEY)) 161 if (!(mode & LUA_WEAK_KEY))
160 markobject(st, key(n)); 162 markobject(st, key(n));
161 if (!(mode & LUA_WEAK_VALUE)) 163 if (!(mode & LUA_WEAK_VALUE))
162 markobject(st, val(n)); 164 markobject(st, val(n));
@@ -173,7 +175,7 @@ static void markall (lua_State *L) {
173 marktable(&st, G(L)->type2tag); 175 marktable(&st, G(L)->type2tag);
174 markobject(&st, &G(L)->registry); 176 markobject(&st, &G(L)->registry);
175 while (st.tmark) { /* mark tables */ 177 while (st.tmark) { /* mark tables */
176 Hash *h = st.tmark; /* get first table from list */ 178 Table *h = st.tmark; /* get first table from list */
177 st.tmark = h->mark; /* remove it from list */ 179 st.tmark = h->mark; /* remove it from list */
178 traversetable(&st, h); 180 traversetable(&st, h);
179 } 181 }
@@ -196,21 +198,27 @@ static int hasmark (const TObject *o) {
196} 198}
197 199
198 200
199static void cleardeadnodes (Hash *h) { 201static void cleardeadnodes (Table *h) {
200 int i; 202 int i;
201 for (i=0; i<h->size; i++) { 203 i = sizearray(h);
204 while (i--) {
205 TObject *o = &h->array[i];
206 if (!hasmark(o))
207 setnilvalue(o); /* remove value */
208 }
209 i = sizenode(h);
210 while (i--) {
202 Node *n = node(h, i); 211 Node *n = node(h, i);
203 if (ttype(val(n)) == LUA_TNIL) continue; /* empty node */
204 if (!hasmark(val(n)) || !hasmark(key(n))) { 212 if (!hasmark(val(n)) || !hasmark(key(n))) {
205 setnilvalue(val(n)); /* remove value */ 213 setnilvalue(val(n)); /* remove value ... */
206 removekey(n); 214 removekey(n); /* ... and key */
207 } 215 }
208 } 216 }
209} 217}
210 218
211 219
212static void cleartables (global_State *G) { 220static void cleartables (global_State *G) {
213 Hash *h; 221 Table *h;
214 for (h = G->roottable; h; h = h->next) { 222 for (h = G->roottable; h; h = h->next) {
215 if (h->weakmode && ismarked(h)) 223 if (h->weakmode && ismarked(h))
216 cleardeadnodes(h); 224 cleardeadnodes(h);
@@ -260,8 +268,8 @@ static void collectclosures (lua_State *L) {
260 268
261 269
262static void collecttable (lua_State *L) { 270static void collecttable (lua_State *L) {
263 Hash **p = &G(L)->roottable; 271 Table **p = &G(L)->roottable;
264 Hash *curr; 272 Table *curr;
265 while ((curr = *p) != NULL) { 273 while ((curr = *p) != NULL) {
266 if (ismarked(curr)) { 274 if (ismarked(curr)) {
267 curr->mark = curr; /* unmark */ 275 curr->mark = curr; /* unmark */
@@ -333,7 +341,7 @@ static void collectstrings (lua_State *L, int all) {
333 } 341 }
334 } 342 }
335 if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) && 343 if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) &&
336 G(L)->strt.size > MINPOWER2) 344 G(L)->strt.size > 4)
337 luaS_resize(L, G(L)->strt.size/2); /* table is too big */ 345 luaS_resize(L, G(L)->strt.size/2); /* table is too big */
338} 346}
339 347
diff --git a/lobject.c b/lobject.c
index 0b597ff1..3dfafde4 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 1.69 2001/03/07 12:27:06 roberto Exp roberto $ 2** $Id: lobject.c,v 1.70 2001/03/26 14:31:49 roberto Exp $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -23,6 +23,34 @@
23const TObject luaO_nilobject = {LUA_TNIL, {NULL}}; 23const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
24 24
25 25
26int luaO_log2 (unsigned int x) {
27 static const lu_byte log_8[255] = {
28 0,
29 1,1,
30 2,2,2,2,
31 3,3,3,3,3,3,3,3,
32 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
33 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
34 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
35 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
36 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
37 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
38 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
39 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
40 };
41 if (x & 0xffff0000) {
42 if (x & 0xff000000) return log_8[((x>>24) & 0xff) - 1]+24;
43 else return log_8[((x>>16) & 0xff) - 1]+16;
44 }
45 else {
46 if (x & 0x0000ff00) return log_8[((x>>8) & 0xff) - 1]+8;
47 else if (x) return log_8[(x & 0xff) - 1];
48 return -1; /* special `log' for 0 */
49 }
50}
51
52
53
26int luaO_equalObj (const TObject *t1, const TObject *t2) { 54int luaO_equalObj (const TObject *t1, const TObject *t2) {
27 if (ttype(t1) != ttype(t2)) return 0; 55 if (ttype(t1) != ttype(t2)) return 0;
28 switch (ttype(t1)) { 56 switch (ttype(t1)) {
diff --git a/lobject.h b/lobject.h
index 359055f3..dbabc638 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.113 2001/09/25 17:08:46 roberto Exp $ 2** $Id: lobject.h,v 1.114 2001/10/02 16:45:03 roberto Exp $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -39,7 +39,7 @@ typedef union {
39 union TString *ts; 39 union TString *ts;
40 union Udata *u; 40 union Udata *u;
41 union Closure *cl; 41 union Closure *cl;
42 struct Hash *h; 42 struct Table *h;
43 struct UpVal *v; 43 struct UpVal *v;
44 lua_Number n; /* LUA_TNUMBER */ 44 lua_Number n; /* LUA_TNUMBER */
45} Value; 45} Value;
@@ -214,7 +214,7 @@ typedef union Closure {
214 214
215 215
216/* 216/*
217** Hash Tables 217** Tables
218*/ 218*/
219 219
220typedef struct Node { 220typedef struct Node {
@@ -224,15 +224,17 @@ typedef struct Node {
224} Node; 224} Node;
225 225
226 226
227typedef struct Hash { 227typedef struct Table {
228 TObject *array; /* array part */
228 Node *node; 229 Node *node;
229 int htag; 230 int htag;
230 int size; 231 int sizearray; /* size of `array' array */
232 lu_byte lsizenode; /* log2 of size of `node' array */
233 lu_byte weakmode;
231 Node *firstfree; /* this position is free; all positions after it are full */ 234 Node *firstfree; /* this position is free; all positions after it are full */
232 struct Hash *next; 235 struct Table *next;
233 struct Hash *mark; /* marked tables (point to itself when not marked) */ 236 struct Table *mark; /* marked tables (point to itself when not marked) */
234 int weakmode; 237} Table;
235} Hash;
236 238
237 239
238/* unmarked tables are represented by pointing `mark' to themselves */ 240/* unmarked tables are represented by pointing `mark' to themselves */
@@ -245,6 +247,10 @@ typedef struct Hash {
245#define lmod(s,size) (cast(int, (s) & ((size)-1))) 247#define lmod(s,size) (cast(int, (s) & ((size)-1)))
246 248
247 249
250#define twoto(x) (1<<(x))
251#define sizenode(t) (twoto((t)->lsizenode))
252#define sizearray(t) ((t)->sizearray)
253
248/* 254/*
249** informations about a call (for debugging) 255** informations about a call (for debugging)
250*/ 256*/
@@ -262,6 +268,8 @@ typedef struct CallInfo {
262 268
263extern const TObject luaO_nilobject; 269extern const TObject luaO_nilobject;
264 270
271int luaO_log2 (unsigned int x);
272
265 273
266#define luaO_openspace(L,n,t) cast(t *, luaO_openspaceaux(L,(n)*sizeof(t))) 274#define luaO_openspace(L,n,t) cast(t *, luaO_openspaceaux(L,(n)*sizeof(t)))
267void *luaO_openspaceaux (lua_State *L, size_t n); 275void *luaO_openspaceaux (lua_State *L, size_t n);
diff --git a/lopcodes.c b/lopcodes.c
index 9ad82d7a..ae5f37e3 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.3 2001/08/27 15:14:57 roberto Exp $ 2** $Id: lopcodes.c,v 1.5 2001/09/07 17:39:10 roberto Exp $
3** extracted automatically from lopcodes.h by mkprint.lua 3** extracted automatically from lopcodes.h by mkprint.lua
4** DO NOT EDIT 4** DO NOT EDIT
5** See Copyright Notice in lua.h 5** See Copyright Notice in lua.h
@@ -77,7 +77,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
77 ,opmode(0,0,0,0, 0,1,iABc) /* OP_SETGLOBAL */ 77 ,opmode(0,0,0,0, 0,1,iABc) /* OP_SETGLOBAL */
78 ,opmode(0,0,0,0, 0,0,iABC) /* OP_SETUPVAL */ 78 ,opmode(0,0,0,0, 0,0,iABC) /* OP_SETUPVAL */
79 ,opmode(0,0,1,1, 0,0,iABC) /* OP_SETTABLE */ 79 ,opmode(0,0,1,1, 0,0,iABC) /* OP_SETTABLE */
80 ,opmode(0,0,0,0, 1,0,iABc) /* OP_NEWTABLE */ 80 ,opmode(0,0,0,0, 1,0,iABC) /* OP_NEWTABLE */
81 ,opmode(0,0,1,1, 1,0,iABC) /* OP_SELF */ 81 ,opmode(0,0,1,1, 1,0,iABC) /* OP_SELF */
82 ,opmode(0,0,1,1, 1,0,iABC) /* OP_ADD */ 82 ,opmode(0,0,1,1, 1,0,iABC) /* OP_ADD */
83 ,opmode(0,0,1,1, 1,0,iABC) /* OP_SUB */ 83 ,opmode(0,0,1,1, 1,0,iABC) /* OP_SUB */
diff --git a/lopcodes.h b/lopcodes.h
index 7492c462..8afd2d4e 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.79 2001/08/27 15:14:57 roberto Exp $ 2** $Id: lopcodes.h,v 1.81 2001/09/07 17:39:10 roberto Exp $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -140,7 +140,7 @@ OP_SETGLOBAL,/* A Bc Gbl[Kst(Bc)] := R(A) */
140OP_SETUPVAL,/* A B UpValue[B] := R(A) */ 140OP_SETUPVAL,/* A B UpValue[B] := R(A) */
141OP_SETTABLE,/* A B C R(B)[R/K(C)] := R(A) */ 141OP_SETTABLE,/* A B C R(B)[R/K(C)] := R(A) */
142 142
143OP_NEWTABLE,/* A Bc R(A) := {} (size = Bc) */ 143OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
144 144
145OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[R/K(C)] */ 145OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[R/K(C)] */
146 146
diff --git a/lparser.c b/lparser.c
index b83f5d19..744c9ce6 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.157 2001/09/25 17:06:48 roberto Exp $ 2** $Id: lparser.c,v 1.159 2001/10/02 16:41:36 roberto Exp $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -30,7 +30,8 @@
30** or empty (k = `;' or `}') 30** or empty (k = `;' or `}')
31*/ 31*/
32typedef struct Constdesc { 32typedef struct Constdesc {
33 int n; 33 int narray;
34 int nhash;
34 int k; 35 int k;
35} Constdesc; 36} Constdesc;
36 37
@@ -315,7 +316,7 @@ static void open_func (LexState *ls, FuncState *fs) {
315 fs->jlt = NO_JUMP; 316 fs->jlt = NO_JUMP;
316 fs->freereg = 0; 317 fs->freereg = 0;
317 fs->nk = 0; 318 fs->nk = 0;
318 fs->h = luaH_new(ls->L, 0); 319 fs->h = luaH_new(ls->L, 0, 0);
319 fs->np = 0; 320 fs->np = 0;
320 fs->nlineinfo = 0; 321 fs->nlineinfo = 0;
321 fs->nlocvars = 0; 322 fs->nlocvars = 0;
@@ -507,6 +508,7 @@ static int recfields (LexState *ls, expdesc *t) {
507 int n = 0; 508 int n = 0;
508 do { /* at least one element */ 509 do { /* at least one element */
509 recfield(ls, t); 510 recfield(ls, t);
511 luaX_checklimit(ls, n, MAX_INT, l_s("items in a constructor"));
510 n++; 512 n++;
511 } while (anotherfield(ls)); 513 } while (anotherfield(ls));
512 return n; 514 return n;
@@ -523,8 +525,7 @@ static int listfields (LexState *ls, expdesc *t) {
523 expr(ls, &v); 525 expr(ls, &v);
524 while (anotherfield(ls)) { 526 while (anotherfield(ls)) {
525 luaK_exp2nextreg(fs, &v); 527 luaK_exp2nextreg(fs, &v);
526 luaX_checklimit(ls, n, MAXARG_Bc, 528 luaX_checklimit(ls, n, MAXARG_Bc, l_s("items in a constructor"));
527 l_s("`item groups' in a list initializer"));
528 if (n%LFIELDS_PER_FLUSH == 0) { 529 if (n%LFIELDS_PER_FLUSH == 0) {
529 luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); /* flush */ 530 luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); /* flush */
530 fs->freereg = reg; /* free registers */ 531 fs->freereg = reg; /* free registers */
@@ -548,7 +549,7 @@ static int listfields (LexState *ls, expdesc *t) {
548static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) { 549static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) {
549 switch (ls->t.token) { 550 switch (ls->t.token) {
550 case l_c(';'): case l_c('}'): { /* constructor_part -> empty */ 551 case l_c(';'): case l_c('}'): { /* constructor_part -> empty */
551 cd->n = 0; 552 cd->narray = cd->nhash = 0;
552 cd->k = ls->t.token; 553 cd->k = ls->t.token;
553 break; 554 break;
554 } 555 }
@@ -559,13 +560,15 @@ static void constructor_part (LexState *ls, expdesc *t, Constdesc *cd) {
559 /* else go through to recfields */ 560 /* else go through to recfields */
560 } 561 }
561 case l_c('['): { /* constructor_part -> recfields */ 562 case l_c('['): { /* constructor_part -> recfields */
562 cd->n = recfields(ls, t); 563 cd->nhash = recfields(ls, t);
564 cd->narray = 0;
563 cd->k = 1; /* record */ 565 cd->k = 1; /* record */
564 break; 566 break;
565 } 567 }
566 default: { /* constructor_part -> listfields */ 568 default: { /* constructor_part -> listfields */
567 case_default: 569 case_default:
568 cd->n = listfields(ls, t); 570 cd->narray = listfields(ls, t);
571 cd->nhash = 0;
569 cd->k = 0; /* list */ 572 cd->k = 0; /* list */
570 break; 573 break;
571 } 574 }
@@ -577,24 +580,27 @@ static void constructor (LexState *ls, expdesc *t) {
577 /* constructor -> `{' constructor_part [`;' constructor_part] `}' */ 580 /* constructor -> `{' constructor_part [`;' constructor_part] `}' */
578 FuncState *fs = ls->fs; 581 FuncState *fs = ls->fs;
579 int line = ls->linenumber; 582 int line = ls->linenumber;
580 int n; 583 int na, nh;
581 int pc; 584 int pc;
582 Constdesc cd; 585 Constdesc cd;
583 pc = luaK_codeABc(fs, OP_NEWTABLE, 0, 0); 586 pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
584 init_exp(t, VRELOCABLE, pc); 587 init_exp(t, VRELOCABLE, pc);
585 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ 588 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
586 check(ls, l_c('{')); 589 check(ls, l_c('{'));
587 constructor_part(ls, t, &cd); 590 constructor_part(ls, t, &cd);
588 n = cd.n; 591 na = cd.narray;
592 nh = cd.nhash;
589 if (optional(ls, l_c(';'))) { 593 if (optional(ls, l_c(';'))) {
590 Constdesc other_cd; 594 Constdesc other_cd;
591 constructor_part(ls, t, &other_cd); 595 constructor_part(ls, t, &other_cd);
592 check_condition(ls, (cd.k != other_cd.k), l_s("invalid constructor syntax")); 596 check_condition(ls,(cd.k != other_cd.k), l_s("invalid constructor syntax"));
593 n += other_cd.n; 597 na += other_cd.narray;
598 nh += other_cd.nhash;
594 } 599 }
595 check_match(ls, l_c('}'), l_c('{'), line); 600 check_match(ls, l_c('}'), l_c('{'), line);
596 luaX_checklimit(ls, n, MAXARG_Bc, l_s("elements in a table constructor")); 601 if (na > 0)
597 SETARG_Bc(fs->f->code[pc], n); /* set initial table size */ 602 SETARG_B(fs->f->code[pc], luaO_log2(na-1)+2); /* set initial table size */
603 SETARG_C(fs->f->code[pc], luaO_log2(nh)+1); /* set initial table size */
598} 604}
599 605
600/* }====================================================================== */ 606/* }====================================================================== */
diff --git a/lstate.c b/lstate.c
index 640bfcde..1fe006ae 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.68 2001/09/07 17:39:10 roberto Exp $ 2** $Id: lstate.c,v 1.69 2001/10/17 21:12:57 roberto Exp $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -64,10 +64,10 @@ static void f_luaopen (lua_State *L, void *ud) {
64 G(L)->ntag = 0; 64 G(L)->ntag = 0;
65 G(L)->nblocks = sizeof(lua_State) + sizeof(global_State); 65 G(L)->nblocks = sizeof(lua_State) + sizeof(global_State);
66 luaD_init(L, so->stacksize); /* init stack */ 66 luaD_init(L, so->stacksize); /* init stack */
67 L->gt = luaH_new(L, 10); /* table of globals */ 67 L->gt = luaH_new(L, 0, 4); /* table of globals */
68 G(L)->type2tag = luaH_new(L, 10); 68 G(L)->type2tag = luaH_new(L, 0, 3);
69 sethvalue(&G(L)->registry, luaH_new(L, 0)); 69 sethvalue(&G(L)->registry, luaH_new(L, 0, 0));
70 luaS_resize(L, MINPOWER2); 70 luaS_resize(L, 4); /* initial size of string table */
71 luaX_init(L); 71 luaX_init(L);
72 luaT_init(L); 72 luaT_init(L);
73 G(L)->GCthreshold = 4*G(L)->nblocks; 73 G(L)->GCthreshold = 4*G(L)->nblocks;
diff --git a/ltable.c b/ltable.c
index a40e615f..a4828fca 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,13 +1,17 @@
1/* 1/*
2** $Id: ltable.c,v 1.83 2001/07/05 20:31:14 roberto Exp roberto $ 2** $Id: ltable.c,v 1.86 2001/09/07 17:30:16 roberto Exp $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8/* 8/*
9** Implementation of tables (aka arrays, objects, or hash tables); 9** Implementation of tables (aka arrays, objects, or hash tables).
10** uses a mix of chained scatter table with Brent's variation. 10** Tables keep its elements in two parts: an array part and a hash part.
11** Non-negative integer keys are all candidates to be kept in the array
12** part. The actual size of the array is the largest `n' such that at
13** least half the slots between 0 and n are in use.
14** Hash uses a mix of chained scatter table with Brent's variation.
11** A main invariant of these tables is that, if an element is not 15** A main invariant of these tables is that, if an element is not
12** in its main position (i.e. the `original' position that its hash gives 16** in its main position (i.e. the `original' position that its hash gives
13** to it), then the colliding element is in its own main position. 17** to it), then the colliding element is in its own main position.
@@ -18,6 +22,7 @@
18*/ 22*/
19 23
20 24
25
21#define LUA_PRIVATE 26#define LUA_PRIVATE
22#include "lua.h" 27#include "lua.h"
23 28
@@ -28,20 +33,34 @@
28#include "ltable.h" 33#include "ltable.h"
29 34
30 35
36/*
37** max size of array part is 2^MAXBITS
38*/
39#if BITS_INT > 24
40#define MAXBITS 24
41#else
42#define MAXBITS (BITS_INT-1)
43#endif
44
45/* check whether `x' < 2^MAXBITS */
46#define toobig(x) ((((x)-1) >> MAXBITS) != 0)
47
48
31 49
32#define TagDefault LUA_TTABLE 50#define TagDefault LUA_TTABLE
33 51
34 52
35#define hashnum(t,n) (node(t, lmod(cast(lu_hash, cast(ls_hash, n)), t->size))) 53#define hashnum(t,n) \
36#define hashstr(t,str) (node(t, lmod((str)->tsv.hash, t->size))) 54 (node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t))))
37#define hashpointer(t,p) (node(t, lmod(IntPoint(p), t->size))) 55#define hashstr(t,str) (node(t, lmod((str)->tsv.hash, sizenode(t))))
56#define hashpointer(t,p) (node(t, lmod(IntPoint(p), sizenode(t))))
38 57
39 58
40/* 59/*
41** returns the `main' position of an element in a table (that is, the index 60** returns the `main' position of an element in a table (that is, the index
42** of its hash value) 61** of its hash value)
43*/ 62*/
44Node *luaH_mainposition (const Hash *t, const TObject *key) { 63Node *luaH_mainposition (const Table *t, const TObject *key) {
45 switch (ttype(key)) { 64 switch (ttype(key)) {
46 case LUA_TNUMBER: 65 case LUA_TNUMBER:
47 return hashnum(t, nvalue(key)); 66 return hashnum(t, nvalue(key));
@@ -53,119 +72,237 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
53} 72}
54 73
55 74
56Node *luaH_next (lua_State *L, Hash *t, const TObject *key) { 75/*
76** returns the index for `key' if `key' is an appropriate key to live in
77** the array part of the table, -1 otherwise.
78*/
79static int arrayindex (const TObject *key) {
80 if (ttype(key) == LUA_TNUMBER) {
81 int k = cast(int, nvalue(key));
82 if (cast(lua_Number, k) == nvalue(key) && k >= 1 && !toobig(k))
83 return k;
84 }
85 return -1; /* `key' did not match some condition */
86}
87
88
89/*
90** returns the index of a `key' for table traversals. First goes all
91** elements in the array part, then elements in the hash part. The
92** beginning and end of a traversal are signalled by -1.
93*/
94int luaH_index (lua_State *L, Table *t, const TObject *key) {
57 int i; 95 int i;
58 if (ttype(key) == LUA_TNIL) 96 if (ttype(key) == LUA_TNIL) return -1; /* first iteration */
59 i = 0; /* first iteration */ 97 i = arrayindex(key);
98 if (0 <= i && i < t->sizearray) { /* is `key' inside array part? */
99 return i; /* yes; that's the index */
100 }
60 else { 101 else {
61 const TObject *v = luaH_get(t, key); 102 const TObject *v = luaH_get(t, key);
62 if (v == &luaO_nilobject) 103 if (v == &luaO_nilobject)
63 luaD_error(L, l_s("invalid key for `next'")); 104 luaD_error(L, l_s("invalid key for `next'"));
64 i = cast(int, (cast(const lu_byte *, v) - 105 i = cast(int, (cast(const lu_byte *, v) -
65 cast(const lu_byte *, val(node(t, 0)))) / sizeof(Node)) + 1; 106 cast(const lu_byte *, val(node(t, 0)))) / sizeof(Node));
66 } 107 return i + t->sizearray; /* hash elements are numbered after array ones */
67 for (; i<t->size; i++) {
68 Node *n = node(t, i);
69 if (ttype(val(n)) != LUA_TNIL)
70 return n;
71 } 108 }
72 return NULL; /* no more elements */
73} 109}
74 110
75 111
76int luaH_nexti (Hash *t, int i) { 112int luaH_nexti (Table *t, int i, TObject *where) {
77 while ((++i)<t->size) { 113 for (i++; i < t->sizearray; i++) { /* try first array part */
78 if (ttype(val(node(t, i))) != LUA_TNIL) /* a non-nil value? */ 114 if (ttype(&t->array[i]) != LUA_TNIL) { /* a non-nil value? */
115 setnvalue(where, i+1);
116 setobj(where+1, &t->array[i]);
79 return i; 117 return i;
118 }
119 }
120 for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
121 if (ttype(val(node(t, i))) != LUA_TNIL) { /* a non-nil value? */
122 setobj(where, key(node(t, i)));
123 setobj(where+1, val(node(t, i)));
124 return i + t->sizearray;
125 }
80 } 126 }
81 return -1; /* no more elements */ 127 return -1; /* no more elements */
82} 128}
83 129
84 130
85#define check_grow(L, p, n) \
86 if ((p) >= MAX_INT/(n)) luaD_error(L, l_s("table overflow"));
87
88/* 131/*
89** returns smaller power of 2 larger than `n' (minimum is MINPOWER2) 132** {=============================================================
133** Rehash
134** ==============================================================
90*/ 135*/
91static int power2 (lua_State *L, int n) { 136
92 int p = MINPOWER2; 137
93 while (p <= n) { 138static void computesizes (int nums[], int ntotal, int *narray, int *nhash) {
94 check_grow(L, p, 2); 139 int n = 0; /* optimal (log of) size for array part */
95 p *= 2; 140 int na = 0; /* number of elements to go to array part */
141 int a = nums[0]; /* accumulator */
142 int i;
143 for (i=1; i<=MAXBITS; i++) {
144 if (nums[i] == 0) continue; /* ignore empty slices */
145 a += nums[i]; /* number of elements smaller than 2^i */
146 if (a >= (1<<(i-1))) { /* more than half elements in use? */
147 n = i;
148 na = a;
149 }
150 }
151 *nhash = ntotal - na;
152 *narray = (n == 0) ? 0 : (1<<n);
153}
154
155
156static void numuse (const Table *t, int *narray, int *nhash) {
157 int nums[MAXBITS+1];
158 int i;
159 int totaluse = 0;
160 for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* init `nums' */
161 /* count elements in array part */
162 i = luaO_log2(t->sizearray) + 1; /* number of `slices' */
163 while (i--) { /* for each slice [2^(i-1) to 2^i) */
164 int to = twoto(i);
165 int from = to/2;
166 if (to > t->sizearray) to = t->sizearray;
167 for (; from < to; from++)
168 if (ttype(&t->array[from]) != LUA_TNIL) {
169 nums[i]++;
170 totaluse++;
171 }
172 }
173 /* count elements in hash part */
174 i = sizenode(t);
175 while (i--) {
176 if (ttype(&t->node[i].val) != LUA_TNIL) {
177 int k = arrayindex(&t->node[i].key);
178 if (k >= 0) /* is `key' an appropriate array index? */
179 nums[luaO_log2(k-1)+1]++; /* count as such */
180 totaluse++;
181 }
96 } 182 }
97 return p; 183 computesizes(nums, totaluse, narray, nhash);
98} 184}
99 185
100 186
101static void setnodevector (lua_State *L, Hash *t, int size) { 187/*
188** (log of) minimum size for hash part of a table
189*/
190#define MINHASHSIZE 1
191
192
193static void setarrayvector (lua_State *L, Table *t, int size) {
194 int i;
195 if (size > twoto(MAXBITS))
196 luaD_error(L, l_s("table overflow"));
197 luaM_reallocvector(L, t->array, t->sizearray, size, TObject);
198 for (i=t->sizearray; i<size; i++)
199 setnilvalue(&t->array[i]);
200 t->sizearray = size;
201}
202
203
204static void setnodevector (lua_State *L, Table *t, int lsize) {
102 int i; 205 int i;
206 int size;
207 if (lsize < MINHASHSIZE) lsize = MINHASHSIZE;
208 else if (lsize > MAXBITS)
209 luaD_error(L, l_s("table overflow"));
210 size = twoto(lsize);
103 t->node = luaM_newvector(L, size, Node); 211 t->node = luaM_newvector(L, size, Node);
104 for (i=0; i<size; i++) { 212 for (i=0; i<size; i++) {
105 t->node[i].next = NULL; 213 t->node[i].next = NULL;
106 setnilvalue(key(node(t, i))); 214 setnilvalue(key(node(t, i)));
107 setnilvalue(val(node(t, i))); 215 setnilvalue(val(node(t, i)));
108 } 216 }
109 t->size = size; 217 t->lsizenode = cast(lu_byte, lsize);
110 t->firstfree = node(t, size-1); /* first free position to be used */ 218 t->firstfree = node(t, size-1); /* first free position to be used */
111} 219}
112 220
113 221
114Hash *luaH_new (lua_State *L, int size) { 222static void rehash (lua_State *L, Table *t) {
115 Hash *t = luaM_new(L, Hash); 223 int i;
224 int oldasize, oldhsize, nasize, nhsize;
225 Node *nold;
226 numuse(t, &nasize, &nhsize); /* compute new sizes for array and hash parts */
227 oldasize = t->sizearray;
228 if (nasize > oldasize) /* should grow array part? */
229 setarrayvector(L, t, nasize);
230 /* create new hash part with appropriate size */
231 nold = t->node; /* save old hash ... */
232 oldhsize = t->lsizenode; /* ... and (log of) old size */
233 setnodevector(L, t, luaO_log2(nhsize+nhsize/4)+1);
234 /* re-insert elements */
235 if (nasize < oldasize) { /* array part must shrink? */
236 t->sizearray = nasize;
237 /* re-insert elements from vanishing slice */
238 for (i=nasize; i<oldasize; i++) {
239 if (ttype(&t->array[i]) != LUA_TNIL)
240 luaH_setnum(L, t, i+1, &t->array[i]);
241 }
242 /* shink array */
243 luaM_reallocvector(L, t->array, oldasize, nasize, TObject);
244 }
245 /* re-insert elements in hash part */
246 i = twoto(oldhsize);
247 while (i--) {
248 Node *old = nold+i;
249 if (ttype(val(old)) != LUA_TNIL)
250 luaH_set(L, t, key(old), val(old));
251 }
252 luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
253}
254
255/*
256** }=============================================================
257*/
258
259
260Table *luaH_new (lua_State *L, int narray, int lnhash) {
261 Table *t = luaM_new(L, Table);
116 t->htag = TagDefault; 262 t->htag = TagDefault;
117 t->next = G(L)->roottable; 263 t->next = G(L)->roottable;
118 G(L)->roottable = t; 264 G(L)->roottable = t;
119 t->mark = t; 265 t->mark = t;
120 t->size = 0;
121 t->weakmode = 0; 266 t->weakmode = 0;
267 /* temporary values (kept only if some malloc fails) */
268 t->array = NULL;
269 t->sizearray = 0;
270 t->lsizenode = 0;
122 t->node = NULL; 271 t->node = NULL;
123 setnodevector(L, t, power2(L, size)); 272 setarrayvector(L, t, narray);
273 setnodevector(L, t, lnhash);
124 return t; 274 return t;
125} 275}
126 276
127 277
128void luaH_free (lua_State *L, Hash *t) { 278void luaH_free (lua_State *L, Table *t) {
129 luaM_freearray(L, t->node, t->size, Node); 279 lua_assert(t->lsizenode > 0 || t->node == NULL);
280 if (t->lsizenode > 0)
281 luaM_freearray(L, t->node, sizenode(t), Node);
282 luaM_freearray(L, t->array, t->sizearray, TObject);
130 luaM_freelem(L, t); 283 luaM_freelem(L, t);
131} 284}
132 285
133 286
134static int numuse (const Hash *t) { 287#if 0
135 Node *v = t->node; 288/*
136 int size = t->size; 289** try to remove an element from a hash table; cannot move any element
137 int realuse = 0; 290** (because gc can call `remove' during a table traversal)
138 int i; 291*/
139 for (i=0; i<size; i++) { 292void luaH_remove (Table *t, Node *e) {
140 if (ttype(&v[i].val) != LUA_TNIL) 293 Node *mp = luaH_mainposition(t, key(e));
141 realuse++; 294 if (e != mp) { /* element not in its main position? */
142 } 295 while (mp->next != e) mp = mp->next; /* find previous */
143 return realuse; 296 mp->next = e->next; /* remove `e' from its list */
144}
145
146
147static void rehash (lua_State *L, Hash *t) {
148 int oldsize = t->size;
149 Node *nold = t->node;
150 int nelems = numuse(t);
151 int i;
152 lua_assert(nelems<=oldsize);
153 if (nelems >= oldsize-oldsize/4) { /* using more than 3/4? */
154 check_grow(L, oldsize, 2);
155 setnodevector(L, t, oldsize*2); /* grow array */
156 } 297 }
157 else if (nelems <= oldsize/4 && /* less than 1/4? */ 298 else {
158 oldsize > MINPOWER2) 299 if (e->next != NULL) ??
159 setnodevector(L, t, oldsize/2); /* shrink array */
160 else
161 setnodevector(L, t, oldsize); /* just rehash; keep the same size */
162 for (i=0; i<oldsize; i++) {
163 Node *old = nold+i;
164 if (ttype(val(old)) != LUA_TNIL)
165 luaH_set(L, t, key(old), val(old));
166 } 300 }
167 luaM_freearray(L, nold, oldsize, Node); /* free old array */ 301 lua_assert(ttype(val(node)) == LUA_TNIL);
302 setnilvalue(key(e)); /* clear node `e' */
303 e->next = NULL;
168} 304}
305#endif
169 306
170 307
171/* 308/*
@@ -175,7 +312,8 @@ static void rehash (lua_State *L, Hash *t) {
175** put new key in its main position; otherwise (colliding node is in its main 312** put new key in its main position; otherwise (colliding node is in its main
176** position), new key goes to an empty position. 313** position), new key goes to an empty position.
177*/ 314*/
178static TObject *newkey (lua_State *L, Hash *t, const TObject *key) { 315static void newkey (lua_State *L, Table *t, const TObject *key,
316 const TObject *val) {
179 Node *mp = luaH_mainposition(t, key); 317 Node *mp = luaH_mainposition(t, key);
180 if (ttype(val(mp)) != LUA_TNIL) { /* main position is not free? */ 318 if (ttype(val(mp)) != LUA_TNIL) { /* main position is not free? */
181 Node *othern = luaH_mainposition(t, key(mp)); /* `mp' of colliding node */ 319 Node *othern = luaH_mainposition(t, key(mp)); /* `mp' of colliding node */
@@ -197,21 +335,21 @@ static TObject *newkey (lua_State *L, Hash *t, const TObject *key) {
197 } 335 }
198 setobj(key(mp), key); 336 setobj(key(mp), key);
199 lua_assert(ttype(val(mp)) == LUA_TNIL); 337 lua_assert(ttype(val(mp)) == LUA_TNIL);
338 settableval(val(mp), val);
200 for (;;) { /* correct `firstfree' */ 339 for (;;) { /* correct `firstfree' */
201 if (ttype(key(t->firstfree)) == LUA_TNIL) 340 if (ttype(key(t->firstfree)) == LUA_TNIL)
202 return val(mp); /* OK; table still has a free place */ 341 return; /* OK; table still has a free place */
203 else if (t->firstfree == t->node) break; /* cannot decrement from here */ 342 else if (t->firstfree == t->node) break; /* cannot decrement from here */
204 else (t->firstfree)--; 343 else (t->firstfree)--;
205 } 344 }
206 rehash(L, t); /* no more free places */ 345 rehash(L, t); /* no more free places; must create one */
207 return newkey(L, t, key); /* `rehash' invalidates this insertion */
208} 346}
209 347
210 348
211/* 349/*
212** generic search function 350** generic search function
213*/ 351*/
214static const TObject *luaH_getany (Hash *t, const TObject *key) { 352static const TObject *luaH_getany (Table *t, const TObject *key) {
215 if (ttype(key) == LUA_TNIL) return &luaO_nilobject; 353 if (ttype(key) == LUA_TNIL) return &luaO_nilobject;
216 else { 354 else {
217 Node *n = luaH_mainposition(t, key); 355 Node *n = luaH_mainposition(t, key);
@@ -227,21 +365,25 @@ static const TObject *luaH_getany (Hash *t, const TObject *key) {
227/* 365/*
228** search function for integers 366** search function for integers
229*/ 367*/
230const TObject *luaH_getnum (Hash *t, int key) { 368const TObject *luaH_getnum (Table *t, int key) {
231 Node *n = hashnum(t, key); 369 if (1 <= key && key <= t->sizearray)
232 do { /* check whether `key' is somewhere in the chain */ 370 return &t->array[key-1];
233 if (ttype(key(n)) == LUA_TNUMBER && nvalue(key(n)) == (lua_Number)key) 371 else {
234 return val(n); /* that's it */ 372 Node *n = hashnum(t, key);
235 else n = n->next; 373 do { /* check whether `key' is somewhere in the chain */
236 } while (n); 374 if (ttype(key(n)) == LUA_TNUMBER && nvalue(key(n)) == (lua_Number)key)
237 return &luaO_nilobject; 375 return val(n); /* that's it */
376 else n = n->next;
377 } while (n);
378 return &luaO_nilobject;
379 }
238} 380}
239 381
240 382
241/* 383/*
242** search function for strings 384** search function for strings
243*/ 385*/
244const TObject *luaH_getstr (Hash *t, TString *key) { 386const TObject *luaH_getstr (Table *t, TString *key) {
245 Node *n = hashstr(t, key); 387 Node *n = hashstr(t, key);
246 do { /* check whether `key' is somewhere in the chain */ 388 do { /* check whether `key' is somewhere in the chain */
247 if (ttype(key(n)) == LUA_TSTRING && tsvalue(key(n)) == key) 389 if (ttype(key(n)) == LUA_TSTRING && tsvalue(key(n)) == key)
@@ -255,7 +397,7 @@ const TObject *luaH_getstr (Hash *t, TString *key) {
255/* 397/*
256** main search function 398** main search function
257*/ 399*/
258const TObject *luaH_get (Hash *t, const TObject *key) { 400const TObject *luaH_get (Table *t, const TObject *key) {
259 switch (ttype(key)) { 401 switch (ttype(key)) {
260 case LUA_TSTRING: return luaH_getstr(t, tsvalue(key)); 402 case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
261 case LUA_TNUMBER: { 403 case LUA_TNUMBER: {
@@ -269,34 +411,40 @@ const TObject *luaH_get (Hash *t, const TObject *key) {
269} 411}
270 412
271 413
272void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val) { 414void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val) {
273 const TObject *p = luaH_get(t, key); 415 const TObject *p = luaH_get(t, key);
274 if (p == &luaO_nilobject) { 416 if (p != &luaO_nilobject) {
417 settableval(p, val);
418 }
419 else {
275 if (ttype(key) == LUA_TNIL) luaD_error(L, l_s("table index is nil")); 420 if (ttype(key) == LUA_TNIL) luaD_error(L, l_s("table index is nil"));
276 p = newkey(L, t, key); 421 newkey(L, t, key, val);
277 } 422 }
278 settableval(p, val);
279} 423}
280 424
281 425
282void luaH_setstr (lua_State *L, Hash *t, TString *key, const TObject *val) { 426void luaH_setstr (lua_State *L, Table *t, TString *key, const TObject *val) {
283 const TObject *p = luaH_getstr(t, key); 427 const TObject *p = luaH_getstr(t, key);
284 if (p == &luaO_nilobject) { 428 if (p != &luaO_nilobject) {
429 settableval(p, val);
430 }
431 else {
285 TObject k; 432 TObject k;
286 setsvalue(&k, key); 433 setsvalue(&k, key);
287 p = newkey(L, t, &k); 434 newkey(L, t, &k, val);
288 } 435 }
289 settableval(p, val);
290} 436}
291 437
292 438
293void luaH_setnum (lua_State *L, Hash *t, int key, const TObject *val) { 439void luaH_setnum (lua_State *L, Table *t, int key, const TObject *val) {
294 const TObject *p = luaH_getnum(t, key); 440 const TObject *p = luaH_getnum(t, key);
295 if (p == &luaO_nilobject) { 441 if (p != &luaO_nilobject) {
442 settableval(p, val);
443 }
444 else {
296 TObject k; 445 TObject k;
297 setnvalue(&k, key); 446 setnvalue(&k, key);
298 p = newkey(L, t, &k); 447 newkey(L, t, &k, val);
299 } 448 }
300 settableval(p, val);
301} 449}
302 450
diff --git a/ltable.h b/ltable.h
index f342a6f0..aa41586e 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 1.34 2001/07/05 20:31:14 roberto Exp roberto $ 2** $Id: ltable.h,v 1.36 2001/08/31 19:46:07 roberto Exp $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -17,19 +17,19 @@
17#define settableval(p,v) setobj(cast(TObject *, p), v) 17#define settableval(p,v) setobj(cast(TObject *, p), v)
18 18
19 19
20const TObject *luaH_getnum (Hash *t, int key); 20const TObject *luaH_getnum (Table *t, int key);
21void luaH_setnum (lua_State *L, Hash *t, int key, const TObject *val); 21void luaH_setnum (lua_State *L, Table *t, int key, const TObject *val);
22const TObject *luaH_getstr (Hash *t, TString *key); 22const TObject *luaH_getstr (Table *t, TString *key);
23void luaH_setstr (lua_State *L, Hash *t, TString *key, const TObject *val); 23void luaH_setstr (lua_State *L, Table *t, TString *key, const TObject *val);
24const TObject *luaH_get (Hash *t, const TObject *key); 24const TObject *luaH_get (Table *t, const TObject *key);
25void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val); 25void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val);
26Hash *luaH_new (lua_State *L, int nhash); 26Table *luaH_new (lua_State *L, int narray, int lnhash);
27void luaH_free (lua_State *L, Hash *t); 27void luaH_free (lua_State *L, Table *t);
28Node *luaH_next (lua_State *L, Hash *t, const TObject *r); 28int luaH_index (lua_State *L, Table *t, const TObject *key);
29int luaH_nexti (Hash *t, int i); 29int luaH_nexti (Table *t, int i, TObject *where);
30 30
31/* exported only for debugging */ 31/* exported only for debugging */
32Node *luaH_mainposition (const Hash *t, const TObject *key); 32Node *luaH_mainposition (const Table *t, const TObject *key);
33 33
34 34
35#endif 35#endif
diff --git a/ltests.c b/ltests.c
index afcc460a..4b6e3de2 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 1.92 2001/10/02 16:45:03 roberto Exp $ 2** $Id: ltests.c,v 1.93 2001/10/17 21:12:57 roberto Exp $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -211,12 +211,6 @@ static int listlocals (lua_State *L) {
211/* }====================================================== */ 211/* }====================================================== */
212 212
213 213
214static int pushbool (lua_State *L, int b) {
215 if (b) lua_pushnumber(L, 1);
216 else lua_pushnil(L);
217 return 1;
218}
219
220 214
221 215
222static int get_limits (lua_State *L) { 216static int get_limits (lua_State *L) {
@@ -252,7 +246,7 @@ static int hash_query (lua_State *L) {
252 } 246 }
253 else { 247 else {
254 TObject *o = luaA_index(L, 1); 248 TObject *o = luaA_index(L, 1);
255 Hash *t; 249 Table *t;
256 luaL_checktype(L, 2, LUA_TTABLE); 250 luaL_checktype(L, 2, LUA_TTABLE);
257 t = hvalue(luaA_index(L, 2)); 251 t = hvalue(luaA_index(L, 2));
258 lua_pushnumber(L, luaH_mainposition(t, o) - t->node); 252 lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
@@ -262,16 +256,21 @@ static int hash_query (lua_State *L) {
262 256
263 257
264static int table_query (lua_State *L) { 258static int table_query (lua_State *L) {
265 const Hash *t; 259 const Table *t;
266 int i = luaL_opt_int(L, 2, -1); 260 int i = luaL_opt_int(L, 2, -1);
267 luaL_checktype(L, 1, LUA_TTABLE); 261 luaL_checktype(L, 1, LUA_TTABLE);
268 t = hvalue(luaA_index(L, 1)); 262 t = hvalue(luaA_index(L, 1));
269 if (i == -1) { 263 if (i == -1) {
270 lua_pushnumber(L, t->size); 264 lua_pushnumber(L, t->sizearray);
265 lua_pushnumber(L, sizenode(t));
271 lua_pushnumber(L, t->firstfree - t->node); 266 lua_pushnumber(L, t->firstfree - t->node);
272 return 2;
273 } 267 }
274 else if (i < t->size) { 268 else if (i < t->sizearray) {
269 lua_pushnumber(L, i);
270 luaA_pushobject(L, &t->array[i]);
271 lua_pushnil(L);
272 }
273 else if ((i -= t->sizearray) < sizenode(t)) {
275 if (ttype(val(node(t, i))) != LUA_TNIL || 274 if (ttype(val(node(t, i))) != LUA_TNIL ||
276 ttype(key(node(t, i))) == LUA_TNIL || 275 ttype(key(node(t, i))) == LUA_TNIL ||
277 ttype(key(node(t, i))) == LUA_TNUMBER) { 276 ttype(key(node(t, i))) == LUA_TNUMBER) {
@@ -280,14 +279,12 @@ static int table_query (lua_State *L) {
280 else 279 else
281 lua_pushstring(L, "<undef>"); 280 lua_pushstring(L, "<undef>");
282 luaA_pushobject(L, &t->node[i].val); 281 luaA_pushobject(L, &t->node[i].val);
283 if (t->node[i].next) { 282 if (t->node[i].next)
284 lua_pushnumber(L, t->node[i].next - t->node); 283 lua_pushnumber(L, t->node[i].next - t->node);
285 return 3;
286 }
287 else 284 else
288 return 2; 285 lua_pushnil(L);
289 } 286 }
290 return 0; 287 return 3;
291} 288}
292 289
293 290
@@ -448,11 +445,12 @@ static int settagmethod (lua_State *L) {
448 return 1; 445 return 1;
449} 446}
450 447
451static int equal (lua_State *L) { 448
452 return pushbool(L, lua_equal(L, 1, 2)); 449static int log2_aux (lua_State *L) {
450 lua_pushnumber(L, luaO_log2(luaL_check_int(L, 1)));
451 return 1;
453} 452}
454 453
455
456 454
457/* 455/*
458** {====================================================== 456** {======================================================
@@ -596,6 +594,13 @@ static int testC (lua_State *L) {
596 else 594 else
597 lua_pushnil(L); 595 lua_pushnil(L);
598 } 596 }
597 else if EQ(l_s("equal")) {
598 int a = getnum;
599 if (lua_equal(L, a, getnum))
600 lua_pushnumber(L, 1);
601 else
602 lua_pushnil(L);
603 }
599 else if EQ(l_s("rawcall")) { 604 else if EQ(l_s("rawcall")) {
600 int narg = getnum; 605 int narg = getnum;
601 int nres = getnum; 606 int nres = getnum;
@@ -656,7 +661,7 @@ static const struct luaL_reg tests_funcs[] = {
656 {l_s("closestate"), closestate}, 661 {l_s("closestate"), closestate},
657 {l_s("doremote"), doremote}, 662 {l_s("doremote"), doremote},
658 {l_s("settagmethod"), settagmethod}, 663 {l_s("settagmethod"), settagmethod},
659 {l_s("equal"), equal}, 664 {l_s("log2"), log2_aux},
660 {l_s("totalmem"), mem_query} 665 {l_s("totalmem"), mem_query}
661}; 666};
662 667
diff --git a/lvm.c b/lvm.c
index 980ed113..29877135 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.193 2001/09/07 17:39:10 roberto Exp $ 2** $Id: lvm.c,v 1.195 2001/10/02 16:45:03 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*/
@@ -295,7 +295,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
295 295
296static void luaV_pack (lua_State *L, StkId firstelem) { 296static void luaV_pack (lua_State *L, StkId firstelem) {
297 int i; 297 int i;
298 Hash *htab = luaH_new(L, 0); 298 Table *htab = luaH_new(L, 0, 0);
299 TObject n; 299 TObject n;
300 for (i=0; firstelem+i<L->top; i++) 300 for (i=0; firstelem+i<L->top; i++)
301 luaH_setnum(L, htab, i+1, firstelem+i); 301 luaH_setnum(L, htab, i+1, firstelem+i);
@@ -420,7 +420,9 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
420 break; 420 break;
421 } 421 }
422 case OP_NEWTABLE: { 422 case OP_NEWTABLE: {
423 sethvalue(ra, luaH_new(L, GETARG_Bc(i))); 423 int b = GETARG_B(i);
424 if (b > 0) b = twoto(b-1);
425 sethvalue(ra, luaH_new(L, b, GETARG_C(i)));
424 luaV_checkGC(L, ra+1); 426 luaV_checkGC(L, ra+1);
425 break; 427 break;
426 } 428 }
@@ -599,18 +601,15 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
599 /* go through */ 601 /* go through */
600 } 602 }
601 case OP_TFORLOOP: { 603 case OP_TFORLOOP: {
602 Hash *t; 604 Table *t;
603 int n; 605 int n;
604 runtime_check(L, ttype(ra) == LUA_TTABLE && 606 runtime_check(L, ttype(ra) == LUA_TTABLE &&
605 ttype(ra+1) == LUA_TNUMBER); 607 ttype(ra+1) == LUA_TNUMBER);
606 t = hvalue(ra); 608 t = hvalue(ra);
607 n = cast(int, nvalue(ra+1)); 609 n = cast(int, nvalue(ra+1));
608 n = luaH_nexti(t, n); 610 n = luaH_nexti(t, n, ra+2);
609 if (n != -1) { /* repeat loop? */ 611 if (n != -1) { /* repeat loop? */
610 Node *node = node(t, n);
611 setnvalue(ra+1, n); /* index */ 612 setnvalue(ra+1, n); /* index */
612 setobj(ra+2, key(node));
613 setobj(ra+3, val(node));
614 dojump(pc, i); /* repeat loop */ 613 dojump(pc, i); /* repeat loop */
615 } 614 }
616 break; 615 break;
@@ -619,7 +618,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
619 case OP_SETLISTO: { 618 case OP_SETLISTO: {
620 int bc; 619 int bc;
621 int n; 620 int n;
622 Hash *h; 621 Table *h;
623 runtime_check(L, ttype(ra) == LUA_TTABLE); 622 runtime_check(L, ttype(ra) == LUA_TTABLE);
624 h = hvalue(ra); 623 h = hvalue(ra);
625 bc = GETARG_Bc(i); 624 bc = GETARG_Bc(i);