2 ** $Id: lstring.c,v 2.8 2005/12/22 16:19:56 roberto Exp $
3 ** String table (keeps all strings handled by Lua)
4 ** See Copyright Notice in lua.h
22 void luaS_resize (lua_State
*L
, int newsize
) {
26 if (G(L
)->gcstate
== GCSsweepstring
)
27 return; /* cannot resize during GC traverse */
28 newhash
= luaM_newvector(L
, newsize
, GCObject
*);
30 for (i
=0; i
<newsize
; i
++) newhash
[i
] = NULL
;
32 for (i
=0; i
<tb
->size
; i
++) {
33 GCObject
*p
= tb
->hash
[i
];
34 while (p
) { /* for each node in the list */
35 GCObject
*next
= p
->gch
.next
; /* save next */
36 unsigned int h
= gco2ts(p
)->hash
;
37 int h1
= lmod(h
, newsize
); /* new position */
38 lua_assert(cast_int(h
%newsize
) == lmod(h
, newsize
));
39 p
->gch
.next
= newhash
[h1
]; /* chain it */
44 luaM_freearray(L
, tb
->hash
, tb
->size
, TString
*);
50 static TString
*newlstr (lua_State
*L
, const char *str
, size_t l
,
54 if (l
+1 > (MAX_SIZET
- sizeof(TString
))/sizeof(char))
56 ts
= cast(TString
*, luaM_malloc(L
, (l
+1)*sizeof(char)+sizeof(TString
)));
59 ts
->tsv
.marked
= luaC_white(G(L
));
60 ts
->tsv
.tt
= LUA_TSTRING
;
62 memcpy(ts
+1, str
, l
*sizeof(char));
63 ((char *)(ts
+1))[l
] = '\0'; /* ending 0 */
65 h
= lmod(h
, tb
->size
);
66 ts
->tsv
.next
= tb
->hash
[h
]; /* chain new entry */
67 tb
->hash
[h
] = obj2gco(ts
);
69 if (tb
->nuse
> cast(lu_int32
, tb
->size
) && tb
->size
<= MAX_INT
/2)
70 luaS_resize(L
, tb
->size
*2); /* too crowded */
75 TString
*luaS_newlstr (lua_State
*L
, const char *str
, size_t l
) {
77 unsigned int h
= cast(unsigned int, l
); /* seed */
78 size_t step
= (l
>>5)+1; /* if string is too long, don't hash all its chars */
80 for (l1
=l
; l1
>=step
; l1
-=step
) /* compute hash */
81 h
= h
^ ((h
<<5)+(h
>>2)+cast(unsigned char, str
[l1
-1]));
82 for (o
= G(L
)->strt
.hash
[lmod(h
, G(L
)->strt
.size
)];
85 TString
*ts
= rawgco2ts(o
);
86 if (ts
->tsv
.len
== l
&& (memcmp(str
, getstr(ts
), l
) == 0)) {
87 /* string may be dead */
88 if (isdead(G(L
), o
)) changewhite(o
);
92 return newlstr(L
, str
, l
, h
); /* not found */
96 Udata
*luaS_newudata (lua_State
*L
, size_t s
, Table
*e
) {
98 if (s
> MAX_SIZET
- sizeof(Udata
))
100 u
= cast(Udata
*, luaM_malloc(L
, s
+ sizeof(Udata
)));
101 u
->uv
.marked
= luaC_white(G(L
)); /* is not finalized */
102 u
->uv
.tt
= LUA_TUSERDATA
;
104 u
->uv
.metatable
= NULL
;
106 /* chain it on udata list (after main thread) */
107 u
->uv
.next
= G(L
)->mainthread
->next
;
108 G(L
)->mainthread
->next
= obj2gco(u
);