aboutsummaryrefslogtreecommitdiff
path: root/lstring.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-11-09 17:05:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-11-09 17:05:42 -0300
commit024f9064f1b43758eb36aba52547edc0312bf4ba (patch)
tree9d8609112058e885196a581f0736fbdd94f7f94d /lstring.c
parent7f4906f565ab9f8b1125107a3abae3d759f3ecf2 (diff)
downloadlua-024f9064f1b43758eb36aba52547edc0312bf4ba.tar.gz
lua-024f9064f1b43758eb36aba52547edc0312bf4ba.tar.bz2
lua-024f9064f1b43758eb36aba52547edc0312bf4ba.zip
External strings
Strings can use external buffers to store their contents.
Diffstat (limited to 'lstring.c')
-rw-r--r--lstring.c78
1 files changed, 75 insertions, 3 deletions
diff --git a/lstring.c b/lstring.c
index c4b3c7ba..8701b705 100644
--- a/lstring.c
+++ b/lstring.c
@@ -136,6 +136,20 @@ void luaS_init (lua_State *L) {
136} 136}
137 137
138 138
139size_t luaS_sizelngstr (size_t len, int kind) {
140 switch (kind) {
141 case LSTRREG: /* regular long string */
142 /* don't need 'falloc'/'ud', but need space for content */
143 return offsetof(TString, falloc) + (len + 1) * sizeof(char);
144 case LSTRFIX: /* fixed external long string */
145 /* don't need 'falloc'/'ud' */
146 return offsetof(TString, falloc);
147 default: /* external long string with deallocation */
148 lua_assert(kind == LSTRMEM);
149 return sizeof(TString);
150 }
151}
152
139 153
140/* 154/*
141** creates a new string object 155** creates a new string object
@@ -153,11 +167,11 @@ static TString *createstrobj (lua_State *L, size_t totalsize, int tag,
153 167
154 168
155TString *luaS_createlngstrobj (lua_State *L, size_t l) { 169TString *luaS_createlngstrobj (lua_State *L, size_t l) {
156 size_t totalsize = sizestrlng(l); 170 size_t totalsize = luaS_sizelngstr(l, LSTRREG);
157 TString *ts = createstrobj(L, totalsize, LUA_VLNGSTR, G(L)->seed); 171 TString *ts = createstrobj(L, totalsize, LUA_VLNGSTR, G(L)->seed);
158 ts->u.lnglen = l; 172 ts->u.lnglen = l;
159 ts->shrlen = -1; /* signals that it is a long string */ 173 ts->shrlen = LSTRREG; /* signals that it is a regular long string */
160 ts->contents = cast_charp(ts) + sizeof(TString); 174 ts->contents = cast_charp(ts) + offsetof(TString, falloc);
161 ts->contents[l] = '\0'; /* ending 0 */ 175 ts->contents[l] = '\0'; /* ending 0 */
162 return ts; 176 return ts;
163} 177}
@@ -275,3 +289,61 @@ Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) {
275 return u; 289 return u;
276} 290}
277 291
292
293struct NewExt {
294 int kind;
295 const char *s;
296 size_t len;
297 TString *ts; /* output */
298};
299
300
301static void f_newext (lua_State *L, void *ud) {
302 struct NewExt *ne = cast(struct NewExt *, ud);
303 size_t size = luaS_sizelngstr(0, ne->kind);
304 ne->ts = createstrobj(L, size, LUA_VLNGSTR, G(L)->seed);
305}
306
307
308static void f_pintern (lua_State *L, void *ud) {
309 struct NewExt *ne = cast(struct NewExt *, ud);
310 ne->ts = internshrstr(L, ne->s, ne->len);
311}
312
313
314TString *luaS_newextlstr (lua_State *L,
315 const char *s, size_t len, lua_Alloc falloc, void *ud) {
316 struct NewExt ne;
317 if (len <= LUAI_MAXSHORTLEN) { /* short string? */
318 ne.s = s; ne.len = len;
319 if (!falloc)
320 f_pintern(L, &ne); /* just internalize string */
321 else {
322 int status = luaD_rawrunprotected(L, f_pintern, &ne);
323 (*falloc)(ud, cast_voidp(s), len + 1, 0); /* free external string */
324 if (status != LUA_OK) /* memory error? */
325 luaM_error(L); /* re-raise memory error */
326 }
327 return ne.ts;
328 }
329 /* "normal" case: long strings */
330 if (!falloc) {
331 ne.kind = LSTRFIX;
332 f_newext(L, &ne); /* just create header */
333 }
334 else {
335 ne.kind = LSTRMEM;
336 if (luaD_rawrunprotected(L, f_newext, &ne) != LUA_OK) { /* mem. error? */
337 (*falloc)(ud, cast_voidp(s), len + 1, 0); /* free external string */
338 luaM_error(L); /* re-raise memory error */
339 }
340 ne.ts->falloc = falloc;
341 ne.ts->ud = ud;
342 }
343 ne.ts->shrlen = ne.kind;
344 ne.ts->u.lnglen = len;
345 ne.ts->contents = cast_charp(s);
346 return ne.ts;
347}
348
349