Skip to content

Commit

Permalink
TOMSCI: Adding lua_newbuf() API
Browse files Browse the repository at this point in the history
  • Loading branch information
tomsci committed Nov 18, 2018
1 parent 61fad77 commit 09bdc6c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 6 deletions.
40 changes: 40 additions & 0 deletions components/lua/lapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,46 @@ LUA_API void lua_pushrolstring (lua_State *L, const char *s, size_t len) {
}


LUA_API void *lua_newbuf(lua_State *L, size_t len) {
TString *ts = cast(TString *, luaM_malloc(L, (len+1)*sizeof(char)+sizeof(TString)));
ts->tsv.len = len;
ts->tsv.tt = LUA_TNIL;
ts->tsv.marked = 0; /* so sizestring works */
return ts + 1;
}


LUA_API void *lua_reallocbuf(lua_State *L, void *buf, size_t newlen) {
size_t oldsz, newsz;
TString *ts = cast(TString *, buf) - 1;
if (ts->tsv.tt != LUA_TNIL) {
lua_pushliteral(L, "Attempt to modify an invalid buf");
lua_error(L);
}
oldsz = (ts->tsv.len+1)*sizeof(char)+sizeof(TString);
if (newlen == 0) {
/* Free the buffer */
luaM_freemem(L, ts, oldsz);
return NULL;
}
newsz = (newlen+1)*sizeof(char)+sizeof(TString);
ts = cast(TString *, luaM_realloc_(L, ts, oldsz, newsz));
ts->tsv.len = newlen;
return ts + 1;
}


LUA_API void lua_pushbuf(lua_State *L, void *buf) {
TString *ts = cast(TString *, buf) - 1;
lua_lock(L);
luaC_checkGC(L);
luaS_buftostr(L, ts);
setsvalue2s(L, L->top, ts);
api_incr_top(L);
lua_unlock(L);
}


LUA_API void lua_pushstring (lua_State *L, const char *s) {
if (s == NULL)
lua_pushnil(L);
Expand Down
27 changes: 21 additions & 6 deletions components/lua/lstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "lstate.h"
#include "lstring.h"

#define LUAS_PREALLOCED_STRING 2
#define LUAS_READONLY_STRING 1
#define LUAS_REGULAR_STRING 0

Expand Down Expand Up @@ -53,25 +54,35 @@ void luaS_resize (lua_State *L, int newsize) {
}

static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h, int readonly) {
unsigned int h, int strtype) {
TString *ts;
stringtable *tb;
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L);
tb = &G(L)->strt;
if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */
ts = cast(TString *, luaM_malloc(L, readonly ? sizeof(char**)+sizeof(TString) : (l+1)*sizeof(char)+sizeof(TString)));
if (strtype == LUAS_PREALLOCED_STRING)
ts = cast(TString *, str) - 1;
else
ts = cast(TString *, luaM_malloc(L, strtype == LUAS_READONLY_STRING ? sizeof(char**)+sizeof(TString) : (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;
if (!readonly) {
switch (strtype) {
case LUAS_REGULAR_STRING:
memcpy(ts+1, str, l*sizeof(char));
/* Drop through */
case LUAS_PREALLOCED_STRING:
((char *)(ts+1))[l] = '\0'; /* ending 0 */
} else {
break;
case LUAS_READONLY_STRING:
*(char **)(ts+1) = (char *)str;
luaS_readonly(ts);
break;
default:
break;
}
h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h]; /* chain new entry */
Expand All @@ -81,7 +92,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
}


static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, int readonly) {
static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, int strtype) {
GCObject *o;
unsigned int h = cast(unsigned int, l); /* seed */
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
Expand All @@ -98,7 +109,7 @@ static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, in
return ts;
}
}
return newlstr(L, str, l, h, readonly); /* not found */
return newlstr(L, str, l, h, strtype); /* not found */
}

static int lua_is_ptr_in_ro_area(const char *p) {
Expand Down Expand Up @@ -146,3 +157,7 @@ Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
return u;
}


void luaS_buftostr (lua_State *L, TString *ts) {
luaS_newlstr_helper(L, cast(const char *, ts + 1), ts->tsv.len, LUAS_PREALLOCED_STRING);
}
2 changes: 2 additions & 0 deletions components/lua/lstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
LUAI_FUNC TString *luaS_newrolstr (lua_State *L, const char *str, size_t l);

LUAI_FUNC void luaS_buftostr (lua_State *L, TString *ts);

#endif
8 changes: 8 additions & 0 deletions components/lua/lua.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,14 @@ LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);


/*
** Buffer management
*/
LUA_API void *(lua_newbuf) (lua_State *L, size_t len);
LUA_API void *(lua_reallocbuf) (lua_State *L, void *buf, size_t newlen);
LUA_API void (lua_pushbuf) (lua_State *L, void *buf);
#define lua_freebuf(L, b) lua_reallocbuf(L, (b), 0)


/*
** ===============================================================
Expand Down

0 comments on commit 09bdc6c

Please sign in to comment.