Commit 17df207a authored by Johny Mattsson's avatar Johny Mattsson
Browse files

Port Terry's Lua 5.1 + 5.3 work from the esp8266 branch.

Changes have been kept to a minimum, but a serious chunk of work was
needed to move from 8266isms to IDFisms.

Some things got refactored into components/lua/common, in particular
the LFS location awareness.

As part of this work I also evicted our partition table manipulation
code, as with the current IDF it kept breaking checksums and rendering
things unbootable, which is the opposite of helpful (which was the
original intent behind it).

The uart module got relocated from base_nodemcu to the modules component
properly, after I worked out how to force its inclusion using Kconfig alone.
parent f123d462
...@@ -326,7 +326,7 @@ static int ow_crc16( lua_State *L ) ...@@ -326,7 +326,7 @@ static int ow_crc16( lua_State *L )
return 1; return 1;
} }
LROT_BEGIN(ow) LROT_BEGIN(ow, NULL, 0)
LROT_FUNCENTRY( setup, ow_setup ) LROT_FUNCENTRY( setup, ow_setup )
LROT_FUNCENTRY( reset, ow_reset ) LROT_FUNCENTRY( reset, ow_reset )
LROT_FUNCENTRY( skip, ow_skip ) LROT_FUNCENTRY( skip, ow_skip )
......
/*
** The pipe algo is somewhat similar to the luaL_Buffer algo, except that it
** uses table to store the LUAL_BUFFERSIZE byte array chunks instead of the
** stack. Writing is always to the last UD in the table and overflow pushes a
** new UD to the end of the table. Reading is always from the first UD in the
** table and underrun removes the first UD to shift a new one into slot 2. (Slot
** 1 of the table is reserved for the pipe reader function with 0 denoting no
** reader.)
**
** Reads and writes may span multiple UD buffers and if the read spans multiple
** UDs then the parts are collected as strings on the Lua stack and then
** concatenated with a lua_concat().
**
** Note that pipe tables also support the undocumented length and tostring
** operators for debugging puposes, so if p is a pipe then #p[i] gives the
** effective length of pipe slot i and printing p[i] gives its contents.
**
** The pipe library also supports the automatic scheduling of a reader task.
** This is declared by including a Lua CB function and an optional prioirty for
** it to execute at in the pipe.create() call. The reader task may or may not
** empty the FIFO (and there is also nothing to stop the task also writing to
** the FIFO. The reader automatically reschedules itself if the pipe contains
** unread content.
**
** The reader tasks may be interleaved with other tasks that write to the pipe
** and others that don't. Any task writing to the pipe will also trigger the
** posting of a read task if one is not already pending. In this way at most
** only one pending reader task is pending, and this prevents overrun of the
** task queueing system.
**
** Implementation Notes:
**
** - The Pipe slot 1 is used to store the Lua CB function reference of the
** reader task. Note that is actually an auxiliary wrapper around the
** supplied Lua CB function, and this wrapper also uses upvals to store
** internal pipe state. The remaining slots are the Userdata buffer chunks.
**
** - This internal state needs to be shared with the pipe_write function, but a
** limitation of Lua 5.1 is that C functions cannot share upvals; to avoid
** this constraint, this function is also denormalised to act as the
** pipe_write function: if Arg1 is the pipe then its a pipe:write() otherwise
** its a CB wrapper.
**
** Also note that the pipe module is used by the Lua VM and therefore the create
** read, and unread methods are exposed as directly callable C functions. (Write
** is available through pipe[1].)
**
** Read the docs/modules/pipe.md documentation for a functional description.
*/
#include "module.h"
#include "lauxlib.h"
#include <string.h>
#include "platform.h"
#include "task/task.h"
#define INVALID_LEN ((unsigned)-1)
typedef struct buffer {
int start, end;
char buf[LUAL_BUFFERSIZE];
} buffer_t;
#define AT_TAIL 0x00
#define AT_HEAD 0x01
#define WRITING 0x02
static buffer_t *checkPipeUD (lua_State *L, int ndx);
static buffer_t *newPipeUD(lua_State *L, int ndx, int n);
static int pipe_write_aux(lua_State *L);
LROT_TABLE(pipe_meta);
/* Validation and utility functions */
// [-0, +0, v]
static buffer_t *checkPipeTable (lua_State *L, int tbl, int flags) {
int m = lua_gettop(L), n = lua_objlen(L, tbl);
if (lua_istable(L, tbl) && lua_getmetatable(L, tbl)) {
lua_pushrotable(L, LROT_TABLEREF(pipe_meta));/* push comparison metatable */
if (lua_rawequal(L, -1, -2)) { /* check these match */
buffer_t *ud;
if (n == 1) {
ud = (flags & WRITING) ? newPipeUD(L, tbl, 2) : NULL;
} else {
int i = flags & AT_HEAD ? 2 : n; /* point to head or tail of T */
lua_rawgeti(L, tbl, i); /* and fetch UD */
ud = checkPipeUD(L, -1);
}
lua_settop(L, m);
return ud; /* and return ptr to buffer_t rec */
}
}
luaL_argerror(L, tbl, "pipe table");
return NULL; /* NORETURN avoid compiler error */
}
static buffer_t *checkPipeUD (lua_State *L, int ndx) { // [-0, +0, v]
luaL_checktype(L, ndx, LUA_TUSERDATA); /* NORETURN on error */
buffer_t *ud = lua_touserdata(L, ndx);
if (ud && lua_getmetatable(L, ndx)) { /* Get UD and its metatable? */
lua_pushrotable(L, LROT_TABLEREF(pipe_meta)); /* push correct metatable */
if (lua_rawequal(L, -1, -2)) { /* Do these match? */
lua_pop(L, 2); /* remove both metatables */
return ud; /* and return ptr to buffer_t rec */
}
}
return NULL;
}
/* Create new buffer chunk at `n` in the table which is at stack `ndx` */
static buffer_t *newPipeUD(lua_State *L, int ndx, int n) { // [-0,+0,-]
buffer_t *ud = (buffer_t *) lua_newuserdata(L, sizeof(buffer_t));
lua_pushrotable(L, LROT_TABLEREF(pipe_meta)); /* push the metatable */
lua_setmetatable(L, -2); /* set UD's metabtable to pipe_meta */
ud->start = ud->end = 0;
lua_rawseti(L, ndx, n); /* T[n] = new UD */
return ud; /* ud points to new T[n] */
}
#define CHAR_DELIM -1
#define CHAR_DELIM_KEEP -2
static char getsize_delim (lua_State *L, int ndx, int *len) { // [-0, +0, v]
char delim;
int n;
if( lua_type( L, ndx ) == LUA_TNUMBER ) {
n = luaL_checkinteger( L, ndx );
luaL_argcheck(L, n > 0, ndx, "invalid chunk size");
delim = '\0';
} else if (lua_isnil(L, ndx)) {
n = CHAR_DELIM;
delim = '\n';
} else {
size_t ldelim;
const char *s = lua_tolstring( L, 2, &ldelim);
n = ldelim == 2 && s[1] == '+' ? CHAR_DELIM_KEEP : CHAR_DELIM ;
luaL_argcheck(L, ldelim + n == 0, ndx, "invalid delimiter");
delim = s[0];
}
if (len)
*len = n;
return delim;
}
/*
** Read CB Initiator AND pipe_write. If arg1 == the pipe, then this is a pipe
** write(); otherwise it is the Lua CB wapper for the task post. This botch
** allows these two functions to share Upvals within the Lua 5.1 VM:
*/
#define UVpipe lua_upvalueindex(1) // The pipe table object
#define UVfunc lua_upvalueindex(2) // The CB's Lua function
#define UVprio lua_upvalueindex(3) // The task priority
#define UVstate lua_upvalueindex(4) // Pipe state;
#define CB_NOT_USED 0
#define CB_ACTIVE 1
#define CB_WRITE_UPDATED 2
#define CB_QUIESCENT 4
/*
** Note that nothing precludes the Lua CB function from itself writing to the
** pipe and in this case this routine will call itself recursively.
**
** The Lua CB itself takes the pipe object as a parameter and returns an
** optional boolean to force or to suppress automatic retasking if needed. If
** omitted, then the default is to repost if the pipe is not empty, otherwise
** the task chain is left to lapse.
*/
static int pipe_write_and_read_poster (lua_State *L) {
int state = lua_tointeger(L, UVstate);
if (lua_rawequal(L, 1, UVpipe)) {
/* arg1 == the pipe, so this was invoked as a pipe_write() */
if (pipe_write_aux(L) && state && !(state & CB_WRITE_UPDATED)) {
/*
* if this resulted in a write and not already in a CB and not already
* toggled the write update then post the task
*/
state |= CB_WRITE_UPDATED;
lua_pushinteger(L, state);
lua_replace(L, UVstate); /* Set CB state write updated flag */
if (state == (CB_QUIESCENT | CB_WRITE_UPDATED)) {
lua_rawgeti(L, 1, 1); /* Get CB ref from pipe[1] */
luaL_posttask(L, (int) lua_tointeger(L, UVprio)); /* and repost task */
}
}
} else if (state != CB_NOT_USED) {
/* invoked by the luaN_taskpost() so call the Lua CB */
int repost; /* can take the values CB_WRITE_UPDATED or 0 */
lua_pushinteger(L, CB_ACTIVE); /* CB state set to active only */
lua_replace(L, UVstate);
lua_pushvalue(L, UVfunc); /* Lua CB function */
lua_pushvalue(L, UVpipe); /* pipe table */
lua_call(L, 1, 1); /* Errors are thrown back to caller */
/*
* On return from the Lua CB, the task is never reposted if the pipe is empty.
* If it is not empty then the Lua CB return status determines when reposting
* occurs:
* - true = repost
* - false = don't repost
* - nil = only repost if there has been a write update.
*/
if (lua_isboolean(L,-1)) {
repost = (lua_toboolean(L, -1) == true &&
lua_objlen(L, UVpipe) > 1) ? CB_WRITE_UPDATED : 0;
} else {
repost = state & CB_WRITE_UPDATED;
}
state = CB_QUIESCENT | repost;
lua_pushinteger(L, state); /* Update the CB state */
lua_replace(L, UVstate);
if (repost) {
lua_rawgeti(L, UVpipe, 1); /* Get CB ref from pipe[1] */
luaL_posttask(L, (int) lua_tointeger(L, UVprio)); /* and repost task */
}
}
return 0;
}
/* Lua callable methods. Since the metatable is linked to both the pipe table */
/* and the userdata entries the __len & __tostring functions must handle both */
// Lua: buf = pipe.create()
int pipe_create(lua_State *L) {
int prio = -1;
lua_settop(L, 2); /* fix stack sze as 2 */
if (!lua_isnil(L, 1)) {
luaL_checktype(L, 1, LUA_TFUNCTION); /* non-nil arg1 must be a function */
if (lua_isnil(L, 2)) {
prio = TASK_PRIORITY_MEDIUM;
} else {
prio = (int) lua_tointeger(L, 2);
luaL_argcheck(L, prio >= TASK_PRIORITY_LOW &&
prio <= TASK_PRIORITY_HIGH, 2,
"invalid priority");
}
}
lua_createtable (L, 1, 0); /* create pipe table */
lua_pushrotable(L, LROT_TABLEREF(pipe_meta));
lua_setmetatable(L, -2); /* set pipe table's metabtable to pipe_meta */
lua_pushvalue(L, -1); /* UV1: pipe object */
lua_pushvalue(L, 1); /* UV2: CB function */
lua_pushinteger(L, prio); /* UV3: task priority */
lua_pushinteger(L, prio == -1 ? CB_NOT_USED : CB_QUIESCENT);
lua_pushcclosure(L, pipe_write_and_read_poster, 4); /* aux func for C task */
lua_rawseti(L, -2, 1); /* and write to T[1] */
return 1; /* return the table */
}
// len = #pipeobj[i]
static int pipe__len (lua_State *L) {
if (lua_istable(L, 1)) {
lua_pushinteger(L, lua_objlen(L, 1));
} else {
buffer_t *ud = checkPipeUD(L, 1);
lua_pushinteger(L, ud->end - ud->start);
}
return 1;
}
//Lua s = pipeUD:tostring()
static int pipe__tostring (lua_State *L) {
if (lua_istable(L, 1)) {
lua_pushfstring(L, "Pipe: %p", lua_topointer(L, 1));
} else {
buffer_t *ud = checkPipeUD(L, 1);
lua_pushlstring(L, ud->buf + ud->start, ud->end - ud->start);
}
return 1;
}
// Lua: rec = p:read(end_or_delim) // also [-2, +1,- ]
int pipe_read(lua_State *L) {
buffer_t *ud = checkPipeTable(L, 1, AT_HEAD);
int i, k=0, n;
lua_settop(L,2);
const char delim = getsize_delim(L, 2, &n);
lua_pop(L,1);
while (ud && n) {
int want, used, avail = ud->end - ud->start;
if (n < 0 /* one of the CHAR_DELIM flags */) {
/* getting a delimited chunk so scan for delimiter */
for (i = ud->start; i < ud->end && ud->buf[i] != delim; i++) {}
/* Can't have i = ud->end and ud->buf[i] == delim so either */
/* we've scanned full buffer avail OR we've hit a delim char */
if (i == ud->end) {
want = used = avail; /* case where we've scanned without a hit */
} else {
want = used = i + 1 - ud->start; /* case where we've hit a delim */
if (n == CHAR_DELIM)
want--;
n = 0; /* force loop exit because delim found */
}
} else {
want = used = (n < avail) ? n : avail;
n -= used;
}
lua_pushlstring(L, ud->buf + ud->start, want); /* part we want */
k++;
ud->start += used;
if (ud->start == ud->end) {
/* shift the pipe array down overwriting T[1] */
int nUD = lua_objlen(L, 1);
for (i = 2; i < nUD; i++) { /* for i = 2, nUD-1 */
lua_rawgeti(L, 1, i+1); lua_rawseti(L, 1, i); /* T[i] = T[i+1] */
}
lua_pushnil(L); lua_rawseti(L, 1, nUD--); /* T[n] = nil */
if (nUD>1) {
lua_rawgeti(L, 1, 2);
ud = checkPipeUD(L, -1);
lua_pop(L, 1);
} else {
ud = NULL;
}
}
}
if (k)
lua_concat(L, k);
else
lua_pushnil(L);
return 1;
}
// Lua: buf:unread(some_string)
int pipe_unread(lua_State *L) {
size_t l = INVALID_LEN;
const char *s = lua_tolstring(L, 2, &l);
if (l==0)
return 0;
luaL_argcheck(L, l != INVALID_LEN, 2, "must be a string");
buffer_t *ud = checkPipeTable(L, 1, AT_HEAD | WRITING);
do {
int used = ud->end - ud->start;
int lrem = LUAL_BUFFERSIZE-used;
if (used == LUAL_BUFFERSIZE) {
/* If the current UD is full insert a new UD at T[2] */
int i, nUD = lua_objlen(L, 1);
for (i = nUD; i > 1; i--) { /* for i = nUD,1,-1 */
lua_rawgeti(L, 1, i); lua_rawseti(L, 1, i+1); /* T[i+1] = T[i] */
}
ud = newPipeUD(L, 1, 2);
used = 0; lrem = LUAL_BUFFERSIZE;
/* Filling leftwards; make this chunk "empty but at the right end" */
ud->start = ud->end = LUAL_BUFFERSIZE;
} else if (ud->start < l) {
/* If the unread can't fit it before the start, shift content to end */
memmove(ud->buf + lrem,
ud->buf + ud->start, used); /* must be memmove not cpy */
ud->start = lrem; ud->end = LUAL_BUFFERSIZE;
}
if (l <= (unsigned )lrem)
break;
/* If we're here then the remaining string is strictly longer than the */
/* remaining buffer space; top off the buffer before looping around again */
l -= lrem;
memcpy(ud->buf, s + l, lrem);
ud->start = 0;
} while(1);
/* Copy any residual tail to the UD buffer.
* Here, ud != NULL and 0 <= l <= ud->start */
ud->start -= l;
memcpy(ud->buf + ud->start, s, l);
return 0;
}
// Lua: buf:write(some_string)
static int pipe_write_aux(lua_State *L) {
size_t l = INVALID_LEN;
const char *s = lua_tolstring(L, 2, &l);
//dbg_printf("pipe write(%u): %s", l, s);
if (l==0)
return false;
luaL_argcheck(L, l != INVALID_LEN, 2, "must be a string");
buffer_t *ud = checkPipeTable(L, 1, AT_TAIL | WRITING);
do {
int used = ud->end - ud->start;
if (used == LUAL_BUFFERSIZE) {
/* If the current UD is full insert a new UD at T[end] */
ud = newPipeUD(L, 1, lua_objlen(L, 1)+1);
used = 0;
} else if (LUAL_BUFFERSIZE - ud->end < l) {
/* If the write can't fit it at the end then shift content to the start */
memmove(ud->buf, ud->buf + ud->start, used); /* must be memmove not cpy */
ud->start = 0; ud->end = used;
}
int lrem = LUAL_BUFFERSIZE-used;
if (l <= (unsigned )lrem)
break;
/* If we've got here then the remaining string is longer than the buffer */
/* space left, so top off the buffer before looping around again */
memcpy(ud->buf + ud->end, s, lrem);
ud->end += lrem;
l -= lrem;
s += lrem;
} while(1);
/* Copy any residual tail to the UD buffer. Note that this is l>0 and */
memcpy(ud->buf + ud->end, s, l);
ud->end += l;
return true;
}
// Lua: fread = pobj:reader(1400) -- or other number
// fread = pobj:reader('\n') -- or other delimiter (delim is stripped)
// fread = pobj:reader('\n+') -- or other delimiter (delim is retained)
#define TBL lua_upvalueindex(1)
#define N lua_upvalueindex(2)
static int pipe_read_aux(lua_State *L) {
lua_settop(L, 0); /* ignore args since we use upvals instead */
lua_pushvalue(L, TBL);
lua_pushvalue(L, N);
return pipe_read(L);
}
static int pipe_reader(lua_State *L) {
lua_settop(L,2);
checkPipeTable (L, 1,AT_HEAD);
getsize_delim(L, 2, NULL);
lua_pushcclosure(L, pipe_read_aux, 2); /* return (closure, nil, table) */
return 1;
}
// return number of records
static int pipe_nrec (lua_State *L) {
lua_pushinteger(L, lua_objlen(L, 1) - 1);
return 1;
}
LROT_BEGIN(pipe_funcs, NULL, 0)
LROT_FUNCENTRY( __len, pipe__len )
LROT_FUNCENTRY( __tostring, pipe__tostring )
LROT_FUNCENTRY( read, pipe_read )
LROT_FUNCENTRY( reader, pipe_reader )
LROT_FUNCENTRY( unread, pipe_unread )
LROT_FUNCENTRY( nrec, pipe_nrec )
LROT_END(pipe_funcs, NULL, 0)
/* Using a index func is needed because the write method is at pipe[1] */
static int pipe__index(lua_State *L) {
lua_settop(L,2);
const char *k=lua_tostring(L,2);
if(!strcmp(k,"write")){
lua_rawgeti(L, 1, 1);
} else {
lua_pushrotable(L, LROT_TABLEREF(pipe_funcs));
lua_replace(L, 1);
lua_rawget(L, 1);
}
return 1;
}
LROT_BEGIN(pipe_meta, NULL, LROT_MASK_INDEX)
LROT_FUNCENTRY( __index, pipe__index)
LROT_FUNCENTRY( __len, pipe__len )
LROT_FUNCENTRY( __tostring, pipe__tostring )
LROT_END(pipe_meta, NULL, LROT_MASK_INDEX)
LROT_BEGIN(pipe, NULL, 0)
LROT_FUNCENTRY( create, pipe_create )
LROT_END(pipe, NULL, 0)
NODEMCU_MODULE(PIPE, "pipe", pipe, NULL);
...@@ -56,7 +56,7 @@ static int getPixel(lua_State *L) ...@@ -56,7 +56,7 @@ static int getPixel(lua_State *L)
return 1; return 1;
} }
LROT_BEGIN(qrcodegen) LROT_BEGIN(qrcodegen, NULL, 0)
LROT_FUNCENTRY(encodeText, encodeText) LROT_FUNCENTRY(encodeText, encodeText)
LROT_FUNCENTRY(getSize, getSize) LROT_FUNCENTRY(getSize, getSize)
LROT_FUNCENTRY(getPixel, getPixel) LROT_FUNCENTRY(getPixel, getPixel)
......
...@@ -77,7 +77,7 @@ static int sigma_delta_setduty( lua_State *L ) ...@@ -77,7 +77,7 @@ static int sigma_delta_setduty( lua_State *L )
// Module function map // Module function map
LROT_BEGIN(sigma_delta) LROT_BEGIN(sigma_delta, NULL, 0)
LROT_FUNCENTRY( setup, sigma_delta_setup ) LROT_FUNCENTRY( setup, sigma_delta_setup )
LROT_FUNCENTRY( close, sigma_delta_close ) LROT_FUNCENTRY( close, sigma_delta_close )
//LROT_FUNCENTRY( setpwmduty, sigma_delta_setpwmduty ) //LROT_FUNCENTRY( setpwmduty, sigma_delta_setpwmduty )
......
#define LUA_LIB #define LUA_LIB
#include "lua.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lstring.h"
#ifndef LOCAL_LUA #ifndef LOCAL_LUA
#include "module.h" #include "module.h"
...@@ -18,7 +16,9 @@ ...@@ -18,7 +16,9 @@
#define DEFAULT_DEPTH 20 #define DEFAULT_DEPTH 20
#define DBG_PRINTF(...) #define DBG_PRINTF(...)
#define SJSON_FLOAT_FMT ((sizeof(lua_Float) == 8) ? "%.19g" : "%.9g")
typedef struct { typedef struct {
jsonsl_t jsn; jsonsl_t jsn;
...@@ -86,31 +86,31 @@ create_new_element(jsonsl_t jsn, ...@@ -86,31 +86,31 @@ create_new_element(jsonsl_t jsn,
switch(state->type) { switch(state->type) {
case JSONSL_T_SPECIAL: case JSONSL_T_SPECIAL:
case JSONSL_T_STRING: case JSONSL_T_STRING:
case JSONSL_T_HKEY: case JSONSL_T_HKEY:
break; break;
case JSONSL_T_LIST: case JSONSL_T_LIST:
case JSONSL_T_OBJECT: case JSONSL_T_OBJECT:
create_table(data); create_table(data);
state->lua_object_ref = lua_ref(data->L, 1); state->lua_object_ref = luaL_ref(data->L, LUA_REGISTRYINDEX);
state->used_count = 0; state->used_count = 0;
lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref()); lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
if (data->hkey_ref == LUA_NOREF) { if (data->hkey_ref == LUA_NOREF) {
// list, so append // list, so append
lua_pushnumber(data->L, get_parent_object_used_count_pre_inc()); lua_pushinteger(data->L, get_parent_object_used_count_pre_inc());
DBG_PRINTF("Adding array element\n"); DBG_PRINTF("Adding array element\n");
} else { } else {
// object, so // object, so
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref); lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
lua_unref(data->L, data->hkey_ref); luaL_unref(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
data->hkey_ref = LUA_NOREF; data->hkey_ref = LUA_NOREF;
DBG_PRINTF("Adding hash element\n"); DBG_PRINTF("Adding hash element\n");
} }
if (data->pos_ref != LUA_NOREF && state->level > 1) { if (data->pos_ref != LUA_NOREF && state->level > 1) {
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref); lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
lua_pushnumber(data->L, state->level - 1); lua_pushinteger(data->L, state->level - 1);
lua_pushvalue(data->L, -3); // get the key lua_pushvalue(data->L, -3); // get the key
lua_settable(data->L, -3); lua_settable(data->L, -3);
lua_pop(data->L, 1); lua_pop(data->L, 1);
...@@ -118,13 +118,13 @@ create_new_element(jsonsl_t jsn, ...@@ -118,13 +118,13 @@ create_new_element(jsonsl_t jsn,
// At this point, the stack: // At this point, the stack:
// top: index/hash key // top: index/hash key
// : table // : table
int want_value = 1; int want_value = 1;
// Invoke the checkpath method if possible // Invoke the checkpath method if possible
if (data->pos_ref != LUA_NOREF) { if (data->pos_ref != LUA_NOREF) {
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->metatable); lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->metatable);
lua_getfield(data->L, -1, "checkpath"); lua_getfield(data->L, -1, "checkpath");
if (lua_type(data->L, -1) != LUA_TNIL) { if (!lua_isnil(data->L, -1)) {
// Call with the new table and the path as arguments // Call with the new table and the path as arguments
lua_rawgeti(data->L, LUA_REGISTRYINDEX, state->lua_object_ref); lua_rawgeti(data->L, LUA_REGISTRYINDEX, state->lua_object_ref);
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref); lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
...@@ -155,9 +155,15 @@ create_new_element(jsonsl_t jsn, ...@@ -155,9 +155,15 @@ create_new_element(jsonsl_t jsn,
static void push_number(JSN_DATA *data, struct jsonsl_state_st *state) { static void push_number(JSN_DATA *data, struct jsonsl_state_st *state) {
lua_pushlstring(data->L, get_state_buffer(data, state), state->pos_cur - state->pos_begin); lua_pushlstring(data->L, get_state_buffer(data, state), state->pos_cur - state->pos_begin);
LUA_NUMBER r = lua_tonumber(data->L, -1); #if LUA_VERSION_NUM == 501
lua_pop(data->L, 1); lua_pushnumber(data->L, lua_tonumber(data->L, -1));
lua_pushnumber(data->L, r); #else
if (!lua_stringtonumber(data->L, lua_tostring(data->L, -1))) {
// In this case stringtonumber does not push a value
luaL_error(data->L, "Invalid number");
}
#endif
lua_remove(data->L, -2);
} }
static int fromhex(char c) { static int fromhex(char c) {
...@@ -217,7 +223,7 @@ static void push_string(JSN_DATA *data, struct jsonsl_state_st *state) { ...@@ -217,7 +223,7 @@ static void push_string(JSN_DATA *data, struct jsonsl_state_st *state) {
continue; continue;
} }
} }
luaL_putchar(&b, nc); luaL_addchar(&b, nc);
} }
luaL_pushresult(&b); luaL_pushresult(&b);
} }
...@@ -236,18 +242,18 @@ cleanup_closing_element(jsonsl_t jsn, ...@@ -236,18 +242,18 @@ cleanup_closing_element(jsonsl_t jsn,
switch (state->type) { switch (state->type) {
case JSONSL_T_HKEY: case JSONSL_T_HKEY:
push_string(data, state); push_string(data, state);
data->hkey_ref = lua_ref(data->L, 1); data->hkey_ref = luaL_ref(data->L, LUA_REGISTRYINDEX);
break; break;
case JSONSL_T_STRING: case JSONSL_T_STRING:
lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref()); lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
if (data->hkey_ref == LUA_NOREF) { if (data->hkey_ref == LUA_NOREF) {
// list, so append // list, so append
lua_pushnumber(data->L, get_parent_object_used_count_pre_inc()); lua_pushinteger(data->L, get_parent_object_used_count_pre_inc());
} else { } else {
// object, so // object, so
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref); lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
lua_unref(data->L, data->hkey_ref); luaL_unref(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
data->hkey_ref = LUA_NOREF; data->hkey_ref = LUA_NOREF;
} }
push_string(data, state); push_string(data, state);
...@@ -274,11 +280,11 @@ cleanup_closing_element(jsonsl_t jsn, ...@@ -274,11 +280,11 @@ cleanup_closing_element(jsonsl_t jsn,
lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref()); lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
if (data->hkey_ref == LUA_NOREF) { if (data->hkey_ref == LUA_NOREF) {
// list, so append // list, so append
lua_pushnumber(data->L, get_parent_object_used_count_pre_inc()); lua_pushinteger(data->L, get_parent_object_used_count_pre_inc());
} else { } else {
// object, so // object, so
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref); lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
lua_unref(data->L, data->hkey_ref); luaL_unref(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
data->hkey_ref = LUA_NOREF; data->hkey_ref = LUA_NOREF;
} }
lua_pushvalue(data->L, -3); lua_pushvalue(data->L, -3);
...@@ -289,11 +295,11 @@ cleanup_closing_element(jsonsl_t jsn, ...@@ -289,11 +295,11 @@ cleanup_closing_element(jsonsl_t jsn,
break; break;
case JSONSL_T_OBJECT: case JSONSL_T_OBJECT:
case JSONSL_T_LIST: case JSONSL_T_LIST:
lua_unref(data->L, state->lua_object_ref); luaL_unref(data->L, LUA_REGISTRYINDEX, state->lua_object_ref);
state->lua_object_ref = LUA_NOREF; state->lua_object_ref = LUA_NOREF;
if (data->pos_ref != LUA_NOREF) { if (data->pos_ref != LUA_NOREF) {
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref); lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
lua_pushnumber(data->L, state->level); lua_pushinteger(data->L, state->level);
lua_pushnil(data->L); lua_pushnil(data->L);
lua_settable(data->L, -3); lua_settable(data->L, -3);
lua_pop(data->L, 1); lua_pop(data->L, 1);
...@@ -347,11 +353,11 @@ static int sjson_decoder_int(lua_State *L, int argno) { ...@@ -347,11 +353,11 @@ static int sjson_decoder_int(lua_State *L, int argno) {
data->error = NULL; data->error = NULL;
data->L = L; data->L = L;
data->buffer_len = 0; data->buffer_len = 0;
data->min_needed = data->min_available = jsn->pos; data->min_needed = data->min_available = jsn->pos;
lua_pushlightuserdata(L, 0); lua_pushlightuserdata(L, 0);
data->null_ref = lua_ref(L, 1); data->null_ref = luaL_ref(L, LUA_REGISTRYINDEX);
// This may throw... // This may throw...
lua_newtable(L); lua_newtable(L);
...@@ -361,25 +367,25 @@ static int sjson_decoder_int(lua_State *L, int argno) { ...@@ -361,25 +367,25 @@ static int sjson_decoder_int(lua_State *L, int argno) {
luaL_unref(L, LUA_REGISTRYINDEX, data->null_ref); luaL_unref(L, LUA_REGISTRYINDEX, data->null_ref);
data->null_ref = LUA_NOREF; data->null_ref = LUA_NOREF;
lua_getfield(L, argno, "null"); lua_getfield(L, argno, "null");
data->null_ref = lua_ref(L, 1); data->null_ref = luaL_ref(L, LUA_REGISTRYINDEX);
lua_getfield(L, argno, "metatable"); lua_getfield(L, argno, "metatable");
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
data->metatable = lua_ref(L, 1); data->metatable = luaL_ref(L, LUA_REGISTRYINDEX);
if (lua_type(L, -1) != LUA_TNIL) { if (!lua_isnil(L, -1)) {
lua_getfield(L, -1, "checkpath"); lua_getfield(L, -1, "checkpath");
if (lua_type(L, -1) != LUA_TNIL) { if (!lua_isnil(L, -1)) {
lua_newtable(L); lua_newtable(L);
data->pos_ref = lua_ref(L, 1); data->pos_ref = luaL_ref(L, LUA_REGISTRYINDEX);
} }
lua_pop(L, 1); // Throw away the checkpath value lua_pop(L, 1); // Throw away the checkpath value
} }
lua_pop(L, 1); // Throw away the metatable lua_pop(L, 1); // Throw away the metatable
} }
jsonsl_enable_all_callbacks(data->jsn); jsonsl_enable_all_callbacks(data->jsn);
jsn->action_callback = NULL; jsn->action_callback = NULL;
jsn->action_callback_PUSH = create_new_element; jsn->action_callback_PUSH = create_new_element;
jsn->action_callback_POP = cleanup_closing_element; jsn->action_callback_POP = cleanup_closing_element;
...@@ -477,7 +483,7 @@ static int sjson_decoder_write_int(lua_State *L, int udata_pos, int string_pos) ...@@ -477,7 +483,7 @@ static int sjson_decoder_write_int(lua_State *L, int udata_pos, int string_pos)
size_t blen; size_t blen;
data->buffer = luaL_checklstring(L, -1, &blen); data->buffer = luaL_checklstring(L, -1, &blen);
data->buffer_len = blen; data->buffer_len = blen;
data->buffer_ref = lua_ref(L, 1); data->buffer_ref = luaL_ref(L, LUA_REGISTRYINDEX);
jsonsl_feed(data->jsn, str, len); jsonsl_feed(data->jsn, str, len);
...@@ -611,9 +617,9 @@ static void enc_pop_stack(lua_State *L, ENC_DATA *data) { ...@@ -611,9 +617,9 @@ static void enc_pop_stack(lua_State *L, ENC_DATA *data) {
} }
ENC_DATA_STATE *state = &data->stack[data->level]; ENC_DATA_STATE *state = &data->stack[data->level];
lua_unref(L, state->lua_object_ref); luaL_unref(L, LUA_REGISTRYINDEX, state->lua_object_ref);
state->lua_object_ref = LUA_NOREF; state->lua_object_ref = LUA_NOREF;
lua_unref(L, state->lua_key_ref); luaL_unref(L, LUA_REGISTRYINDEX, state->lua_key_ref);
state->lua_key_ref = LUA_REFNIL; state->lua_key_ref = LUA_REFNIL;
data->level--; data->level--;
} }
...@@ -624,7 +630,7 @@ static void enc_push_stack(lua_State *L, ENC_DATA *data, int argno) { ...@@ -624,7 +630,7 @@ static void enc_push_stack(lua_State *L, ENC_DATA *data, int argno) {
} }
lua_pushvalue(L, argno); lua_pushvalue(L, argno);
ENC_DATA_STATE *state = &data->stack[data->level]; ENC_DATA_STATE *state = &data->stack[data->level];
state->lua_object_ref = lua_ref(L, 1); state->lua_object_ref = luaL_ref(L, LUA_REGISTRYINDEX);
state->size = sjson_encoder_get_table_size(L, argno); state->size = sjson_encoder_get_table_size(L, argno);
state->offset = 0; // We haven't started on this one yet state->offset = 0; // We haven't started on this one yet
} }
...@@ -674,7 +680,7 @@ static int sjson_encoder(lua_State *L) { ...@@ -674,7 +680,7 @@ static int sjson_encoder(lua_State *L) {
luaL_unref(L, LUA_REGISTRYINDEX, data->null_ref); luaL_unref(L, LUA_REGISTRYINDEX, data->null_ref);
data->null_ref = LUA_NOREF; data->null_ref = LUA_NOREF;
lua_getfield(L, argno, "null"); lua_getfield(L, argno, "null");
data->null_ref = lua_ref(L, 1); data->null_ref = luaL_ref(L, LUA_REGISTRYINDEX);
} }
return 1; return 1;
...@@ -694,7 +700,7 @@ static void encode_lua_object(lua_State *L, ENC_DATA *data, int argno, const cha ...@@ -694,7 +700,7 @@ static void encode_lua_object(lua_State *L, ENC_DATA *data, int argno, const cha
lua_rawgeti(L, LUA_REGISTRYINDEX, data->null_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->null_ref);
if (lua_equal(L, -1, -2)) { if (lua_equal(L, -1, -2)) {
type = LUA_TNIL; type = LUA_TNIL;
} }
lua_pop(L, 1); lua_pop(L, 1);
} }
} }
...@@ -716,12 +722,27 @@ static void encode_lua_object(lua_State *L, ENC_DATA *data, int argno, const cha ...@@ -716,12 +722,27 @@ static void encode_lua_object(lua_State *L, ENC_DATA *data, int argno, const cha
case LUA_TNUMBER: case LUA_TNUMBER:
{ {
lua_pushvalue(L, argno); lua_pushvalue(L, argno);
size_t len; char value[50];
const char *str = lua_tolstring(L, -1, &len);
char value[len + 1]; #if LUA_VERSION_NUM == 501
strcpy(value, str); #ifdef LUA_NUMBER_INTEGRAL
snprintf(value, sizeof(value), "%d", lua_tointeger(L, -1));
#else
snprintf(value, sizeof(value), SJSON_FLOAT_FMT, lua_tonumber(L, -1));
#endif
#else
if (lua_isinteger(L, -1)) {
snprintf(value, sizeof(value), LUA_INTEGER_FMT, lua_tointeger(L, -1));
} else {
snprintf(value, sizeof(value), SJSON_FLOAT_FMT, lua_tonumber(L, -1));
}
#endif
lua_pop(L, 1); lua_pop(L, 1);
luaL_addstring(&b, value); if (strcmp(value, "-inf") == 0 || strcmp(value, "nan") == 0 || strcmp(value, "inf") == 0) {
luaL_addstring(&b, "null"); // According to ECMA-262 section 24.5.2 Note 4
} else {
luaL_addstring(&b, value);
}
break; break;
} }
...@@ -785,10 +806,7 @@ static void encode_lua_object(lua_State *L, ENC_DATA *data, int argno, const cha ...@@ -785,10 +806,7 @@ static void encode_lua_object(lua_State *L, ENC_DATA *data, int argno, const cha
static int sjson_encoder_next_value_is_table(lua_State *L) { static int sjson_encoder_next_value_is_table(lua_State *L) {
int count = 10; int count = 10;
while ((lua_type(L, -1) == LUA_TFUNCTION while ((lua_isfunction(L, -1)
#ifdef LUA_TLIGHTFUNCTION
|| lua_type(L, -1) == LUA_TLIGHTFUNCTION
#endif
) && count-- > 0) { ) && count-- > 0) {
// call it and use the return value // call it and use the return value
lua_call(L, 0, 1); // Expecting replacement value lua_call(L, 0, 1); // Expecting replacement value
...@@ -806,7 +824,7 @@ static void sjson_encoder_make_next_chunk(lua_State *L, ENC_DATA *data) { ...@@ -806,7 +824,7 @@ static void sjson_encoder_make_next_chunk(lua_State *L, ENC_DATA *data) {
luaL_buffinit(L, &b); luaL_buffinit(L, &b);
// Ending condition // Ending condition
while (data->level >= 0 && !b.lvl) { while (data->level >= 0 /* && !b.lvl */) {
ENC_DATA_STATE *state = &data->stack[data->level]; ENC_DATA_STATE *state = &data->stack[data->level];
int finished = 0; int finished = 0;
...@@ -815,7 +833,7 @@ static void sjson_encoder_make_next_chunk(lua_State *L, ENC_DATA *data) { ...@@ -815,7 +833,7 @@ static void sjson_encoder_make_next_chunk(lua_State *L, ENC_DATA *data) {
if (state->offset == 0) { if (state->offset == 0) {
// start of object or whatever // start of object or whatever
luaL_addchar(&b, '['); luaL_addchar(&b, '[');
} }
if (state->offset == state->size << 1) { if (state->offset == state->size << 1) {
luaL_addchar(&b, ']'); luaL_addchar(&b, ']');
finished = 1; finished = 1;
...@@ -849,11 +867,11 @@ static void sjson_encoder_make_next_chunk(lua_State *L, ENC_DATA *data) { ...@@ -849,11 +867,11 @@ static void sjson_encoder_make_next_chunk(lua_State *L, ENC_DATA *data) {
if (lua_next(L, -2)) { if (lua_next(L, -2)) {
// save the key // save the key
if (state->offset & 1) { if (state->offset & 1) {
lua_unref(L, state->lua_key_ref); luaL_unref(L, LUA_REGISTRYINDEX, state->lua_key_ref);
state->lua_key_ref = LUA_NOREF; state->lua_key_ref = LUA_NOREF;
// Duplicate the key // Duplicate the key
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
state->lua_key_ref = lua_ref(L, 1); state->lua_key_ref = luaL_ref(L, LUA_REGISTRYINDEX);
} }
if ((state->offset & 1) == 0) { if ((state->offset & 1) == 0) {
...@@ -895,7 +913,7 @@ static void sjson_encoder_make_next_chunk(lua_State *L, ENC_DATA *data) { ...@@ -895,7 +913,7 @@ static void sjson_encoder_make_next_chunk(lua_State *L, ENC_DATA *data) {
} }
} }
luaL_pushresult(&b); luaL_pushresult(&b);
data->current_str_ref = lua_ref(L, 1); data->current_str_ref = luaL_ref(L, LUA_REGISTRYINDEX);
data->offset = 0; data->offset = 0;
} }
...@@ -923,7 +941,7 @@ static int sjson_encoder_read_int(lua_State *L, ENC_DATA *data, int readsize) { ...@@ -923,7 +941,7 @@ static int sjson_encoder_read_int(lua_State *L, ENC_DATA *data, int readsize) {
readsize -= amnt; readsize -= amnt;
if (data->offset == len) { if (data->offset == len) {
lua_unref(L, data->current_str_ref); luaL_unref(L, LUA_REGISTRYINDEX, data->current_str_ref);
data->current_str_ref = LUA_NOREF; data->current_str_ref = LUA_NOREF;
} }
} }
...@@ -992,71 +1010,34 @@ static int sjson_encoder_destructor(lua_State *L) { ...@@ -992,71 +1010,34 @@ static int sjson_encoder_destructor(lua_State *L) {
return 0; return 0;
} }
#ifdef LOCAL_LUA
static const luaL_Reg sjson_encoder_map[] = { LROT_BEGIN(sjson_encoder_map, NULL, LROT_MASK_GC_INDEX)
{ "read", sjson_encoder_read }, LROT_FUNCENTRY( __gc, sjson_encoder_destructor )
{ "__gc", sjson_encoder_destructor }, LROT_TABENTRY( __index, sjson_encoder_map )
{ NULL, NULL } LROT_FUNCENTRY( read, sjson_encoder_read )
}; LROT_END(sjson_encoder_map, NULL, LROT_MASK_GC_INDEX)
static const luaL_Reg sjson_decoder_map[] = {
{ "write", sjson_decoder_write },
{ "result", sjson_decoder_result }, LROT_BEGIN(sjson_decoder_map, NULL, LROT_MASK_GC_INDEX)
{ "__gc", sjson_decoder_destructor }, LROT_FUNCENTRY( __gc, sjson_decoder_destructor )
{ NULL, NULL } LROT_TABENTRY( __index, sjson_decoder_map )
}; LROT_FUNCENTRY( write, sjson_decoder_write )
LROT_FUNCENTRY( result, sjson_decoder_result )
static const luaL_Reg sjsonlib[] = { LROT_END(sjson_decoder_map, NULL, LROT_MASK_GC_INDEX)
{ "decode", sjson_decode },
{ "decoder", sjson_decoder },
{ "encode", sjson_encode }, LROT_BEGIN(sjson, NULL, 0)
{ "encoder", sjson_encoder }, LROT_FUNCENTRY( encode, sjson_encode )
{NULL, NULL} LROT_FUNCENTRY( decode, sjson_decode )
}; LROT_FUNCENTRY( encoder, sjson_encoder )
#else LROT_FUNCENTRY( decoder, sjson_decoder )
LROT_BEGIN(sjson_encoder)
LROT_FUNCENTRY( read, sjson_encoder_read )
LROT_FUNCENTRY( __gc, sjson_encoder_destructor )
LROT_TABENTRY ( __index, sjson_encoder )
LROT_END(sjson_encoder, NULL, 0)
LROT_BEGIN(sjson_decoder)
LROT_FUNCENTRY( write, sjson_decoder_write )
LROT_FUNCENTRY( result, sjson_decoder_result )
LROT_FUNCENTRY( __gc, sjson_decoder_destructor )
LROT_TABENTRY ( __index, sjson_decoder )
LROT_END(sjson_decoder, NULL, 0)
LROT_BEGIN(sjson)
LROT_FUNCENTRY( encode, sjson_encode )
LROT_FUNCENTRY( decode, sjson_decode )
LROT_FUNCENTRY( encoder, sjson_encoder )
LROT_FUNCENTRY( decoder, sjson_decoder )
LROT_LUDENTRY ( NULL, 0 )
LROT_END(sjson, NULL, 0) LROT_END(sjson, NULL, 0)
#endif
LUALIB_API int luaopen_sjson (lua_State *L) { LUALIB_API int luaopen_sjson (lua_State *L) {
#ifdef LOCAL_LUA luaL_rometatable(L, "sjson.decoder", LROT_TABLEREF(sjson_decoder_map));
luaL_register(L, LUA_SJSONLIBNAME, sjsonlib); luaL_rometatable(L, "sjson.encoder", LROT_TABLEREF(sjson_encoder_map));
lua_getglobal(L, LUA_SJSONLIBNAME);
lua_pushstring(L, "NULL");
lua_pushlightuserdata(L, 0);
lua_settable(L, -3);
lua_pop(L, 1);
luaL_newmetatable(L, "sjson.encoder");
luaL_register(L, NULL, sjson_encoder_map);
lua_setfield(L, -1, "__index");
luaL_newmetatable(L, "sjson.decoder");
luaL_register(L, NULL, sjson_decoder_map);
lua_setfield(L, -1, "__index");
#else
luaL_rometatable(L, "sjson.decoder", (void *)sjson_decoder_map);
luaL_rometatable(L, "sjson.encoder", (void *)sjson_encoder_map);
#endif
return 1; return 1;
} }
#ifndef LOCAL_LUA
NODEMCU_MODULE(SJSON, "sjson", sjson, luaopen_sjson); NODEMCU_MODULE(SJSON, "sjson", sjson, luaopen_sjson);
#endif
...@@ -129,19 +129,19 @@ static int l_crypto_box_seal_open(lua_State *L) ...@@ -129,19 +129,19 @@ static int l_crypto_box_seal_open(lua_State *L)
return 1; return 1;
} }
LROT_BEGIN(random) LROT_BEGIN(random, NULL, 0)
LROT_FUNCENTRY(random, l_randombytes_random) LROT_FUNCENTRY(random, l_randombytes_random)
LROT_FUNCENTRY(uniform, l_randombytes_uniform) LROT_FUNCENTRY(uniform, l_randombytes_uniform)
LROT_FUNCENTRY(buf, l_randombytes_buf) LROT_FUNCENTRY(buf, l_randombytes_buf)
LROT_END(random, NULL, 0) LROT_END(random, NULL, 0)
LROT_BEGIN(crypto_box) LROT_BEGIN(crypto_box, NULL, 0)
LROT_FUNCENTRY(keypair, l_crypto_box_keypair) LROT_FUNCENTRY(keypair, l_crypto_box_keypair)
LROT_FUNCENTRY(seal, l_crypto_box_seal) LROT_FUNCENTRY(seal, l_crypto_box_seal)
LROT_FUNCENTRY(seal_open, l_crypto_box_seal_open) LROT_FUNCENTRY(seal_open, l_crypto_box_seal_open)
LROT_END(crypto_box, NULL, 0) LROT_END(crypto_box, NULL, 0)
LROT_BEGIN(sodium) LROT_BEGIN(sodium, NULL, 0)
LROT_TABENTRY(random, random) LROT_TABENTRY(random, random)
LROT_TABENTRY(crypto_box, crypto_box) LROT_TABENTRY(crypto_box, crypto_box)
LROT_END(sodium, NULL, 0) LROT_END(sodium, NULL, 0)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "driver/spi_common.h" #include "driver/spi_common.h"
LROT_BEGIN(lspi) LROT_BEGIN(lspi, NULL, 0)
LROT_FUNCENTRY( master, lspi_master ) LROT_FUNCENTRY( master, lspi_master )
// LROT_FUNCENTRY( slave, lspi_slave ) // LROT_FUNCENTRY( slave, lspi_slave )
#if defined(CONFIG_IDF_TARGET_ESP32) #if defined(CONFIG_IDF_TARGET_ESP32)
......
...@@ -177,7 +177,7 @@ free_mem: ...@@ -177,7 +177,7 @@ free_mem:
} }
LROT_BEGIN(lspi_device) LROT_BEGIN(lspi_device, NULL, 0)
LROT_FUNCENTRY( transfer, lspi_device_transfer ) LROT_FUNCENTRY( transfer, lspi_device_transfer )
LROT_FUNCENTRY( remove, lspi_device_free ) LROT_FUNCENTRY( remove, lspi_device_free )
LROT_FUNCENTRY( __gc, lspi_device_free ) LROT_FUNCENTRY( __gc, lspi_device_free )
...@@ -320,7 +320,7 @@ static int lspi_host_device( lua_State *L ) ...@@ -320,7 +320,7 @@ static int lspi_host_device( lua_State *L )
} }
LROT_BEGIN(lspi_master) LROT_BEGIN(lspi_master, NULL, 0)
LROT_FUNCENTRY( device, lspi_host_device ) LROT_FUNCENTRY( device, lspi_host_device )
LROT_FUNCENTRY( close, lspi_host_free ) LROT_FUNCENTRY( close, lspi_host_free )
LROT_FUNCENTRY( __gc, lspi_host_free ) LROT_FUNCENTRY( __gc, lspi_host_free )
...@@ -332,7 +332,7 @@ LROT_END(lspi_master, NULL, 0) ...@@ -332,7 +332,7 @@ LROT_END(lspi_master, NULL, 0)
// Generic // Generic
// //
int luaopen_spi_master( lua_State *L ) { int luaopen_spi_master( lua_State *L ) {
luaL_rometatable(L, UD_HOST_STR, (void *)lspi_master_map); luaL_rometatable(L, UD_HOST_STR, LROT_TABLEREF(lspi_master));
luaL_rometatable(L, UD_DEVICE_STR, (void *)lspi_device_map); luaL_rometatable(L, UD_DEVICE_STR, LROT_TABLEREF(lspi_device));
return 0; return 0;
} }
...@@ -392,7 +392,7 @@ static int b_size (lua_State *L) { ...@@ -392,7 +392,7 @@ static int b_size (lua_State *L) {
LROT_BEGIN(thislib) LROT_BEGIN(thislib, NULL, 0)
LROT_FUNCENTRY(pack, b_pack) LROT_FUNCENTRY(pack, b_pack)
LROT_FUNCENTRY(unpack, b_unpack) LROT_FUNCENTRY(unpack, b_unpack)
LROT_FUNCENTRY(size, b_size) LROT_FUNCENTRY(size, b_size)
......
...@@ -118,7 +118,7 @@ static int time_epoch2cal(lua_State *L) ...@@ -118,7 +118,7 @@ static int time_epoch2cal(lua_State *L)
static int time_cal2epoc(lua_State *L) static int time_cal2epoc(lua_State *L)
{ {
struct tm date; struct tm date;
luaL_checkanytable (L, 1); luaL_checktable (L, 1);
lua_getfield (L, 1, "year"); lua_getfield (L, 1, "year");
date.tm_year = luaL_optinteger(L, -1, 1900) - 1900; date.tm_year = luaL_optinteger(L, -1, 1900) - 1900;
...@@ -143,7 +143,7 @@ static int time_cal2epoc(lua_State *L) ...@@ -143,7 +143,7 @@ static int time_cal2epoc(lua_State *L)
return 1; return 1;
} }
LROT_BEGIN(time) LROT_BEGIN(time, NULL, 0)
LROT_FUNCENTRY(set, time_set) LROT_FUNCENTRY(set, time_set)
LROT_FUNCENTRY(get, time_get) LROT_FUNCENTRY(get, time_get)
LROT_FUNCENTRY(getlocal, time_getLocal) LROT_FUNCENTRY(getlocal, time_getLocal)
......
...@@ -81,7 +81,7 @@ static int tmr_register(lua_State* L) ...@@ -81,7 +81,7 @@ static int tmr_register(lua_State* L)
luaL_argcheck(L, mode == TIMER_MODE_SINGLE || mode == TIMER_MODE_SEMI || mode == TIMER_MODE_AUTO, stack, "Invalid mode"); luaL_argcheck(L, mode == TIMER_MODE_SINGLE || mode == TIMER_MODE_SEMI || mode == TIMER_MODE_AUTO, stack, "Invalid mode");
++stack; ++stack;
luaL_argcheck(L, lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION, stack, "Must be function"); luaL_checkfunction(L, stack);
if (tmr->timer) { if (tmr->timer) {
// delete previous timer since mode change could be requested here // delete previous timer since mode change could be requested here
...@@ -235,7 +235,7 @@ static int tmr_create( lua_State *L ) { ...@@ -235,7 +235,7 @@ static int tmr_create( lua_State *L ) {
// Module function map // Module function map
LROT_BEGIN(tmr_dyn) LROT_BEGIN(tmr_dyn, NULL, 0)
LROT_FUNCENTRY( register, tmr_register ) LROT_FUNCENTRY( register, tmr_register )
LROT_FUNCENTRY( alarm, tmr_alarm ) LROT_FUNCENTRY( alarm, tmr_alarm )
LROT_FUNCENTRY( start, tmr_start ) LROT_FUNCENTRY( start, tmr_start )
...@@ -247,7 +247,7 @@ LROT_BEGIN(tmr_dyn) ...@@ -247,7 +247,7 @@ LROT_BEGIN(tmr_dyn)
LROT_TABENTRY ( __index, tmr_dyn ) LROT_TABENTRY ( __index, tmr_dyn )
LROT_END(tmr_dyn, NULL, 0) LROT_END(tmr_dyn, NULL, 0)
LROT_BEGIN(tmr) LROT_BEGIN(tmr, NULL, 0)
LROT_FUNCENTRY( create, tmr_create ) LROT_FUNCENTRY( create, tmr_create )
LROT_NUMENTRY ( ALARM_SINGLE, TIMER_MODE_SINGLE ) LROT_NUMENTRY ( ALARM_SINGLE, TIMER_MODE_SINGLE )
LROT_NUMENTRY ( ALARM_SEMI, TIMER_MODE_SEMI ) LROT_NUMENTRY ( ALARM_SEMI, TIMER_MODE_SEMI )
...@@ -255,7 +255,7 @@ LROT_BEGIN(tmr) ...@@ -255,7 +255,7 @@ LROT_BEGIN(tmr)
LROT_END(tmr, NULL, 0) LROT_END(tmr, NULL, 0)
static int luaopen_tmr( lua_State *L ){ static int luaopen_tmr( lua_State *L ){
luaL_rometatable(L, "tmr.timer", (void *)tmr_dyn_map); luaL_rometatable(L, "tmr.timer", LROT_TABLEREF(tmr_dyn));
alarm_task_id = task_get_id(alarm_timer_task); alarm_task_id = task_get_id(alarm_timer_task);
......
...@@ -558,7 +558,7 @@ static int lu8g2_updateDisplayArea( lua_State *L ) ...@@ -558,7 +558,7 @@ static int lu8g2_updateDisplayArea( lua_State *L )
} }
LROT_BEGIN(lu8g2_display) LROT_BEGIN(lu8g2_display, NULL, 0)
LROT_FUNCENTRY( clearBuffer, lu8g2_clearBuffer ) LROT_FUNCENTRY( clearBuffer, lu8g2_clearBuffer )
LROT_FUNCENTRY( drawBox, lu8g2_drawBox ) LROT_FUNCENTRY( drawBox, lu8g2_drawBox )
LROT_FUNCENTRY( drawCircle, lu8g2_drawCircle ) LROT_FUNCENTRY( drawCircle, lu8g2_drawCircle )
...@@ -802,7 +802,7 @@ U8G2_DISPLAY_TABLE_SPI ...@@ -802,7 +802,7 @@ U8G2_DISPLAY_TABLE_SPI
#define U8G2_DISPLAY_TABLE_ENTRY(function, binding) \ #define U8G2_DISPLAY_TABLE_ENTRY(function, binding) \
LROT_FUNCENTRY( binding, l ## binding ) LROT_FUNCENTRY( binding, l ## binding )
LROT_BEGIN(lu8g2) LROT_BEGIN(lu8g2, NULL, 0)
U8G2_DISPLAY_TABLE_I2C U8G2_DISPLAY_TABLE_I2C
U8G2_DISPLAY_TABLE_SPI U8G2_DISPLAY_TABLE_SPI
// //
...@@ -824,7 +824,7 @@ LROT_BEGIN(lu8g2) ...@@ -824,7 +824,7 @@ LROT_BEGIN(lu8g2)
LROT_END(lu8g2, NULL, 0) LROT_END(lu8g2, NULL, 0)
int luaopen_u8g2( lua_State *L ) { int luaopen_u8g2( lua_State *L ) {
luaL_rometatable(L, "u8g2.display", (void *)lu8g2_display_map); luaL_rometatable(L, "u8g2.display", LROT_TABLEREF(lu8g2_display));
return 0; return 0;
} }
......
...@@ -86,8 +86,7 @@ static int uart_on( lua_State* L ) ...@@ -86,8 +86,7 @@ static int uart_on( lua_State* L )
us->need_len = 0; us->need_len = 0;
} }
// luaL_checkanyfunction(L, stack); if (lua_isfunction(L, stack)) {
if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){
if ( lua_isnumber(L, stack+1) ){ if ( lua_isnumber(L, stack+1) ){
run = lua_tointeger(L, stack+1); run = lua_tointeger(L, stack+1);
} }
...@@ -280,7 +279,7 @@ static int luart_tx_flush (lua_State *L) ...@@ -280,7 +279,7 @@ static int luart_tx_flush (lua_State *L)
} }
// Module function map // Module function map
LROT_BEGIN(uart) LROT_BEGIN(uart, NULL, 0)
LROT_FUNCENTRY( setup, uart_setup ) LROT_FUNCENTRY( setup, uart_setup )
LROT_FUNCENTRY( write, uart_write ) LROT_FUNCENTRY( write, uart_write )
LROT_FUNCENTRY( start, uart_start ) LROT_FUNCENTRY( start, uart_start )
......
...@@ -678,7 +678,9 @@ UCG_DISPLAY_TABLE ...@@ -678,7 +678,9 @@ UCG_DISPLAY_TABLE
// Module function map // Module function map
LROT_BEGIN(lucg_display) LROT_BEGIN(lucg_display, NULL, 0)
LROT_FUNCENTRY( __gc, lucg_close_display )
LROT_TABENTRY( __index, lucg_display )
LROT_FUNCENTRY( begin, lucg_begin ) LROT_FUNCENTRY( begin, lucg_begin )
LROT_FUNCENTRY( clearScreen, lucg_clearScreen ) LROT_FUNCENTRY( clearScreen, lucg_clearScreen )
LROT_FUNCENTRY( draw90Line, lucg_draw90Line ) LROT_FUNCENTRY( draw90Line, lucg_draw90Line )
...@@ -722,11 +724,10 @@ LROT_BEGIN(lucg_display) ...@@ -722,11 +724,10 @@ LROT_BEGIN(lucg_display)
LROT_FUNCENTRY( undoClipRange, lucg_setMaxClipRange ) LROT_FUNCENTRY( undoClipRange, lucg_setMaxClipRange )
LROT_FUNCENTRY( undoRotate, lucg_undoRotate ) LROT_FUNCENTRY( undoRotate, lucg_undoRotate )
LROT_FUNCENTRY( undoScale, lucg_undoScale ) LROT_FUNCENTRY( undoScale, lucg_undoScale )
LROT_FUNCENTRY( __gc, lucg_close_display )
LROT_TABENTRY( __index, lucg_display )
LROT_END(lucg_display, NULL, 0) LROT_END(lucg_display, NULL, 0)
LROT_BEGIN(lucg) LROT_BEGIN(lucg, NULL, 0)
LROT_TABENTRY( __metatable, lucg )
#undef UCG_DISPLAY_TABLE_ENTRY #undef UCG_DISPLAY_TABLE_ENTRY
#define UCG_DISPLAY_TABLE_ENTRY(binding, device, extension) LROT_FUNCENTRY( binding, l ## binding ) #define UCG_DISPLAY_TABLE_ENTRY(binding, device, extension) LROT_FUNCENTRY( binding, l ## binding )
UCG_DISPLAY_TABLE UCG_DISPLAY_TABLE
...@@ -746,13 +747,11 @@ LROT_BEGIN(lucg) ...@@ -746,13 +747,11 @@ LROT_BEGIN(lucg)
LROT_NUMENTRY( DRAW_LOWER_RIGHT, UCG_DRAW_LOWER_RIGHT ) LROT_NUMENTRY( DRAW_LOWER_RIGHT, UCG_DRAW_LOWER_RIGHT )
LROT_NUMENTRY( DRAW_LOWER_LEFT, UCG_DRAW_LOWER_LEFT ) LROT_NUMENTRY( DRAW_LOWER_LEFT, UCG_DRAW_LOWER_LEFT )
LROT_NUMENTRY( DRAW_ALL, UCG_DRAW_ALL ) LROT_NUMENTRY( DRAW_ALL, UCG_DRAW_ALL )
LROT_TABENTRY( __metatable, lucg )
LROT_END(lucg, NULL, 0) LROT_END(lucg, NULL, 0)
int luaopen_ucg( lua_State *L ) int luaopen_ucg( lua_State *L )
{ {
luaL_rometatable(L, "ucg.display", (void *)lucg_display_map); // create metatable luaL_rometatable(L, "ucg.display", LROT_TABLEREF(lucg_display)); // create metatable
return 0; return 0;
} }
......
...@@ -108,10 +108,10 @@ static int wifi_init (lua_State *L) ...@@ -108,10 +108,10 @@ static int wifi_init (lua_State *L)
} }
LROT_EXTERN(wifi_sta); extern LROT_TABLE(wifi_sta);
LROT_EXTERN(wifi_ap); extern LROT_TABLE(wifi_ap);
LROT_BEGIN(wifi) LROT_BEGIN(wifi, NULL, 0)
LROT_FUNCENTRY( getchannel, wifi_getchannel ) LROT_FUNCENTRY( getchannel, wifi_getchannel )
LROT_FUNCENTRY( getmode, wifi_getmode ) LROT_FUNCENTRY( getmode, wifi_getmode )
LROT_FUNCENTRY( mode, wifi_mode ) LROT_FUNCENTRY( mode, wifi_mode )
......
...@@ -136,7 +136,7 @@ void wifi_ap_init (void) ...@@ -136,7 +136,7 @@ void wifi_ap_init (void)
static int wifi_ap_setip(lua_State *L) static int wifi_ap_setip(lua_State *L)
{ {
luaL_checkanytable (L, 1); luaL_checktable (L, 1);
size_t len = 0; size_t len = 0;
const char *str = NULL; const char *str = NULL;
...@@ -202,7 +202,7 @@ static int wifi_ap_sethostname(lua_State *L) ...@@ -202,7 +202,7 @@ static int wifi_ap_sethostname(lua_State *L)
static int wifi_ap_config (lua_State *L) static int wifi_ap_config (lua_State *L)
{ {
luaL_checkanytable (L, 1); luaL_checktable (L, 1);
bool save = luaL_optbool (L, 2, DEFAULT_SAVE); bool save = luaL_optbool (L, 2, DEFAULT_SAVE);
wifi_config_t cfg; wifi_config_t cfg;
...@@ -257,7 +257,7 @@ static int wifi_ap_on (lua_State *L) ...@@ -257,7 +257,7 @@ static int wifi_ap_on (lua_State *L)
} }
LROT_PUBLIC_BEGIN(wifi_ap) LROT_BEGIN(wifi_ap, NULL, 0)
LROT_FUNCENTRY( setip, wifi_ap_setip ) LROT_FUNCENTRY( setip, wifi_ap_setip )
LROT_FUNCENTRY( sethostname, wifi_ap_sethostname ) LROT_FUNCENTRY( sethostname, wifi_ap_sethostname )
LROT_FUNCENTRY( config, wifi_ap_config ) LROT_FUNCENTRY( config, wifi_ap_config )
......
...@@ -63,7 +63,7 @@ int wifi_on (lua_State *L, const event_desc_t *table, unsigned n, int *event_cb) ...@@ -63,7 +63,7 @@ int wifi_on (lua_State *L, const event_desc_t *table, unsigned n, int *event_cb)
{ {
const char *event_name = luaL_checkstring (L, 1); const char *event_name = luaL_checkstring (L, 1);
if (!lua_isnoneornil (L, 2)) if (!lua_isnoneornil (L, 2))
luaL_checkanyfunction (L, 2); luaL_checkfunction (L, 2);
lua_settop (L, 2); lua_settop (L, 2);
int idx = wifi_event_idx_by_name (table, n, event_name); int idx = wifi_event_idx_by_name (table, n, event_name);
......
...@@ -164,7 +164,7 @@ void wifi_sta_init (void) ...@@ -164,7 +164,7 @@ void wifi_sta_init (void)
// --- Lua API functions ---------------------------------------------------- // --- Lua API functions ----------------------------------------------------
static int wifi_sta_setip(lua_State *L) static int wifi_sta_setip(lua_State *L)
{ {
luaL_checkanytable (L, 1); luaL_checktable (L, 1);
size_t len = 0; size_t len = 0;
const char *str = NULL; const char *str = NULL;
...@@ -224,7 +224,7 @@ static int wifi_sta_sethostname(lua_State *L) ...@@ -224,7 +224,7 @@ static int wifi_sta_sethostname(lua_State *L)
static int wifi_sta_config (lua_State *L) static int wifi_sta_config (lua_State *L)
{ {
luaL_checkanytable (L, 1); luaL_checktable (L, 1);
bool save = luaL_optbool (L, 2, DEFAULT_SAVE); bool save = luaL_optbool (L, 2, DEFAULT_SAVE);
lua_settop (L, 1); lua_settop (L, 1);
...@@ -405,9 +405,9 @@ static int wifi_sta_scan (lua_State *L) ...@@ -405,9 +405,9 @@ static int wifi_sta_scan (lua_State *L)
if (scan_cb_ref != LUA_NOREF) if (scan_cb_ref != LUA_NOREF)
return luaL_error (L, "scan already in progress"); return luaL_error (L, "scan already in progress");
luaL_checkanytable (L, 1); luaL_checktable (L, 1);
luaL_checkanyfunction (L, 2); luaL_checkfunction (L, 2);
lua_settop (L, 2); lua_settop (L, 2);
scan_cb_ref = luaL_ref (L, LUA_REGISTRYINDEX); scan_cb_ref = luaL_ref (L, LUA_REGISTRYINDEX);
...@@ -438,7 +438,7 @@ static int wifi_sta_scan (lua_State *L) ...@@ -438,7 +438,7 @@ static int wifi_sta_scan (lua_State *L)
} }
LROT_PUBLIC_BEGIN(wifi_sta) LROT_BEGIN(wifi_sta, NULL, 0)
LROT_FUNCENTRY( setip, wifi_sta_setip ) LROT_FUNCENTRY( setip, wifi_sta_setip )
LROT_FUNCENTRY( sethostname, wifi_sta_sethostname ) LROT_FUNCENTRY( sethostname, wifi_sta_sethostname )
LROT_FUNCENTRY( config, wifi_sta_config ) LROT_FUNCENTRY( config, wifi_sta_config )
......
...@@ -497,7 +497,10 @@ static int ws2812_buffer_tostring(lua_State* L) { ...@@ -497,7 +497,10 @@ static int ws2812_buffer_tostring(lua_State* L) {
return 1; return 1;
} }
LROT_BEGIN(ws2812_buffer) LROT_BEGIN(ws2812_buffer, NULL, 0)
LROT_FUNCENTRY( __concat, ws2812_buffer_concat )
LROT_TABENTRY ( __index, ws2812_buffer )
LROT_FUNCENTRY( __tostring, ws2812_buffer_tostring )
LROT_FUNCENTRY( dump, ws2812_buffer_dump ) LROT_FUNCENTRY( dump, ws2812_buffer_dump )
LROT_FUNCENTRY( fade, ws2812_buffer_fade ) LROT_FUNCENTRY( fade, ws2812_buffer_fade )
LROT_FUNCENTRY( fill, ws2812_buffer_fill ) LROT_FUNCENTRY( fill, ws2812_buffer_fill )
...@@ -509,12 +512,9 @@ LROT_BEGIN(ws2812_buffer) ...@@ -509,12 +512,9 @@ LROT_BEGIN(ws2812_buffer)
LROT_FUNCENTRY( shift, ws2812_buffer_shift ) LROT_FUNCENTRY( shift, ws2812_buffer_shift )
LROT_FUNCENTRY( size, ws2812_buffer_size ) LROT_FUNCENTRY( size, ws2812_buffer_size )
LROT_FUNCENTRY( sub, ws2812_buffer_sub ) LROT_FUNCENTRY( sub, ws2812_buffer_sub )
LROT_FUNCENTRY( __concat, ws2812_buffer_concat )
LROT_TABENTRY ( __index, ws2812_buffer )
LROT_FUNCENTRY( __tostring, ws2812_buffer_tostring )
LROT_END(ws2812_buffer, NULL, 0) LROT_END(ws2812_buffer, NULL, 0)
LROT_BEGIN(ws2812) LROT_BEGIN(ws2812, NULL, 0)
LROT_FUNCENTRY( newBuffer, ws2812_new_buffer ) LROT_FUNCENTRY( newBuffer, ws2812_new_buffer )
LROT_FUNCENTRY( write, ws2812_write ) LROT_FUNCENTRY( write, ws2812_write )
LROT_NUMENTRY ( FADE_IN, FADE_IN ) LROT_NUMENTRY ( FADE_IN, FADE_IN )
...@@ -525,7 +525,7 @@ LROT_END(ws2812, NULL, 0) ...@@ -525,7 +525,7 @@ LROT_END(ws2812, NULL, 0)
int luaopen_ws2812(lua_State *L) { int luaopen_ws2812(lua_State *L) {
// TODO: Make sure that the GPIO system is initialized // TODO: Make sure that the GPIO system is initialized
luaL_rometatable(L, "ws2812.buffer", (void *)ws2812_buffer_map); // create metatable for ws2812.buffer luaL_rometatable(L, "ws2812.buffer", LROT_TABLEREF(ws2812_buffer)); // create metatable for ws2812.buffer
return 0; return 0;
} }
......
...@@ -266,14 +266,6 @@ typedef struct { ...@@ -266,14 +266,6 @@ typedef struct {
*/ */
bool platform_partition_info (uint8_t idx, platform_partition_t *info); bool platform_partition_info (uint8_t idx, platform_partition_t *info);
/**
* Appends a partition entry to the partition table, if possible.
* Intended for auto-creation of a SPIFFS partition.
* @param info The partition definition to append.
* @returns True if the partition could be added, false if not.
*/
bool platform_partition_add (const platform_partition_t *info);
// ***************************************************************************** // *****************************************************************************
// Helper macros // Helper macros
...@@ -293,4 +285,6 @@ bool platform_partition_add (const platform_partition_t *info); ...@@ -293,4 +285,6 @@ bool platform_partition_add (const platform_partition_t *info);
void platform_print_deprecation_note( const char *msg, const char *time_frame);
#endif #endif
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