mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
165 lines
5.1 KiB
Diff
165 lines
5.1 KiB
Diff
From e8f6c3d34a36a0e9a994d49d2f3ae4c3af18a09a Mon Sep 17 00:00:00 2001
|
|
From: Juan Carrano <j.carrano@fu-berlin.de>
|
|
Date: Wed, 9 May 2018 14:05:53 +0200
|
|
Subject: [PATCH 5/7] Do not allocate buffers on the stack.
|
|
|
|
Change luaL_Buffer so that the memory for the object is always allocated in the heap.
|
|
---
|
|
lauxlib.c | 29 +++++++++++++++++++----------
|
|
lauxlib.h | 1 -
|
|
lstrlib.c | 6 +++---
|
|
ltablib.c | 2 +-
|
|
4 files changed, 23 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/lauxlib.c b/lauxlib.c
|
|
index 8bd2b5af..3767439f 100644
|
|
--- a/lauxlib.c
|
|
+++ b/lauxlib.c
|
|
@@ -23,6 +23,7 @@
|
|
*/
|
|
|
|
#include "lua.h"
|
|
+#include "llimits.h" /* to get lua_assert */
|
|
|
|
#include "lauxlib.h"
|
|
|
|
@@ -493,10 +494,9 @@ static void *newbox (lua_State *L, size_t newsize) {
|
|
|
|
|
|
/*
|
|
-** check whether buffer is using a userdata on the stack as a temporary
|
|
-** buffer
|
|
+** check whether buffer has been assigned a memory region.
|
|
*/
|
|
-#define buffonstack(B) ((B)->b != (B)->initb)
|
|
+#define buffallocated(B) ((B)->b != NULL)
|
|
|
|
|
|
/*
|
|
@@ -504,6 +504,15 @@ static void *newbox (lua_State *L, size_t newsize) {
|
|
*/
|
|
LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
|
|
lua_State *L = B->L;
|
|
+
|
|
+ lua_assert((B->size == 0) == (B->b == NULL));
|
|
+ lua_assert((B->n <= B->size));
|
|
+
|
|
+ /* Force an allocation if the requested size is zero and the buffer is not
|
|
+ * initialized. This avoids weird bugs */
|
|
+ if (sz == 0 && B->size == 0)
|
|
+ sz = 1;
|
|
+
|
|
if (B->size - B->n < sz) { /* not enough space? */
|
|
char *newbuff;
|
|
size_t newsize = B->size * 2; /* double buffer size */
|
|
@@ -512,11 +521,10 @@ LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
|
|
if (newsize < B->n || newsize - B->n < sz)
|
|
luaL_error(L, "buffer too large");
|
|
/* create larger buffer */
|
|
- if (buffonstack(B))
|
|
+ if (buffallocated(B))
|
|
newbuff = (char *)resizebox(L, -1, newsize);
|
|
else { /* no buffer yet */
|
|
newbuff = (char *)newbox(L, newsize);
|
|
- memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */
|
|
}
|
|
B->b = newbuff;
|
|
B->size = newsize;
|
|
@@ -542,7 +550,7 @@ LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
|
|
LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
|
|
lua_State *L = B->L;
|
|
lua_pushlstring(L, B->b, B->n);
|
|
- if (buffonstack(B)) {
|
|
+ if (buffallocated(B)) {
|
|
resizebox(L, -2, 0); /* delete old buffer */
|
|
lua_remove(L, -2); /* remove its header from the stack */
|
|
}
|
|
@@ -559,23 +567,24 @@ LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
|
|
lua_State *L = B->L;
|
|
size_t l;
|
|
const char *s = lua_tolstring(L, -1, &l);
|
|
- if (buffonstack(B))
|
|
+ if (buffallocated(B))
|
|
lua_insert(L, -2); /* put value below buffer */
|
|
luaL_addlstring(B, s, l);
|
|
- lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */
|
|
+ lua_remove(L, -2); /* remove value */
|
|
}
|
|
|
|
|
|
LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
|
|
B->L = L;
|
|
- B->b = B->initb;
|
|
+ B->b = NULL;
|
|
B->n = 0;
|
|
- B->size = LUAL_BUFFERSIZE;
|
|
+ B->size = 0;
|
|
}
|
|
|
|
|
|
LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
|
|
luaL_buffinit(L, B);
|
|
+
|
|
return luaL_prepbuffsize(B, sz);
|
|
}
|
|
|
|
diff --git a/lauxlib.h b/lauxlib.h
|
|
index 77d1494d..b11afc9a 100644
|
|
--- a/lauxlib.h
|
|
+++ b/lauxlib.h
|
|
@@ -148,7 +148,6 @@ typedef struct luaL_Buffer {
|
|
size_t size; /* buffer size */
|
|
size_t n; /* number of characters in buffer */
|
|
lua_State *L;
|
|
- char initb[LUAL_BUFFERSIZE]; /* initial buffer */
|
|
} luaL_Buffer;
|
|
|
|
|
|
diff --git a/lstrlib.c b/lstrlib.c
|
|
index 934b7db8..a978d07a 100644
|
|
--- a/lstrlib.c
|
|
+++ b/lstrlib.c
|
|
@@ -773,7 +773,7 @@ static int str_gsub (lua_State *L) {
|
|
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
|
|
tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
|
|
"string/function/table expected");
|
|
- luaL_buffinit(L, &b);
|
|
+ luaL_buffinitsize(L, &b, luaL_len(L, 1));
|
|
if (anchor) {
|
|
p++; lp--; /* skip anchor character */
|
|
}
|
|
@@ -1020,7 +1020,7 @@ static int str_format (lua_State *L) {
|
|
const char *strfrmt = luaL_checklstring(L, arg, &sfl);
|
|
const char *strfrmt_end = strfrmt+sfl;
|
|
luaL_Buffer b;
|
|
- luaL_buffinit(L, &b);
|
|
+ luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE);
|
|
while (strfrmt < strfrmt_end) {
|
|
if (*strfrmt != L_ESC)
|
|
luaL_addchar(&b, *strfrmt++);
|
|
@@ -1335,7 +1335,7 @@ static int str_pack (lua_State *L) {
|
|
size_t totalsize = 0; /* accumulate total size of result */
|
|
initheader(L, &h);
|
|
lua_pushnil(L); /* mark to separate arguments from string buffer */
|
|
- luaL_buffinit(L, &b);
|
|
+ luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE);
|
|
while (*fmt != '\0') {
|
|
int size, ntoalign;
|
|
KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
|
|
diff --git a/ltablib.c b/ltablib.c
|
|
index 588bf40d..0e50898b 100644
|
|
--- a/ltablib.c
|
|
+++ b/ltablib.c
|
|
@@ -173,7 +173,7 @@ static int tconcat (lua_State *L) {
|
|
const char *sep = luaL_optlstring(L, 2, "", &lsep);
|
|
lua_Integer i = luaL_optinteger(L, 3, 1);
|
|
last = luaL_optinteger(L, 4, last);
|
|
- luaL_buffinit(L, &b);
|
|
+ luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE);
|
|
for (; i < last; i++) {
|
|
addfield(L, &b, i);
|
|
luaL_addlstring(&b, sep, lsep);
|
|
--
|
|
2.25.1
|
|
|