ESP32: remove use of luaM_free in file module (#2631)

* file: remove use of luaM_free

* added safe pushlstring function
This commit is contained in:
Javier Peletier 2019-02-20 23:26:39 +01:00 committed by Arnim Läuger
parent 2339726097
commit d1eab2396c
3 changed files with 46 additions and 20 deletions

View File

@ -65,4 +65,9 @@ inline bool luaX_valid_ref(lua_ref_t ref) {
return ref > 0; return ref > 0;
} }
// luaX_pushlstring is the same as lua_pushlstring except it will return nonzero in case of error
// (instead of throwing an exception and never returning) and will put the error message on the top of the stack.
int luaX_pushlstring(lua_State* L, const char* s, size_t l);
#endif #endif

View File

@ -115,3 +115,26 @@ void luaX_set_ref(lua_State* L, int idx, lua_ref_t* ref) {
lua_pushvalue(L, idx); // push on the stack the referenced index lua_pushvalue(L, idx); // push on the stack the referenced index
*ref = luaL_ref(L, LUA_REGISTRYINDEX); // set the reference (pops 1 value) *ref = luaL_ref(L, LUA_REGISTRYINDEX); // set the reference (pops 1 value)
} }
// pushlstring_t is a helper struct to provide a protected lua_pushlstring call
typedef struct {
const char* s;
size_t l;
} pushlstring_t;
// safe_pushlstring is a private function meant to be called in protected mode.
static int safe_pushlstring(lua_State* L) {
pushlstring_t *ps = (pushlstring_t*)lua_touserdata(L,-1);
lua_pushlstring(L, ps->s, ps->l);
return 1;
}
// luaX_pushlstring is the same as lua_pushlstring except it will return nonzero in case of error
// (instead of throwing an exception and never returning) and will put the error message on the top of the stack.
int luaX_pushlstring(lua_State* L, const char* s, size_t l) {
lua_pushcfunction(L, &safe_pushlstring);
pushlstring_t* ps =(pushlstring_t*) lua_newuserdata(L, sizeof(pushlstring_t));
ps->s = s;
ps->l = l;
return lua_pcall(L, 1, 1, 0);
}

View File

@ -2,6 +2,7 @@
#include "module.h" #include "module.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lnodeaux.h"
#include "lmem.h" #include "lmem.h"
#include "platform.h" #include "platform.h"
@ -140,7 +141,6 @@ static int file_obj_free( lua_State *L )
if (ud->fd) { if (ud->fd) {
// close file if it's still open // close file if it's still open
vfs_close(ud->fd); vfs_close(ud->fd);
ud->fd = 0;
} }
return 0; return 0;
@ -383,12 +383,7 @@ static int file_stat( lua_State* L )
// g_read() // g_read()
static int file_g_read( lua_State* L, int n, int16_t end_char, int fd ) static int file_g_read( lua_State* L, int n, int16_t end_char, int fd )
{ {
static char *heap_mem = NULL; char *heap_mem = NULL;
// free leftover memory
if (heap_mem) {
luaM_free(L, heap_mem);
heap_mem = NULL;
}
if(n <= 0) if(n <= 0)
n = FILE_READ_CHUNK; n = FILE_READ_CHUNK;
@ -396,19 +391,19 @@ static int file_g_read( lua_State* L, int n, int16_t end_char, int fd )
if(end_char < 0 || end_char >255) if(end_char < 0 || end_char >255)
end_char = EOF; end_char = EOF;
if(!fd) if(!fd)
return luaL_error(L, "open a file first"); return luaL_error(L, "open a file first");
char *p; char *p;
int i; int i;
size_t bufsize = n;
if (n > LUAL_BUFFERSIZE) { if (n > LUAL_BUFFERSIZE) {
// get buffer from heap // get buffer from heap
p = heap_mem = luaM_malloc(L, n); p = heap_mem = luaM_malloc(L, bufsize);
} else { } else {
// small chunks go onto the stack // small chunks go onto the stack
p = alloca(n); p = alloca(bufsize);
} }
n = vfs_read(fd, p, n); n = vfs_read(fd, p, n);
@ -424,21 +419,24 @@ static int file_g_read( lua_State* L, int n, int16_t end_char, int fd )
i = n; i = n;
} }
int err = 0;
if (i == 0 || n == VFS_RES_ERR) { if (i == 0 || n == VFS_RES_ERR) {
if (heap_mem) {
luaM_free(L, heap_mem);
heap_mem = NULL;
}
lua_pushnil(L); lua_pushnil(L);
return 1; } else {
vfs_lseek(fd, -(n - i), VFS_SEEK_CUR);
err = luaX_pushlstring(L, p, i); // On error it will return nonzero and leave a message on top of the stack.
} }
vfs_lseek(fd, -(n - i), VFS_SEEK_CUR);
lua_pushlstring(L, p, i);
if (heap_mem) { if (heap_mem) {
luaM_free(L, heap_mem); luaM_freearray(L, heap_mem, bufsize, char);
heap_mem = NULL;
} }
if (err){
lua_error(L); // luaX_pushlstring failed and the error message is on top of the stack. Throw it.
// never returns
}
return 1; return 1;
} }