diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-11-08 13:24:38 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-11-08 13:24:38 -0300 |
commit | 7f4906f565ab9f8b1125107a3abae3d759f3ecf2 (patch) | |
tree | f1c9c36ce0e96f1e89673bfe25175cbf83523bf6 /lstring.c | |
parent | b8a9d14032b717f6e5c493a9ec20e3494c9f82a0 (diff) | |
download | lua-7f4906f565ab9f8b1125107a3abae3d759f3ecf2.tar.gz lua-7f4906f565ab9f8b1125107a3abae3d759f3ecf2.tar.bz2 lua-7f4906f565ab9f8b1125107a3abae3d759f3ecf2.zip |
Towards external strings
Long strings have a pointer to string contents.
Diffstat (limited to 'lstring.c')
-rw-r--r-- | lstring.c | 19 |
1 files changed, 11 insertions, 8 deletions
@@ -140,24 +140,25 @@ void luaS_init (lua_State *L) { | |||
140 | /* | 140 | /* |
141 | ** creates a new string object | 141 | ** creates a new string object |
142 | */ | 142 | */ |
143 | static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { | 143 | static TString *createstrobj (lua_State *L, size_t totalsize, int tag, |
144 | unsigned int h) { | ||
144 | TString *ts; | 145 | TString *ts; |
145 | GCObject *o; | 146 | GCObject *o; |
146 | size_t totalsize; /* total size of TString object */ | ||
147 | totalsize = sizelstring(l); | ||
148 | o = luaC_newobj(L, tag, totalsize); | 147 | o = luaC_newobj(L, tag, totalsize); |
149 | ts = gco2ts(o); | 148 | ts = gco2ts(o); |
150 | ts->hash = h; | 149 | ts->hash = h; |
151 | ts->extra = 0; | 150 | ts->extra = 0; |
152 | getstr(ts)[l] = '\0'; /* ending 0 */ | ||
153 | return ts; | 151 | return ts; |
154 | } | 152 | } |
155 | 153 | ||
156 | 154 | ||
157 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { | 155 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { |
158 | TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); | 156 | size_t totalsize = sizestrlng(l); |
157 | TString *ts = createstrobj(L, totalsize, LUA_VLNGSTR, G(L)->seed); | ||
159 | ts->u.lnglen = l; | 158 | ts->u.lnglen = l; |
160 | ts->shrlen = 0xFF; /* signals that it is a long string */ | 159 | ts->shrlen = -1; /* signals that it is a long string */ |
160 | ts->contents = cast_charp(ts) + sizeof(TString); | ||
161 | ts->contents[l] = '\0'; /* ending 0 */ | ||
161 | return ts; | 162 | return ts; |
162 | } | 163 | } |
163 | 164 | ||
@@ -194,7 +195,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
194 | TString **list = &tb->hash[lmod(h, tb->size)]; | 195 | TString **list = &tb->hash[lmod(h, tb->size)]; |
195 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ | 196 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ |
196 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { | 197 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { |
197 | if (l == ts->shrlen && (memcmp(str, getshrstr(ts), l * sizeof(char)) == 0)) { | 198 | if (l == cast_uint(ts->shrlen) && |
199 | (memcmp(str, getshrstr(ts), l * sizeof(char)) == 0)) { | ||
198 | /* found! */ | 200 | /* found! */ |
199 | if (isdead(g, ts)) /* dead (but not collected yet)? */ | 201 | if (isdead(g, ts)) /* dead (but not collected yet)? */ |
200 | changewhite(ts); /* resurrect it */ | 202 | changewhite(ts); /* resurrect it */ |
@@ -206,8 +208,9 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
206 | growstrtab(L, tb); | 208 | growstrtab(L, tb); |
207 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ | 209 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ |
208 | } | 210 | } |
209 | ts = createstrobj(L, l, LUA_VSHRSTR, h); | 211 | ts = createstrobj(L, sizestrshr(l), LUA_VSHRSTR, h); |
210 | ts->shrlen = cast_byte(l); | 212 | ts->shrlen = cast_byte(l); |
213 | getshrstr(ts)[l] = '\0'; /* ending 0 */ | ||
211 | memcpy(getshrstr(ts), str, l * sizeof(char)); | 214 | memcpy(getshrstr(ts), str, l * sizeof(char)); |
212 | ts->u.hnext = *list; | 215 | ts->u.hnext = *list; |
213 | *list = ts; | 216 | *list = ts; |