2 ** $Id: lstring.c,v 1.78 2002/12/04 17:38:31 roberto Exp $
3 ** String table (keeps all strings handled by Lua)
4 ** See Copyright Notice in lua.h
21 void luaS_freeall (lua_State
*L
) {
22 lua_assert(G(L
)->strt
.nuse
==0);
23 luaM_freearray(L
, G(L
)->strt
.hash
, G(L
)->strt
.size
, TString
*);
27 void luaS_resize (lua_State
*L
, int newsize
) {
28 GCObject
**newhash
= luaM_newvector(L
, newsize
, GCObject
*);
29 stringtable
*tb
= &G(L
)->strt
;
31 for (i
=0; i
<newsize
; i
++) newhash
[i
] = NULL
;
33 for (i
=0; i
<tb
->size
; i
++) {
34 GCObject
*p
= tb
->hash
[i
];
35 while (p
) { /* for each node in the list */
36 GCObject
*next
= p
->gch
.next
; /* save next */
37 lu_hash h
= gcotots(p
)->tsv
.hash
;
38 int h1
= lmod(h
, newsize
); /* new position */
39 lua_assert(cast(int, h
%newsize
) == lmod(h
, newsize
));
40 p
->gch
.next
= newhash
[h1
]; /* chain it */
45 luaM_freearray(L
, tb
->hash
, tb
->size
, TString
*);
51 static TString
*newlstr (lua_State
*L
, const char *str
, size_t l
, lu_hash h
) {
52 TString
*ts
= cast(TString
*, luaM_malloc(L
, sizestring(l
)));
57 ts
->tsv
.tt
= LUA_TSTRING
;
59 memcpy(ts
+1, str
, l
*sizeof(char));
60 ((char *)(ts
+1))[l
] = '\0'; /* ending 0 */
62 h
= lmod(h
, tb
->size
);
63 ts
->tsv
.next
= tb
->hash
[h
]; /* chain new entry */
64 tb
->hash
[h
] = valtogco(ts
);
66 if (tb
->nuse
> cast(ls_nstr
, tb
->size
) && tb
->size
<= MAX_INT
/2)
67 luaS_resize(L
, tb
->size
*2); /* too crowded */
72 TString
*luaS_newlstr (lua_State
*L
, const char *str
, size_t l
) {
74 lu_hash h
= (lu_hash
)l
; /* seed */
75 size_t step
= (l
>>5)+1; /* if string is too long, don't hash all its chars */
77 for (l1
=l
; l1
>=step
; l1
-=step
) /* compute hash */
78 h
= h
^ ((h
<<5)+(h
>>2)+(unsigned char)(str
[l1
-1]));
79 for (o
= G(L
)->strt
.hash
[lmod(h
, G(L
)->strt
.size
)];
82 TString
*ts
= gcotots(o
);
83 if (ts
->tsv
.len
== l
&& (memcmp(str
, getstr(ts
), l
) == 0))
86 return newlstr(L
, str
, l
, h
); /* not found */
90 Udata
*luaS_newudata (lua_State
*L
, size_t s
) {
92 u
= cast(Udata
*, luaM_malloc(L
, sizeudata(s
)));
93 u
->uv
.marked
= (1<<1); /* is not finalized */
94 u
->uv
.tt
= LUA_TUSERDATA
;
96 u
->uv
.metatable
= hvalue(defaultmeta(L
));
97 /* chain it on udata list */
98 u
->uv
.next
= G(L
)->rootudata
;
99 G(L
)->rootudata
= valtogco(u
);