Unverified Commit 1f2e5bba authored by Terry Ellison's avatar Terry Ellison Committed by GitHub
Browse files

Implement panic call handling for all modules (#3163)

parent 4e689e98
......@@ -50,32 +50,25 @@ define prTV
printf "Boolean: %u\n", $val.n
end
if $type == 2
# ROTable
printf "ROTable: %p\n", $val.p
end
if $type == 3
# Light Function
printf "Light Func: %p\n", $val.p
end
if $type == 4
# Light User Data
printf "Light Udata: %p\n", $val.p
end
if $type == 5
if $type == 3
# Number
printf "Number: %u\n", $val.n
end
if $type == 6
prTS $arg0
if $type == 4
# String
printf "String: %s\n", (char *)($val.p)+16
end
if $type == 7
if $type == 5
# Table
set $o = &($val->gc.h)
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
printf "Nodes: %4i %p\n", 2<<($o->lsizenode), $o->node
printf "Arry: %4i %p\n", $o->sizearray, $o->array
end
if $type == 8
if $type == 6
# Function
set $o = &($val->gc.cl.c)
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
......@@ -88,16 +81,24 @@ define prTV
$o->nupvalues, $o->gclist, $o->env, $o->f
end
end
if $type == 9
if $type == 7
# UserData
set $o = &($val->gc.u.uv)
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
printf "UD = %p Userdata: metatable = ", ($o+1))
print ($o)->metatable
end
if $type == 10
if $type == 8
# Thread
end
if $type == 21
# ROTable
printf "ROTable: %p\n", $val.p
end
if $type == 38
# Light Function
printf "Light Func: %p\n", $val.p
end
end
end
......
......@@ -684,6 +684,26 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
}
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref) {
int reft;
/*
* If the ref is positive and the entry in table t exists then
* overwrite the value otherwise fall through to luaL_ref()
*/
if (ref) {
if (*ref >= 0) {
t = abs_index(L, t);
lua_rawgeti(L, t, *ref);
reft = lua_type(L, -1);
lua_pop(L, 1);
if (reft != LUA_TNIL) {
lua_rawseti(L, t, *ref);
return;
}
}
*ref = luaL_ref(L, t);
}
}
/*
** {======================================================
......@@ -899,23 +919,23 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
* is the option to exit the interactive session and start the Xtensa remote GDB
* which will then sync up with the remote GDB client to allow forensics of the error.
*/
#ifdef LUA_CROSS_COMPILER
LUALIB_API void lua_debugbreak(void) {
puts(" lua_debugbreak "); /* allows BT analysis of assert fails */
}
#else
extern void gdbstub_init(void);
extern void gdbstub_redirect_output(int);
LUALIB_API void lua_debugbreak(void) {
LUALIB_API void lua_debugbreak (void) {
#ifdef LUA_CROSS_COMPILER
puts(" lua_debugbreak "); /* allows gdb BT analysis of assert fails */
#else
static int repeat_entry = 0;
if (repeat_entry == 0) {
dbg_printf("Start up the gdb stub if not already started\n");
gdbstub_init();
gdbstub_redirect_output(1);
repeat_entry = 1;
}
asm("break 0,0" ::);
}
#endif
}
#endif
......
......@@ -73,6 +73,8 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
#define luaL_unref2(l,t,r) luaL_unref(L, (t), (r)); r = LUA_NOREF
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref);
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
......@@ -160,7 +162,6 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
/* }====================================================== */
LUALIB_API int luaL_traceback (lua_State *L);
LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres);
LUALIB_API int luaL_posttask( lua_State* L, int prio );
......
......@@ -668,7 +668,7 @@ static int isinstack (CallInfo *ci, const TValue *o) {
void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
const char *name = NULL;
const char *t = luaT_typenames[ttype(o)];
const char *t = luaT_typenames[basettype(o)];
const char *kind = (isinstack(L->ci, o)) ?
getobjname(L, L->ci, cast_int(o - L->base), &name) :
NULL;
......@@ -696,8 +696,8 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = luaT_typenames[ttype(p1)];
const char *t2 = luaT_typenames[ttype(p2)];
const char *t1 = luaT_typenames[basettype(p1)];
const char *t2 = luaT_typenames[basettype(p2)];
if (t1[2] == t2[2])
luaG_runerror(L, "attempt to compare two %s values", t1);
else
......
......@@ -138,7 +138,7 @@ static void flashErase(uint32_t start, uint32_t end){
}
/* =====================================================================================
* luaN_init(), luaN_reload_reboot() and luaN_index() are exported via lflash.h.
* luaN_init() is exported via lflash.h.
* The first is the startup hook used in lstate.c and the last two are
* implementations of the node.flash API calls.
*/
......@@ -194,10 +194,12 @@ static int loadLFS (lua_State *L);
static int loadLFSgc (lua_State *L);
static void procFirstPass (void);
/* lua_lfsreload() and lua_lfsindex() are exported via lua.h */
/*
* Library function called by node.flashreload(filename).
*/
LUALIB_API int luaN_reload_reboot (lua_State *L) {
LUALIB_API int lua_lfsreload (lua_State *L) {
const char *fn = lua_tostring(L, 1), *msg = "";
int status;
......@@ -266,7 +268,7 @@ LUALIB_API int luaN_reload_reboot (lua_State *L) {
* - The base address and length of the LFS
* - An array of the module names in the LFS
*/
LUAI_FUNC int luaN_index (lua_State *L) {
LUAI_FUNC int lua_lfsindex (lua_State *L) {
int n = lua_gettop(L);
/* Return nil + the LFS base address if the LFS size > 0 and it isn't loaded */
......
......@@ -26,27 +26,31 @@
** directly through the task interface the call is wrapped in a C closure with
** the error string as an Upval and this is posted to call the Lua reporter.
*/
static int report_traceback (lua_State *L) {
// **Temp** lua_rawgeti(L, LUA_REGISTRYINDEX, G(L)->error_reporter);
lua_getglobal(L, "print");
static int errhandler_aux (lua_State *L) {
lua_getfield(L, LUA_REGISTRYINDEX, "onerror");
if (!lua_isfunction(L, -1)) {
lua_pop(L, 1);
lua_getglobal(L, "print");
}
lua_pushvalue(L, lua_upvalueindex(1));
lua_call(L, 1, 0); /* Using an error handler would cause an infinite loop! */
return 0;
}
/*
** Catch all error handler for CB calls. This uses debug.traceback() to
** generate a full Lua traceback.
** Error handler for luaL_pcallx(), called from the lua_pcall() with a single
** argument -- the thrown error. This plus depth=2 is passed to debug.traceback()
** to convert into an error message which it handles in a separate posted task.
*/
LUALIB_API int luaL_traceback (lua_State *L) {
if (lua_isstring(L, 1)) {
lua_getglobal(L, "debug");
lua_getfield(L, -1, "traceback");
lua_remove(L, -2);
lua_pushvalue(L, 1); /* pass error message */
static int errhandler (lua_State *L) {
lua_getglobal(L, "debug");
lua_getfield(L, -1, "traceback");
if (lua_isfunction(L, -1)) {
lua_insert(L, 1); /* insert tracback function above error */
lua_pop(L, 1); /* dump the debug table entry */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback and return it as a string */
lua_pushcclosure(L, report_traceback, 1); /* report with str as upval */
lua_pushcclosure(L, errhandler_aux, 1); /* report with str as upval */
luaL_posttask(L, LUA_TASK_HIGH);
}
return 0;
......@@ -60,12 +64,16 @@ LUALIB_API int luaL_traceback (lua_State *L) {
LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres) { // [-narg, +0, v]
int status;
int base = lua_gettop(L) - narg;
lua_pushcfunction(L, luaL_traceback);
lua_pushcfunction(L, errhandler);
lua_insert(L, base); /* put under args */
status = lua_pcall(L, narg, (nres < 0 ? LUA_MULTRET : nres), base);
status = lua_pcall(L, narg, nres, base);
lua_remove(L, base); /* remove traceback function */
if (status && nres >=0)
lua_settop(L, base + nres); /* balance the stack on error */
if (status != LUA_OK && status != LUA_ERRRUN) {
lua_gc(L, LUA_GCCOLLECT, 0); /* call onerror directly if handler failed */
lua_pushliteral(L, "out of memory");
lua_pushcclosure(L, errhandler_aux, 1); /* report EOM as upval */
luaL_posttask(L, LUA_TASK_HIGH);
}
return status;
}
......
/* Read-only tables for Lua */
/*
* NodeMCU extensions to Lua 5.1 for readonly Flash memory support
*/
#ifndef lnodemcu_h
#define lnodemcu_h
......@@ -16,7 +17,8 @@
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".lua_" #s)))
#endif
/* Macros one can use to define rotable entries */
/* Macros used to declare rotable entries */
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
#define LRO_LUDATA(v) {{.p = cast(void*,v)}, LUA_TLIGHTUSERDATA}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
......@@ -25,7 +27,7 @@
#define LRO_FLOATVAL(v) LRO_NUMVAL(v)
#define LRO_ROVAL(v) {{.gc = cast(GCObject *, &(v ## _ROTable))}, LUA_TROTABLE}
#define LROT_MARKED 0 //<<<<<<<<<<*** TBD *** >>>>>>>>>>>
#define LROT_MARKED 0 //<<<<<<<<<< *** TBD *** >>>>>>>>>>>
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA(x)},
......@@ -38,9 +40,9 @@
#define LROT_ENTRYREF(rt) (rt ##_entries)
#define LROT_TABLEREF(rt) (&rt ##_ROTable)
#define LROT_BEGIN(rt,mt,f) LROT_TABLE(rt); \
static const ROTable_entry rt ## _entries[] = {
static ROTable_entry rt ## _entries[] = {
#define LROT_ENTRIES_IN_SECTION(rt,s) \
static const ROTable_entry LOCK_IN_SECTION(s) rt ## _entries[] = {
static ROTable_entry LOCK_IN_SECTION(s) rt ## _entries[] = {
#define LROT_END(rt,mt,f) {NULL, LRO_NILVAL} }; \
const ROTable rt ## _ROTable = { \
(GCObject *)1, LUA_TROTABLE, LROT_MARKED, \
......@@ -64,4 +66,9 @@
#define LROT_MASK_GC_INDEX (LROT_MASK_GC | LROT_MASK_INDEX)
/* Maximum length of a rotable name and of a string key*/
#ifdef LUA_CORE
#endif
#endif
......@@ -410,7 +410,7 @@ typedef struct Table {
GET_BYTE_FN(flags,Table,4,16)
GET_BYTE_FN(lsizenode,Table,4,24)
typedef struct ROTable_entry {
typedef const struct ROTable_entry {
const char *key;
const TValue value;
} ROTable_entry;
......
......@@ -383,10 +383,13 @@ struct lua_Debug {
/* }====================================================================== */
typedef struct ROTable ROTable;
typedef struct ROTable_entry ROTable_entry;
typedef const struct ROTable_entry ROTable_entry;
LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, const ROTable_entry *e, ROTable *mt);
LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, ROTable_entry *e, ROTable *mt);
LUAI_FUNC int lua_lfsreload (lua_State *L);
LUAI_FUNC int lua_lfsindex (lua_State *L);
#define EGC_NOT_ACTIVE 0 // EGC disabled
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
......@@ -413,7 +416,12 @@ LUA_API void lua_setegcmode(lua_State *L, int mode, int limit);
#define dbg_printf printf
#endif
extern void lua_debugbreak(void);
#ifdef DEVELOPMENT_USE_GDB
LUALIB_API void (lua_debugbreak)(void);
#else
#define lua_debugbreak() (void)(0)
#endif
// EGC operations modes
#define EGC_NOT_ACTIVE 0 // EGC disabled
......
......@@ -649,6 +649,28 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
}
}
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref) {
int reft;
/*
* If the ref is positive and the entry in table t exists then
* overwrite the value otherwise fall through to luaL_ref()
*/
if (ref) {
if (*ref >= 0) {
t = lua_absindex(L, t);
lua_rawgeti(L, t, *ref);
reft = lua_type(L, -1);
lua_pop(L, 1);
if (reft != LUA_TNIL) {
lua_rawseti(L, t, *ref);
return;
}
}
*ref = luaL_ref(L, t);
}
}
/* }====================================================== */
......@@ -1127,26 +1149,23 @@ static int errhandler_aux (lua_State *L) {
return 0;
}
/*
** Error handler for luaL_pcallx()
** Error handler for luaL_pcallx(), called from the lua_pcall() with a single
** argument -- the thrown error. This plus depth=2 is passed to debug.traceback()
** to convert into an error message which it handles in a separate posted task.
*/
static int errhandler (lua_State *L) {
if (lua_isnil(L, -1))
return 0;
if (lua_type(L, -1) != LUA_TSTRING) { /* is error object not a string? */
if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
lua_type(L, -1) == LUA_TSTRING) { /* that produces a string? */
lua_remove(L, 1); /* replace ToS with this */
} else if (!lua_isnil(L,-1)) {
lua_pushfstring(L, "(error object is a %s value)", luaL_typename(L, 1));
lua_remove(L, 1); /* replace ToS with error object is type value */
}
lua_getglobal(L, "debug");
lua_getfield(L, -1, "traceback");
if (lua_isfunction(L, -1)) {
lua_insert(L, 1); /* insert tracback function above error */
lua_pop(L, 1); /* dump the debug table entry */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback and return it as a string */
lua_pushcclosure(L, errhandler_aux, 1); /* report with str as upval */
luaL_posttask(L, LUA_TASK_HIGH);
}
luaL_traceback(L, L, lua_tostring(L, 1), 1); /* append a standard traceback */
lua_pushcclosure(L, errhandler_aux, 1); /* report with str as upval */
luaL_posttask(L, LUA_TASK_HIGH);
return 1; /* return the traceback */
return 0;
}
/*
......@@ -1155,11 +1174,17 @@ static int errhandler (lua_State *L) {
*/
LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres) {
int status;
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, errhandler); /* push message handler */
lua_insert(L, base); /* put it under function and args */
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, errhandler); /* push message handler */
lua_insert(L, base); /* put it under function and args */
status = lua_pcall(L, narg, nres, base);
lua_remove(L, base); /* remove message handler from the stack */
lua_remove(L, base); /* remove message handler from the stack */
if (status != LUA_OK && status != LUA_ERRRUN) {
lua_gc(L, LUA_GCCOLLECT, 0); /* call onerror directly if handler failed */
lua_pushliteral(L, "out of memory");
lua_pushcclosure(L, errhandler_aux, 1); /* report EOM as upval */
luaL_posttask(L, LUA_TASK_HIGH);
}
return status;
}
......@@ -1180,7 +1205,7 @@ static void do_task (platform_task_param_t task_fn_ref, uint8_t prio) {
luaL_checktype(L, -1, LUA_TFUNCTION);
luaL_unref(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
lua_pushinteger(L, prio);
luaL_pcallx (L, 1, 0);
luaL_pcallx(L, 1, 0);
}
/*
......
......@@ -79,6 +79,8 @@ LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
#define luaL_unref2(l,t,r) luaL_unref(L, (t), (r)); r = LUA_NOREF
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref);
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
const char *mode);
......
......@@ -83,7 +83,6 @@ typedef LUAI_UACNUMBER l_uacNumber;
typedef LUAI_UACINT l_uacInt;
#if defined(DEVELOPMENT_USE_GDB) && !defined(lua_assert)
extern void (lua_debugbreak)(void);
# define lua_assert(c) ((c) ? (void) 0 : lua_debugbreak())
#endif
......
......@@ -202,8 +202,6 @@ LUALIB_API void lua_debugbreak(void) {
asm("break 0,0" ::);
#endif
}
#else
#define lua_debugbreak() (void)(0)
#endif
//== NodeMCU lua.h API extensions ============================================//
......@@ -567,7 +565,7 @@ LUAI_FUNC int luaN_init (lua_State *L) {
#define getfield(L,t,f) \
lua_getglobal(L, #t); luaL_getmetafield( L, 1, #f ); lua_remove(L, -2);
LUAI_FUNC int luaN_reload_reboot (lua_State *L) {
LUAI_FUNC int lua_lfsreload (lua_State *L) {
int n = 0;
#ifdef LUA_USE_ESP
size_t l;
......@@ -579,6 +577,10 @@ LUAI_FUNC int luaN_reload_reboot (lua_State *L) {
#endif
lua_settop(L, 1);
lua_getglobal(L, "file");
if (lua_isnil(L, 2)) {
lua_pushstring(L, "No file system mounted");
return 1;
}
lua_getfield(L, 2, "exists");
lua_pushstring(L, img + off);
lua_call(L, 1, 1);
......@@ -594,7 +596,7 @@ LUAI_FUNC int luaN_reload_reboot (lua_State *L) {
return 1;
}
LUAI_FUNC int luaN_index (lua_State *L) {
LUAI_FUNC int lua_lfsindex (lua_State *L) {
lua_settop(L,1);
if (lua_isstring(L, 1)){
lua_getglobal(L, "LFS");
......
/*
* NodeMCU extensions to Lua for readonly Flash memory support
* NodeMCU extensions to Lua 5.3 for readonly Flash memory support
*/
#ifndef lnodemcu_h
#define lnodemcu_h
......@@ -27,7 +27,7 @@
#define LRO_FLOATVAL(v) {{.n = v}, LUA_TNUMFLT}
#define LRO_ROVAL(v) {{.gc = cast(GCObject *, &(v ## _ROTable))}, LUA_TTBLROF}
#define LROT_MARKED 0 //<<<<<<<<<<*** TBD *** >>>>>>>>>>>
#define LROT_MARKED 0 //<<<<<<<<<< *** TBD *** >>>>>>>>>>>
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA(x)},
......@@ -65,65 +65,18 @@
#define LROT_MASK_NEWINDEX LROT_MASK(NEWINDEX)
#define LROT_MASK_GC_INDEX (LROT_MASK_GC | LROT_MASK_INDEX)
/* Maximum length of a rotable name and of a string key*/
#define LUA_MAX_ROTABLE_NAME 32
#define LUA_MAX_ROTABLE_NAME 32 /* Maximum length of a rotable name and of a string key*/
#ifdef LUA_CORE
#include "lstate.h"
#include "lzio.h"
typedef struct FlashHeader LFSHeader;
/*
** The LFSHeader uses offsets rather than pointers to avoid 32 vs 64 bit issues
** during host compilation. The offsets are in units of lu_int32's and NOT
** size_t, though clearly any internal pointers are of the size_t for the
** executing architectures: 4 or 8 byte. Likewise recources are size_t aligned
** so LFS regions built for 64-bit execution will have 4-byte alignment packing
** between resources.
*/
struct FlashHeader{
lu_int32 flash_sig; /* a standard fingerprint identifying an LFS image */
lu_int32 flash_size; /* Size of LFS image in bytes */
lu_int32 seed; /* random number seed used in LFS */
lu_int32 timestamp; /* timestamp of LFS build */
lu_int32 nROuse; /* number of elements in ROstrt */
lu_int32 nROsize; /* size of ROstrt */
lu_int32 oROhash; /* offset of TString ** ROstrt hash */
lu_int32 protoROTable; /* offset of master ROTable for proto lookup */
lu_int32 protoHead; /* offset of linked list of Protos in LFS */
lu_int32 shortTShead; /* offset of linked list of short TStrings in LFS */
lu_int32 longTShead; /* offset of linked list of long TStrings in LFS */
lu_int32 reserved;
};
#ifdef LUA_USE_HOST
extern void *LFSregion;
LUAI_FUNC void luaN_setabsolute(lu_int32 addr);
#endif
#define FLASH_FORMAT_VERSION ( 2 << 8)
#define FLASH_SIG_B1 0x06
#define FLASH_SIG_B2 0x02
#define FLASH_SIG_PASS2 0x0F
#define FLASH_FORMAT_MASK 0xF00
#define FLASH_SIG_B2_MASK 0x04
#define FLASH_SIG_ABSOLUTE 0x01
#define FLASH_SIG_IN_PROGRESS 0x08
#define FLASH_SIG (0xfafaa050 | FLASH_FORMAT_VERSION)
#define FLASH_FORMAT_MASK 0xF00
LUAI_FUNC int luaN_init (lua_State *L);
LUAI_FUNC int luaN_flashSetup (lua_State *L);
LUAI_FUNC int luaN_reload_reboot (lua_State *L);
LUAI_FUNC int luaN_index (lua_State *L);
LUAI_FUNC void *luaN_writeFlash (void *data, const void *rec, size_t n);
LUAI_FUNC void luaN_flushFlash (void *);
LUAI_FUNC void luaN_setFlash (void *, unsigned int o);
#endif
#endif
......@@ -64,9 +64,10 @@ static void l_print (lua_State *L, int n) {
luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
lua_getglobal(L, "print");
lua_insert(L, -n-1);
if (lua_pcall(L, n, 0, 0) != LUA_OK)
lua_writestringerror( "error calling 'print' (%s)\n",
lua_tostring(L, -1));
if (lua_pcall(L, n, 0, 0) != LUA_OK) {
lua_writestringerror("error calling 'print' (%s)\n", lua_tostring(L, -1));
lua_settop(L, -n-1);
}
}
}
......@@ -75,52 +76,43 @@ static void l_print (lua_State *L, int n) {
** Message handler is used with all chunks calls. Returns the traceback on ToS
*/
static int msghandler (lua_State *L) {
const char *msg = lua_tostring(L, 1);
if (msg == NULL) { /* is error object not a string? */
if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */
return 1; /* that is the message */
msg = lua_pushfstring(L, "(error object is a %s value)",
luaL_typename(L, 1));
lua_remove(L, -2); /* otherwise swap with printable error */
lua_getglobal(L, "debug");
lua_getfield(L, -1, "traceback");
if (lua_isfunction(L, -1)) {
lua_insert(L, 1); /* insert tracback function above error */
lua_pop(L, 1); /* dump the debug table entry */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback and return it as a string */
}
#ifdef LUA_VERSION_51
lua_getglobal(L,"debug");
lua_getfield(L, -1,"traceback");
lua_insert(L, 1); /* pass error message */
lua_pop(L, 1);
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback */
#else /* LUA_VERSION_53 */
luaL_traceback(L, L, msg, 1); /* append a standard traceback */
#endif
return 1; /* return the traceback */
}
/*
** Interface to 'lua_pcall', which sets appropriate message function
** and error handler. Used to run all chunks.
** Interface to 'lua_pcall', which sets appropriate message function and error
** handler. Used to run all chunks. Results or error traceback left on stack.
** This function is interactive so unlike lua_pcallx(), the error is sent direct
** to the print function and erroring does not trigger an on error restart.
*/
static int docall (lua_State *L, int narg, int nres) {
static int docall (lua_State *L, int narg) {
int status;
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, msghandler); /* push message handler */
lua_insert(L, base); /* put it under chunk and args */
status = lua_pcall(L, narg, (nres ? 0 : LUA_MULTRET), base);
status = lua_pcall(L, narg, LUA_MULTRET, base);
lua_remove(L, base); /* remove message handler from the stack */
/* force a complete garbage collection in case of errors */
if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
return status;
}
#ifndef DISABLE_STARTUP_BANNER
static void print_version (lua_State *L) {
#ifndef DISABLE_STARTUP_BANNER
lua_writestringerror( "\n" NODE_VERSION " build " BUILD_DATE
" powered by " LUA_RELEASE " on SDK %s\n", SDK_VERSION);
#endif
}
#endif
/*
** Returns the string to be used as a prompt by the interpreter.
......@@ -164,7 +156,6 @@ static void l_create_stdin (lua_State *L);
** other C API and Lua functions might be executed as tasks between lines in
** a multiline, so a standard luaL_ref() registry entry is used instead.
*/
//// TODO SHOLD this have an boot return false if pipe empty else nil
static void dojob (lua_State *L) {
static int MLref = LUA_NOREF; /* Lua Reg entry for cached multi-line */
int status;
......@@ -204,21 +195,18 @@ static void dojob (lua_State *L) {
}
/* Execute the compiled chunk of successful */
if (status == 0)
status = docall(L, 0, 0);
status = docall(L, 0);
/* print any returned results or error message */
if (status && !lua_isnil(L, -1))
lua_writestringerror("Lua error: %s\n", lua_tostring(L, -1));
if (status == 0 && lua_gettop(L) - 1)
l_print(L, lua_gettop(L) - 1);
lua_settop(L, 2);
if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
if (status && !lua_isnil(L, -1)) {
lua_pushliteral(L, "Lua error: ");
lua_insert(L , -2);
}
l_print(L, lua_gettop(L) - 1); /* print error or results one stack */
}
prompt = get_prompt(L, MLref!= LUA_NOREF ? 0 : 1);
input_setprompt(prompt);
lua_writestring(prompt,strlen(prompt));
lua_pushnil(L);
}
......@@ -241,7 +229,9 @@ static int pmain (lua_State *L) {
input_setup(LUA_MAXINPUT, get_prompt(L, 1));
lua_input_string(" \n", 2); /* queue CR to issue first prompt */
#ifndef DISABLE_STARTUP_BANNER
print_version(L);
#endif
/*
* And last of all, kick off application initialisation. Note that if
* LUA_INIT_STRING is a file reference and the file system is uninitialised
......@@ -252,7 +242,7 @@ static int pmain (lua_State *L) {
luaL_loadfile(L, init+1) :
luaL_loadbuffer(L, init, strlen(init), "=INIT");
if (status == LUA_OK)
status = docall(L, 0, 0);
status = docall(L, 0);
if (status != LUA_OK)
l_print (L, 1);
return 0;
......@@ -274,7 +264,7 @@ int lua_main (void) {
}
globalL = L;
lua_pushcfunction(L, pmain);
if (docall(L, 0, 0) != LUA_OK) {
if (docall(L, 0) != LUA_OK) {
if (strstr(lua_tostring(L, -1),"!LFSrestart!")) {
lua_close(L);
return 1; /* non-zero return to flag LFS reload */
......@@ -337,7 +327,7 @@ static int l_read_stdin (lua_State *L) {
/* likewise if not CR terminated, then unread and ditto */
lua_insert(L, 1); /* insert false return above the pipe */
lua_getfield(L, 2, "unread");
lua_insert(L, 1); /* insert pipe.unread above the pipe */
lua_insert(L, 2); /* insert pipe.unread above the pipe */
lua_call(L, 2, 0); /* pobj:unread(line) */
return 1; /* return false */
}
......
......@@ -467,16 +467,15 @@ typedef struct ROTable ROTable;
typedef const struct ROTable_entry ROTable_entry;
typedef size_t KeyCache;
LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, const ROTable_entry *e, ROTable *mt);
LUA_API lua_State *(lua_getstate) (void);
LUA_API KeyCache *(lua_getcache) (int cl);
LUA_API int (lua_getstrings) (lua_State *L, int opt);
LUA_API int (lua_freeheap) (void);
LUAI_FUNC int luaN_flashSetup (lua_State *L);
LUAI_FUNC int luaN_reload_reboot (lua_State *L);
LUAI_FUNC int luaN_index (lua_State *L);
LUAI_FUNC int lua_lfsreload (lua_State *L);
LUAI_FUNC int lua_lfsindex (lua_State *L);
#define luaN_freearray(L,a,l) luaM_freearray(L,a,l)
......@@ -487,10 +486,11 @@ LUAI_FUNC int luaN_index (lua_State *L);
typedef struct Proto Proto;
#ifdef DEVELOPMENT_USE_GDB
LUALIB_API void lua_debugbreak(void);
#define ASSERT(s) if (!(s)) {();}
LUALIB_API void (lua_debugbreak)(void);
#define ASSERT(s) if (!(s)) {lua_debugbreak();}
#else
#define ASSERT(s)
#define lua_debugbreak() (void)(0)
#define ASSERT(s) (void)(0)
#endif
LUAI_FUNC int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv);
......
......@@ -48,4 +48,46 @@ LUAI_FUNC int luaU_DumpAllProtos(lua_State *L, const Proto *m, lua_Writer w,
void *data, int strip);
LUAI_FUNC int luaU_undumpLFS(lua_State *L, ZIO *Z, int isabs);
typedef struct FlashHeader LFSHeader;
/*
** The LFSHeader uses offsets rather than pointers to avoid 32 vs 64 bit issues
** during host compilation. The offsets are in units of lu_int32's and NOT
** size_t, though clearly any internal pointers are of the size_t for the
** executing architectures: 4 or 8 byte. Likewise recources are size_t aligned
** so LFS regions built for 64-bit execution will have 4-byte alignment packing
** between resources.
*/
struct FlashHeader{
lu_int32 flash_sig; /* a standard fingerprint identifying an LFS image */
lu_int32 flash_size; /* Size of LFS image in bytes */
lu_int32 seed; /* random number seed used in LFS */
lu_int32 timestamp; /* timestamp of LFS build */
lu_int32 nROuse; /* number of elements in ROstrt */
lu_int32 nROsize; /* size of ROstrt */
lu_int32 oROhash; /* offset of TString ** ROstrt hash */
lu_int32 protoROTable; /* offset of master ROTable for proto lookup */
lu_int32 protoHead; /* offset of linked list of Protos in LFS */
lu_int32 shortTShead; /* offset of linked list of short TStrings in LFS */
lu_int32 longTShead; /* offset of linked list of long TStrings in LFS */
lu_int32 reserved;
};
#ifdef LUA_USE_HOST
extern void *LFSregion;
LUAI_FUNC void luaN_setabsolute(lu_int32 addr);
#endif
#define FLASH_FORMAT_VERSION ( 2 << 8)
#define FLASH_SIG_B1 0x06
#define FLASH_SIG_B2 0x02
#define FLASH_SIG_PASS2 0x0F
#define FLASH_FORMAT_MASK 0xF00
#define FLASH_SIG_B2_MASK 0x04
#define FLASH_SIG_ABSOLUTE 0x01
#define FLASH_SIG_IN_PROGRESS 0x08
#define FLASH_SIG (0xfafaa050 | FLASH_FORMAT_VERSION)
#define FLASH_FORMAT_MASK 0xF00
#endif
......@@ -499,7 +499,7 @@ static int ads1115_lua_readoutdone(void * param) {
luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
ads_ctrl->timer_ref = LUA_NOREF;
read_common(ads_ctrl, raw, L);
lua_call(L, 4, 0);
luaL_pcallx(L, 4, 0);
}
// Read the conversion register from the ADC device
......
......@@ -320,9 +320,9 @@ static void bme280_readoutdone (void *arg)
NODE_DBG("timer out\n");
lua_State *L = lua_getstate();
lua_rawgeti (L, LUA_REGISTRYINDEX, lua_connected_readout_ref);
lua_call (L, 0, 0);
luaL_unref (L, LUA_REGISTRYINDEX, lua_connected_readout_ref);
os_timer_disarm (&bme280_timer);
luaL_pcallx (L, 0, 0);
}
static int bme280_lua_startreadout(lua_State* L) {
......
......@@ -430,9 +430,9 @@ static void bme280_readoutdone (void *arg)
NODE_DBG("timer out\n");
lua_State *L = lua_getstate();
lua_rawgeti (L, LUA_REGISTRYINDEX, lua_connected_readout_ref);
lua_call (L, 0, 0);
luaL_unref (L, LUA_REGISTRYINDEX, lua_connected_readout_ref);
os_timer_disarm (&bme680_timer);
luaL_pcallx (L, 0, 0);
}
static int bme680_lua_startreadout(lua_State* L) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment