- Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlstring.c
More file actions
Latest commit
110 lines (96 loc) · 3.18 KB
/
Copy pathlstring.c
File metadata and controls
110 lines (96 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
** $Id: lstring.c,v 2.8 2005/12/22 16:19:56 roberto Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
#include<string.h>
#definelstring_c
#defineLUA_CORE
#include"include/lua.h"
#include"include/lmem.h"
#include"include/lobject.h"
#include"include/lstate.h"
#include"include/lstring.h"
voidluaS_resize (lua_State*L, intnewsize) {
GCObject**newhash;
stringtable*tb;
inti;
if (G(L)->gcstate==GCSsweepstring)
return; /* cannot resize during GC traverse */
newhash=luaM_newvector(L, newsize, GCObject*);
tb=&G(L)->strt;
for (i=0; i<newsize; i++) newhash[i] =NULL;
/* rehash */
for (i=0; i<tb->size; i++) {
GCObject*p=tb->hash[i];
while (p) { /* for each node in the list */
GCObject*next=p->gch.next; /* save next */
unsigned inth=gco2ts(p)->hash;
inth1=lmod(h, newsize); /* new position */
lua_assert(cast_int(h%newsize) ==lmod(h, newsize));
p->gch.next=newhash[h1]; /* chain it */
newhash[h1] =p;
p=next;
}
}
luaM_freearray(L, tb->hash, tb->size, TString*);
tb->size=newsize;
tb->hash=newhash;
}
staticTString*newlstr (lua_State*L, constchar*str, size_tl,
unsigned inth) {
TString*ts;
stringtable*tb;
if (l+1> (MAX_SIZET-sizeof(TString))/sizeof(char))
luaM_toobig(L);
ts=cast(TString*, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
ts->tsv.len=l;
ts->tsv.hash=h;
ts->tsv.marked=luaC_white(G(L));
ts->tsv.tt=LUA_TSTRING;
ts->tsv.reserved=0;
memcpy(ts+1, str, l*sizeof(char));
((char*)(ts+1))[l] ='\0'; /* ending 0 */
tb=&G(L)->strt;
h=lmod(h, tb->size);
ts->tsv.next=tb->hash[h]; /* chain new entry */
tb->hash[h] =obj2gco(ts);
tb->nuse++;
if (tb->nuse>cast(lu_int32, tb->size) &&tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */
returnts;
}
TString*luaS_newlstr (lua_State*L, constchar*str, size_tl) {
GCObject*o;
unsigned inth=cast(unsignedint, l); /* seed */
size_tstep= (l>>5)+1; /* if string is too long, don't hash all its chars */
size_tl1;
for (l1=l; l1>=step; l1-=step) /* compute hash */
h=h ^ ((h<<5)+(h>>2)+cast(unsignedchar, str[l1-1]));
for (o=G(L)->strt.hash[lmod(h, G(L)->strt.size)];
o!=NULL;
o=o->gch.next) {
TString*ts=rawgco2ts(o);
if (ts->tsv.len==l&& (memcmp(str, getstr(ts), l) ==0)) {
/* string may be dead */
if (isdead(G(L), o)) changewhite(o);
returnts;
}
}
returnnewlstr(L, str, l, h); /* not found */
}
Udata*luaS_newudata (lua_State*L, size_ts, Table*e) {
Udata*u;
if (s>MAX_SIZET-sizeof(Udata))
luaM_toobig(L);
u=cast(Udata*, luaM_malloc(L, s+sizeof(Udata)));
u->uv.marked=luaC_white(G(L)); /* is not finalized */
u->uv.tt=LUA_TUSERDATA;
u->uv.len=s;
u->uv.metatable=NULL;
u->uv.env=e;
/* chain it on udata list (after main thread) */
u->uv.next=G(L)->mainthread->next;
G(L)->mainthread->next=obj2gco(u);
returnu;
}