Alpha working wersion for third party evaluation
This commit is contained in:
parent
e00d927a02
commit
4ae52c232c
73
.gdbinit
73
.gdbinit
|
@ -5,6 +5,15 @@
|
|||
# single hardware breakpoint which can be used as an hb or a wa. You have to
|
||||
# remember to delete the previous one, so the br macro does this for you.
|
||||
#
|
||||
file app/.output/eagle/debug/image/eagle.app.v6.out
|
||||
#set remotedebug 1
|
||||
set remotelogfile gdb_rsp_logfile.txt
|
||||
set serial baud 115200
|
||||
set remote hardware-breakpoint-limit 1
|
||||
set remote hardware-watchpoint-limit 1
|
||||
#set debug xtensa 4
|
||||
target remote /dev/ttyUSB0
|
||||
|
||||
set confirm off
|
||||
set print null-stop
|
||||
define br
|
||||
|
@ -13,10 +22,30 @@ define br
|
|||
end
|
||||
set pagination off
|
||||
|
||||
define prTS
|
||||
set $o = &(((TString *)($arg0))->tsv)
|
||||
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
|
||||
printf "String: hash = 0x%08x, len = %u : %s\n", $o->hash, $o->len, (char *)(&$o[1])
|
||||
end
|
||||
define prTnodes
|
||||
set $o = (Table *)($arg0)
|
||||
set $n = 1<<($o->lsizenode)
|
||||
set $i = 0
|
||||
while $i < $n
|
||||
set $nd = ($o->node) + $i
|
||||
if $nd->i_key.nk.tt && $nd->i_val.tt
|
||||
if $nd->i_key.nk.tt == 6
|
||||
printf "%4u: %s %2i\n", $i, $nd->i_key.nk.tt , $nd->i_val.tt else
|
||||
printf "%4u: %2i %2i\n", $i, $nd->i_key.nk.tt , $nd->i_val.tt
|
||||
end
|
||||
end
|
||||
set $i = $i +1
|
||||
end
|
||||
end
|
||||
define prTV
|
||||
if $arg0
|
||||
set $type = $arg0.tt
|
||||
set $val = $arg0.value
|
||||
set $type = ($arg0).tt
|
||||
set $val = ($arg0).value
|
||||
|
||||
if $type == 0
|
||||
# NIL
|
||||
|
@ -24,34 +53,33 @@ define prTV
|
|||
end
|
||||
if $type == 1
|
||||
# Boolean
|
||||
printf "Boolean: %u\n", $val->n
|
||||
printf "Boolean: %u\n", $val.n
|
||||
end
|
||||
if $type == 2
|
||||
# ROTable
|
||||
printf "ROTable: %p\n", $val->p
|
||||
printf "ROTable: %p\n", $val.p
|
||||
end
|
||||
if $type == 3
|
||||
# Light Function
|
||||
printf "Light Func: %p\n",p $arg $val->p
|
||||
printf "Light Func: %p\n", $val.p
|
||||
end
|
||||
if $type == 4
|
||||
# Light User Data
|
||||
printf "Light Udata: %p\n", $val->pend
|
||||
printf "Light Udata: %p\n", $val.p
|
||||
end
|
||||
if $type == 5
|
||||
# Number
|
||||
printf "Boolean: %u\n", $val->n
|
||||
printf "Number: %u\n", $val.n
|
||||
end
|
||||
if $type == 6
|
||||
# TString
|
||||
set $o = &($val.gc->ts.tsv)
|
||||
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
|
||||
printf "String: hash = 0x%08x, len = %u : %s\n", $o->hash, $o->len, (char *)($ts+1)
|
||||
prTS $arg0
|
||||
end
|
||||
if $type == 7
|
||||
# Table
|
||||
__printComHdr $arg0
|
||||
set $ts = (TString *)$val->p
|
||||
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->nodes
|
||||
printf "Arry: %4i %p\n", $o->sizearray, $o->array
|
||||
end
|
||||
if $type == 8
|
||||
# Function
|
||||
|
@ -106,6 +134,25 @@ define dumpRAMstrt
|
|||
dumpstrt &(L->l_G->strt)
|
||||
end
|
||||
|
||||
define dumpROstrt
|
||||
dumpstrt &(L->l_G->ROstrt)
|
||||
end
|
||||
|
||||
define graylist
|
||||
set $n = $arg0
|
||||
while $n
|
||||
printf "%p %2u %02X\n",$n, $n->gch.tt, $n->gch.marked
|
||||
set $n=$n->gch.next
|
||||
end
|
||||
end
|
||||
|
||||
define prPC
|
||||
printf "Excuting instruction %i: %08x\n", (pc - cl->p->code)+1-1, i
|
||||
end
|
||||
|
||||
define prT
|
||||
print *(Table*)($arg0)
|
||||
end
|
||||
set history save on
|
||||
set history size 1000
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -26,7 +26,7 @@ ifdef DEBUG
|
|||
CCFLAGS += -ggdb -O0
|
||||
LDFLAGS += -ggdb
|
||||
else
|
||||
CCFLAGS += -Os
|
||||
CCFLAGS += -O2
|
||||
endif
|
||||
|
||||
#############################################################
|
||||
|
|
46
app/Makefile
46
app/Makefile
|
@ -20,93 +20,64 @@ FLAVOR = debug
|
|||
ifndef PDIR # {
|
||||
GEN_IMAGES= eagle.app.v6.out
|
||||
GEN_BINS= eagle.app.v6.bin
|
||||
SPECIAL_MKTARGETS=$(APP_MKTARGETS)
|
||||
OPT_MKTARGETS := coap crypto dht http mqtt pcm sjson sqlite3 tsl2561 u8glib ucglib websocket
|
||||
SEL_MKTARGETS := $(shell $(CC) -E -dM include/user_modules.h | sed -n '/^\#define LUA_USE_MODULES_/{s/.\{24\}\(.*\)/\L\1/; p}')
|
||||
OPT_SEL_MKTARGETS := $(foreach tgt,$(OPT_MKTARGETS),$(findstring $(tgt), $(SEL_MKTARGETS)))
|
||||
OPT_SEL_COMPONENTS := $(foreach tgt,$(OPT_SEL_MKTARGETS),$(tgt)/lib$(tgt).a)
|
||||
SPECIAL_MKTARGETS :=$(APP_MKTARGETS)
|
||||
|
||||
SUBDIRS= \
|
||||
user \
|
||||
driver \
|
||||
pcm \
|
||||
mbedtls \
|
||||
platform \
|
||||
libc \
|
||||
lua \
|
||||
lwip \
|
||||
coap \
|
||||
mqtt \
|
||||
task \
|
||||
u8glib \
|
||||
ucglib \
|
||||
smart \
|
||||
modules \
|
||||
spiffs \
|
||||
crypto \
|
||||
dhtlib \
|
||||
tsl2561 \
|
||||
net \
|
||||
http \
|
||||
fatfs \
|
||||
esp-gdbstub \
|
||||
websocket \
|
||||
swTimer \
|
||||
misc \
|
||||
pm \
|
||||
sjson \
|
||||
sqlite3 \
|
||||
|
||||
$(OPT_SEL_MKTARGETS)
|
||||
|
||||
endif # } PDIR
|
||||
|
||||
APPDIR = .
|
||||
LDDIR = ../ld
|
||||
|
||||
CCFLAGS += -Os
|
||||
|
||||
TARGET_LDFLAGS = \
|
||||
-nostdlib \
|
||||
-Wl,-EL \
|
||||
--longcalls \
|
||||
--text-section-literals
|
||||
|
||||
ifeq ($(FLAVOR),debug)
|
||||
TARGET_LDFLAGS += -g -Os
|
||||
endif
|
||||
|
||||
ifeq ($(FLAVOR),release)
|
||||
TARGET_LDFLAGS += -Os
|
||||
endif
|
||||
|
||||
LD_FILE = $(LDDIR)/nodemcu.ld
|
||||
|
||||
COMPONENTS_eagle.app.v6 = \
|
||||
user/libuser.a \
|
||||
driver/libdriver.a \
|
||||
pcm/pcm.a \
|
||||
platform/libplatform.a \
|
||||
task/libtask.a \
|
||||
libc/liblibc.a \
|
||||
lua/liblua.a \
|
||||
lwip/liblwip.a \
|
||||
coap/coap.a \
|
||||
mqtt/mqtt.a \
|
||||
u8glib/u8glib.a \
|
||||
ucglib/ucglib.a \
|
||||
smart/smart.a \
|
||||
spiffs/spiffs.a \
|
||||
fatfs/libfatfs.a \
|
||||
crypto/libcrypto.a \
|
||||
dhtlib/libdhtlib.a \
|
||||
tsl2561/tsl2561lib.a \
|
||||
http/libhttp.a \
|
||||
pm/libpm.a \
|
||||
websocket/libwebsocket.a \
|
||||
esp-gdbstub/libgdbstub.a \
|
||||
net/libnodemcu_net.a \
|
||||
mbedtls/libmbedtls.a \
|
||||
modules/libmodules.a \
|
||||
swTimer/libswtimer.a \
|
||||
misc/libmisc.a \
|
||||
sjson/libsjson.a \
|
||||
sqlite3/libsqlite3.a \
|
||||
|
||||
$(OPT_SEL_COMPONENTS)
|
||||
|
||||
# Inspect the modules library and work out which modules need to be linked.
|
||||
# For each enabled module, a symbol name of the form XYZ_module_selected is
|
||||
|
@ -194,6 +165,5 @@ INCLUDES += -I ./
|
|||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
||||
|
||||
|
||||
.PHONY: FORCE
|
||||
FORCE:
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = coap.a
|
||||
GEN_LIBS = libcoap.a
|
||||
endif
|
||||
|
||||
#############################################################
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libdhtlib.a
|
||||
GEN_LIBS = libdht.a
|
||||
endif
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#if !defined(__MODULE_H_) && !defined(LUA_CROSS_COMPILER)
|
||||
#ifndef __MODULE_H__
|
||||
#define __MODULE_H__
|
||||
|
||||
#include "user_modules.h"
|
||||
|
@ -38,8 +38,11 @@
|
|||
#define MODULE_PASTE_(x,y) x##y
|
||||
#define MODULE_EXPAND_PASTE_(x,y) MODULE_PASTE_(x,y)
|
||||
|
||||
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(s)))
|
||||
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".rodata1." #s)))
|
||||
#else
|
||||
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".lua_" #s)))
|
||||
#endif
|
||||
/* For the ROM table, we name the variable according to ( | denotes concat):
|
||||
* cfgname | _module_selected | LUA_USE_MODULES_##cfgname
|
||||
* where the LUA_USE_MODULES_XYZ macro is first expanded to yield either
|
||||
|
@ -51,20 +54,20 @@
|
|||
* to be linked in.
|
||||
*/
|
||||
#define NODEMCU_MODULE(cfgname, luaname, map, initfunc) \
|
||||
const LOCK_IN_SECTION(".lua_libs") \
|
||||
const LOCK_IN_SECTION(libs) \
|
||||
luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
|
||||
const LOCK_IN_SECTION(".lua_rotable") \
|
||||
const LOCK_IN_SECTION(rotable) \
|
||||
luaR_table MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
|
||||
= { luaname, map }
|
||||
|
||||
|
||||
/* System module registration support, not using LUA_USE_MODULES_XYZ. */
|
||||
#define BUILTIN_LIB_INIT(name, luaname, initfunc) \
|
||||
const LOCK_IN_SECTION(".lua_libs") \
|
||||
const LOCK_IN_SECTION(libs) \
|
||||
luaL_Reg MODULE_PASTE_(lua_lib_,name) = { luaname, initfunc }
|
||||
|
||||
#define BUILTIN_LIB(name, luaname, map) \
|
||||
const LOCK_IN_SECTION(".lua_rotable") \
|
||||
const LOCK_IN_SECTION(rotable) \
|
||||
luaR_table MODULE_PASTE_(lua_rotable_,name) = { luaname, map }
|
||||
|
||||
#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
// This adds the asserts in LUA. It also adds some useful extras to the
|
||||
// node module. This is all silent in normal operation and so can be enabled
|
||||
// without any harm (except for the code size increase and slight slowdown)
|
||||
// Either here for a global change or in the DEFINES variable in the relevant
|
||||
// Makefile for ony one subdirectory. If you want to use the remote GDB to
|
||||
// You can either set these defines here to operate globally or you edit the
|
||||
// relevant Makefile setting them in the DEFINES variable is you only want to
|
||||
// enable extra debug for specific subdirs. If you want to use the remote GDB to
|
||||
// handle breaks and failed assetions then enable DEVELOPMENT_USE GDB
|
||||
//#define DEVELOPMENT_TOOLS
|
||||
//#define DEVELOPMENT_USE_GDB
|
||||
|
@ -54,6 +55,8 @@ extern void luaL_dbgbreak(void);
|
|||
#define NODE_ERR
|
||||
#endif /* NODE_ERROR */
|
||||
|
||||
#define LUA_USE_BUILTIN_DEBUG_MINIMAL // for debug.getregistry() and debug.traceback()
|
||||
|
||||
#define GPIO_INTERRUPT_ENABLE
|
||||
#define GPIO_INTERRUPT_HOOK_ENABLE
|
||||
// #define GPIO_SAFE_NO_INTR_ENABLE
|
||||
|
@ -86,18 +89,22 @@ extern void luaL_dbgbreak(void);
|
|||
// maximum number of open files for SPIFFS
|
||||
#define SPIFFS_MAX_OPEN_FILES 4
|
||||
|
||||
// Uncomment this next line for fastest startup
|
||||
// It reduces the format time dramatically
|
||||
// #define SPIFFS_MAX_FILESYSTEM_SIZE 32768
|
||||
// Uncomment this next line for fastest startup and set the FS only to what
|
||||
// your application needs. This reduces the format time dramatically
|
||||
//#define SPIFFS_MAX_FILESYSTEM_SIZE 0x10000
|
||||
//
|
||||
// You can force the spiffs file system to be at a fixed location
|
||||
// #define SPIFFS_FIXED_LOCATION 0x100000
|
||||
//#define SPIFFS_FIXED_LOCATION 0x100000
|
||||
//
|
||||
// You can force the SPIFFS file system to end on the next !M boundary
|
||||
// (minus the 16k parameter space). THis is useful for certain OTA scenarios
|
||||
// #define SPIFFS_SIZE_1M_BOUNDARY
|
||||
|
||||
// #define LUA_NUMBER_INTEGRAL
|
||||
//#define LUA_NUMBER_INTEGRAL
|
||||
|
||||
// If you want to enable Lua Flash Store (LFS) then set the following define to
|
||||
// the size of the store. This can be any multiple of 4kB up to a maximum 256Kb.
|
||||
//#define LUA_FLASH_STORE 0x10000
|
||||
|
||||
#define READLINE_INTERVAL 80
|
||||
#define LUA_TASK_PRIO USER_TASK_PRIO_0
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
#ifndef __USER_MODULES_H__
|
||||
#define __USER_MODULES_H__
|
||||
|
||||
#define LUA_USE_BUILTIN_STRING // for string.xxx()
|
||||
#define LUA_USE_BUILTIN_TABLE // for table.xxx()
|
||||
#define LUA_USE_BUILTIN_COROUTINE // for coroutine.xxx()
|
||||
#define LUA_USE_BUILTIN_MATH // for math.xxx(), partially work
|
||||
// #define LUA_USE_BUILTIN_IO // for io.xxx(), partially work
|
||||
|
||||
// #define LUA_USE_BUILTIN_OS // for os.xxx(), not work
|
||||
// #define LUA_USE_BUILTIN_DEBUG
|
||||
#define LUA_USE_BUILTIN_DEBUG_MINIMAL // for debug.getregistry() and debug.traceback()
|
||||
|
||||
#ifndef LUA_CROSS_COMPILER
|
||||
|
||||
|
@ -65,13 +57,13 @@
|
|||
//#define LUA_USE_MODULES_SJSON
|
||||
//#define LUA_USE_MODULES_SNTP
|
||||
//#define LUA_USE_MODULES_SOMFY
|
||||
#define LUA_USE_MODULES_SPI
|
||||
//#define LUA_USE_MODULES_SPI
|
||||
//#define LUA_USE_MODULES_SQLITE3
|
||||
//#define LUA_USE_MODULES_STRUCT
|
||||
//#define LUA_USE_MODULES_SWITEC
|
||||
// #define LUA_USE_MODULES_TCS34725
|
||||
//#define LUA_USE_MODULES_TCS34725
|
||||
//#define LUA_USE_MODULES_TM1829
|
||||
#define LUA_USE_MODULES_TLS
|
||||
//#define LUA_USE_MODULES_TLS
|
||||
#define LUA_USE_MODULES_TMR
|
||||
//#define LUA_USE_MODULES_TSL2561
|
||||
//#define LUA_USE_MODULES_U8G
|
||||
|
|
|
@ -25,7 +25,8 @@ STD_CFLAGS=-std=gnu11 -Wimplicit
|
|||
# makefile at its root level - these are then overridden
|
||||
# for a subtree within the makefile rooted therein
|
||||
#
|
||||
#DEFINES +=
|
||||
#DEFINES += -DDEVELOPMENT_TOOLS -DDEVELOPMENT_USE_GDB -DNODE_DEBUG -DBREAK_ON_STARTUP_PIN=1
|
||||
#EXTRA_CCFLAGS += -ggdb -O0
|
||||
|
||||
#############################################################
|
||||
# Recursion Magic - Don't touch this!!
|
||||
|
|
|
@ -414,7 +414,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
|
|||
case LUA_TROTABLE:
|
||||
return rvalue(o);
|
||||
case LUA_TLIGHTFUNCTION:
|
||||
return pvalue(o);
|
||||
return fvalue(o);
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -459,15 +459,6 @@ LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
|||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushrolstring (lua_State *L, const char *s, size_t len) {
|
||||
lua_lock(L);
|
||||
luaC_checkGC(L);
|
||||
setsvalue2s(L, L->top, luaS_newrolstr(L, s, len));
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushstring (lua_State *L, const char *s) {
|
||||
if (s == NULL)
|
||||
lua_pushnil(L);
|
||||
|
|
|
@ -46,6 +46,13 @@
|
|||
|
||||
//#define DEBUG_ALLOCATOR
|
||||
#ifdef DEBUG_ALLOCATOR
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
static void break_hook(void)
|
||||
#define ASSERT(s) if (!(s)) {break_hook();}
|
||||
#else
|
||||
#define ASSERT(s) if (!(s)) {asm ("break 0,0" ::);}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** {======================================================================
|
||||
** Diagnosticd version for realloc. This is enabled only if the
|
||||
|
@ -56,31 +63,72 @@
|
|||
** =======================================================================
|
||||
*/
|
||||
#define this_realloc debug_realloc
|
||||
#define ASSERT(s) if (!(s)) {asm ("break 0,0" ::);}
|
||||
#define MARK 0x55 /* 01010101 (a nice pattern) */
|
||||
#define MARK4 0x55555555
|
||||
#define MARKSIZE 4 /* size of marks after each block */
|
||||
#define fillmem(mem,size) memset(mem, -MARK, size)
|
||||
#define MARKSIZE 2*sizeof(size_t) /* size of marks after each block */
|
||||
#define fillmem(mem,size) memset(mem, ~MARK, size)
|
||||
|
||||
typedef struct Memcontrol { /* memory-allocator control variables */
|
||||
uint32_t numblocks;
|
||||
uint32_t total;
|
||||
uint32_t maxmem;
|
||||
uint32_t memlimit;
|
||||
} Memcontrol;
|
||||
static Memcontrol mc = {0,0,0,32768};
|
||||
|
||||
typedef union MemHeader {
|
||||
typedef union MemHeader MemHeader;
|
||||
union MemHeader {
|
||||
L_Umaxalign a; /* ensures maximum alignment for Header */
|
||||
struct {
|
||||
size_t size;
|
||||
int mark;
|
||||
} d;
|
||||
} MemHeader;
|
||||
MemHeader *next;
|
||||
size_t mark[2];
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct Memcontrol { /* memory-allocator control variables */
|
||||
MemHeader *start;
|
||||
lu_int32 numblocks;
|
||||
lu_int32 total;
|
||||
lu_int32 maxmem;
|
||||
lu_int32 memlimit;
|
||||
} Memcontrol;
|
||||
static Memcontrol mc = {NULL,0,0,0,32768*64};
|
||||
static size_t marker[2] = {0,0};
|
||||
|
||||
static void scanBlocks (void) {
|
||||
MemHeader *p = mc.start;
|
||||
int i;
|
||||
char s,e;
|
||||
for (i=0; p ;i++) {
|
||||
s = memcmp(p->mark, marker, MARKSIZE) ? '<' : ' ';
|
||||
e = memcmp(cast(char *, p+1) + p->size, marker, MARKSIZE) ? '>' : ' ';
|
||||
c_printf("%4u %p %8lu %c %c\n", i, p, p->size, s, e);
|
||||
ASSERT(p->next);
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
static int checkBlocks (void) {
|
||||
MemHeader *p = mc.start;
|
||||
while(p) {
|
||||
if (memcmp(p->mark, marker, MARKSIZE) ||
|
||||
memcmp(cast(char *, p+1) + p->size, marker, MARKSIZE)) {
|
||||
scanBlocks();
|
||||
return 0;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void freeblock (MemHeader *block) {
|
||||
if (block) {
|
||||
size_t size = block->d.size;
|
||||
MemHeader *p = mc.start;
|
||||
MemHeader *next = block->next;
|
||||
size_t size = block->size;
|
||||
ASSERT(checkBlocks());
|
||||
if (p == block) {
|
||||
mc.start = next;
|
||||
} else {
|
||||
while (p->next != block) {
|
||||
ASSERT(p);
|
||||
p = p->next;
|
||||
}
|
||||
p->next = next;
|
||||
}
|
||||
fillmem(block, sizeof(MemHeader) + size + MARKSIZE); /* erase block */
|
||||
c_free(block); /* actually free block */
|
||||
mc.numblocks--; /* update counts */
|
||||
|
@ -88,18 +136,17 @@ static void freeblock (MemHeader *block) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void *debug_realloc (void *b, size_t oldsize, size_t size) {
|
||||
MemHeader *block = cast(MemHeader *, b);
|
||||
int i;
|
||||
ASSERT(checkBlocks());
|
||||
if (!marker[0]) memset(marker, MARK, MARKSIZE);
|
||||
if (block == NULL) {
|
||||
oldsize = 0;
|
||||
} else {
|
||||
block--; /* go to real header */
|
||||
ASSERT(block->d.mark == MARK4);
|
||||
ASSERT(oldsize == block->d.size);
|
||||
for (i = 0; i < MARKSIZE; i++) /* check marks after block */
|
||||
ASSERT (cast(char *, b)[oldsize + i] == MARK);
|
||||
ASSERT(!memcmp(block->mark, marker, MARKSIZE))
|
||||
ASSERT(oldsize == block->size);
|
||||
ASSERT(!memcmp(cast(char *, b)+oldsize, marker, MARKSIZE));
|
||||
}
|
||||
if (size == 0) {
|
||||
freeblock(block);
|
||||
|
@ -108,7 +155,6 @@ void *debug_realloc (void *b, size_t oldsize, size_t size) {
|
|||
return NULL; /* fake a memory allocation error */
|
||||
else {
|
||||
MemHeader *newblock;
|
||||
int i;
|
||||
size_t commonsize = (oldsize < size) ? oldsize : size;
|
||||
size_t realsize = sizeof(MemHeader) + size + MARKSIZE;
|
||||
newblock = cast(MemHeader *, c_malloc(realsize)); /* alloc a new block */
|
||||
|
@ -119,12 +165,14 @@ void *debug_realloc (void *b, size_t oldsize, size_t size) {
|
|||
freeblock(block); /* erase (and check) old copy */
|
||||
}
|
||||
/* initialize new part of the block with something weird */
|
||||
fillmem(cast(char *, newblock + 1) + commonsize, size - commonsize);
|
||||
if (size > commonsize)
|
||||
fillmem(cast(char *, newblock + 1) + commonsize, size - commonsize);
|
||||
/* initialize marks after block */
|
||||
newblock->d.mark = MARK4;
|
||||
newblock->d.size = size;
|
||||
for (i = 0; i < MARKSIZE; i++)
|
||||
cast(char *, newblock + 1)[size + i] = MARK;
|
||||
memset(newblock->mark, MARK, MARKSIZE);
|
||||
newblock->size = size;
|
||||
newblock->next = mc.start;
|
||||
mc.start = newblock;
|
||||
memset(cast(char *, newblock + 1)+ size, MARK, MARKSIZE);
|
||||
mc.total += size;
|
||||
if (mc.total > mc.maxmem)
|
||||
mc.maxmem = mc.total;
|
||||
|
|
|
@ -712,10 +712,5 @@ static void base_open (lua_State *L) {
|
|||
|
||||
LUALIB_API int luaopen_base (lua_State *L) {
|
||||
base_open(L);
|
||||
#if LUA_OPTIMIZE_MEMORY == 0
|
||||
luaL_register(L, LUA_COLIBNAME, co_funcs);
|
||||
return 2;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "lrotable.h"
|
||||
#include "lstring.h"
|
||||
#include "lflash.h"
|
||||
#include "user_modules.h"
|
||||
|
||||
|
||||
|
@ -26,6 +28,39 @@ static int db_getregistry (lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int db_getstrings (lua_State *L) {
|
||||
size_t i,n;
|
||||
stringtable *tb;
|
||||
GCObject *o;
|
||||
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
|
||||
const char *opt = lua_tolstring (L, 1, &n);
|
||||
if (n==3 && memcmp(opt, "ROM", 4) == 0) {
|
||||
if (G(L)->ROstrt.hash == NULL)
|
||||
return 0;
|
||||
tb = &G(L)->ROstrt;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
tb = &G(L)->strt;
|
||||
lua_settop(L, 0);
|
||||
lua_createtable(L, tb->nuse, 0); /* create table the same size as the strt */
|
||||
for (i=0, n=1; i<tb->size; i++) {
|
||||
for(o = tb->hash[i]; o; o=o->gch.next) {
|
||||
TString *ts =cast(TString *, o);
|
||||
lua_pushnil(L);
|
||||
setsvalue2s(L, L->top-1, ts);
|
||||
lua_rawseti(L, -2, n++); /* enumerate the strt, adding elements */
|
||||
}
|
||||
}
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, "table");
|
||||
lua_getfield(L, -1, "sort"); /* look up table.sort function */
|
||||
lua_replace(L, -2); /* dump the table table */
|
||||
lua_pushvalue(L, -2); /* duplicate the strt_copy ref */
|
||||
lua_call(L, 1, 0); /* table.sort(strt_copy) */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifndef LUA_USE_BUILTIN_DEBUG_MINIMAL
|
||||
|
||||
static int db_getmetatable (lua_State *L) {
|
||||
|
@ -395,6 +430,7 @@ const LUA_REG_TYPE dblib[] = {
|
|||
{LSTRKEY("getlocal"), LFUNCVAL(db_getlocal)},
|
||||
#endif
|
||||
{LSTRKEY("getregistry"), LFUNCVAL(db_getregistry)},
|
||||
{LSTRKEY("getstrings"), LFUNCVAL(db_getstrings)},
|
||||
#ifndef LUA_USE_BUILTIN_DEBUG_MINIMAL
|
||||
{LSTRKEY("getmetatable"), LFUNCVAL(db_getmetatable)},
|
||||
{LSTRKEY("getupvalue"), LFUNCVAL(db_getupvalue)},
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
** $Id: lflash.c
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#define lflash_c
|
||||
#define LUA_CORE
|
||||
#define LUAC_CROSS_FILE
|
||||
#include "lua.h"
|
||||
|
||||
#ifdef LUA_FLASH_STORE
|
||||
#include "lobject.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lstate.h"
|
||||
#include "lfunc.h"
|
||||
#include "lflash.h"
|
||||
#include "platform.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#include "c_fcntl.h"
|
||||
#include "c_stdio.h"
|
||||
#include "c_stdlib.h"
|
||||
#include "c_string.h"
|
||||
|
||||
/*
|
||||
* Flash memory is a fixed memory addressable block that is serially allocated by the
|
||||
* luac build process and the out image can be downloaded into SPIFSS and loaded into
|
||||
* flash with a node.flash.load() command. See luac_cross/lflashimg.c for the build
|
||||
* process.
|
||||
*/
|
||||
|
||||
static char *flashAddr;
|
||||
static uint32_t flashAddrPhys;
|
||||
static uint32_t flashSector;
|
||||
static uint32_t curOffset;
|
||||
|
||||
#define ALIGN(s) (((s)+sizeof(size_t)-1) & ((size_t) (- (signed) sizeof(size_t))))
|
||||
#define ALIGN_BITS(s) (((uint32_t)s) & (sizeof(size_t)-1))
|
||||
#define ALL_SET cast(uint32_t, -1)
|
||||
#define FLASH_SIZE LUA_FLASH_STORE
|
||||
#define FLASH_PAGE_SIZE INTERNAL_FLASH_SECTOR_SIZE
|
||||
#define FLASH_PAGES (FLASH_SIZE/FLASH_PAGE_SIZE)
|
||||
|
||||
#define BREAK_ON_STARTUP_PIN 1 // GPIO 5 or setting to 0 will disable pin startup
|
||||
|
||||
#ifdef NODE_DEBUG
|
||||
extern void dbg_printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
void dumpStrt(stringtable *tb, const char *type) {
|
||||
int i,j;
|
||||
GCObject *o;
|
||||
|
||||
NODE_DBG("\nDumping %s String table\n\n========================\n", type);
|
||||
NODE_DBG("No of elements: %d\nSize of table: %d\n", tb->nuse, tb->size);
|
||||
for (i=0; i<tb->size; i++)
|
||||
for(o = tb->hash[i], j=0; o; (o=o->gch.next), j++ ) {
|
||||
TString *ts =cast(TString *, o);
|
||||
NODE_DBG("%5d %5d %08x %08x %5d %1s %s\n",
|
||||
i, j, (size_t) ts, ts->tsv.hash, ts->tsv.len,
|
||||
ts_isreadonly(ts) ? "R" : " ", getstr(ts));
|
||||
}
|
||||
}
|
||||
|
||||
LUA_API void dumpStrings(lua_State *L) {
|
||||
dumpStrt(&G(L)->strt, "RAM");
|
||||
if (G(L)->ROstrt.hash)
|
||||
dumpStrt(&G(L)->ROstrt, "ROM");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* =====================================================================================
|
||||
* The next 4 functions: flashPosition, flashSetPosition, flashBlock and flashErase
|
||||
* wrap writing to flash. The last two are platform dependent. Also note that any
|
||||
* writes are suppressed if the global writeToFlash is false. This is used in
|
||||
* phase I where the pass is used to size the structures in flash.
|
||||
*/
|
||||
static char *flashPosition(void){
|
||||
return flashAddr + curOffset;
|
||||
}
|
||||
|
||||
|
||||
static char *flashSetPosition(uint32_t offset){
|
||||
NODE_DBG("flashSetPosition(%04x)\n", offset);
|
||||
curOffset = offset;
|
||||
return flashPosition();
|
||||
}
|
||||
|
||||
|
||||
static char *flashBlock(const void* b, size_t size) {
|
||||
void *cur = flashPosition();
|
||||
NODE_DBG("flashBlock((%04x),%08x,%04x)\n", curOffset,b,size);
|
||||
lua_assert(ALIGN_BITS(b) == 0 && ALIGN_BITS(size) == 0);
|
||||
platform_flash_write(b, flashAddrPhys+curOffset, size);
|
||||
curOffset += size;
|
||||
return cur;
|
||||
}
|
||||
|
||||
static void flashErase(uint32_t start, uint32_t end){
|
||||
int i;
|
||||
if (start == -1) start = FLASH_PAGES - 1;
|
||||
if (end == -1) end = FLASH_PAGES - 1;
|
||||
NODE_DBG("flashErase(%04x,%04x)\n", flashSector+start, flashSector+end);
|
||||
for (i = start; i<=end; i++)
|
||||
platform_flash_erase_sector( flashSector + i );
|
||||
}
|
||||
|
||||
|
||||
/* =====================================================================================
|
||||
* Hook in user_main.c to allocate flash memory for the lua flash store
|
||||
*/
|
||||
void luaN_user_init(void) {
|
||||
curOffset = 0;
|
||||
flashSector = platform_flash_reserve_section( FLASH_SIZE, &flashAddrPhys );
|
||||
flashAddr = cast(char *,platform_flash_phys2mapped(flashAddrPhys));
|
||||
NODE_DBG("Flash initialised: %x %08x\n", flashSector, flashAddr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Hook in lstate.c:f_luaopen() to set up ROstrt and ROpvmain if needed
|
||||
*/
|
||||
LUAI_FUNC void luaN_init (lua_State *L) {
|
||||
FlashHeader *fh = cast(FlashHeader *, flashAddr);
|
||||
if (fh->flash_sig == FLASH_SIG &&
|
||||
fh->pROhash != ALL_SET &&
|
||||
fh->mainProto != ALL_SET) {
|
||||
G(L)->ROstrt.hash = cast(GCObject **, fh->pROhash);
|
||||
G(L)->ROstrt.nuse = fh->nROuse ;
|
||||
G(L)->ROstrt.size = fh->nROsize;
|
||||
G(L)->ROpvmain = cast(Proto *,fh->mainProto);
|
||||
}
|
||||
}
|
||||
|
||||
#define BYTE_OFFSET(t,f) cast(size_t, &(cast(t *, NULL)->f))
|
||||
/*
|
||||
* Rehook address chain to correct Flash byte addressed within the mapped adress space
|
||||
* Note that on input each 32-bit address field is split into 2×16-bit subfields
|
||||
* - the lu_int16 offset of the target address being referenced
|
||||
* - the lu_int16 offset of the next address pointer.
|
||||
*/
|
||||
|
||||
static int rebuild_core (int fd, uint32_t size, lu_int32 *buf) {
|
||||
int bi; /* byte offset into memory mapped LFS of current buffer */
|
||||
int wNextOffset = BYTE_OFFSET(FlashHeader,mainProto)/sizeof(lu_int32);
|
||||
int wj; /* word offset into current input buffer */
|
||||
for (bi = 0; bi < size; bi += FLASH_PAGE_SIZE) {
|
||||
int wi = bi / sizeof(lu_int32);
|
||||
int blen = ((bi + FLASH_PAGE_SIZE) < size) ? FLASH_PAGE_SIZE : size - bi;
|
||||
int wlen = blen / sizeof(lu_int32);
|
||||
if (vfs_read(fd, buf , blen) != blen)
|
||||
return 0;
|
||||
|
||||
for (wj = 0; wj < wlen; wj++) {
|
||||
if ((wi + wj) == wNextOffset) { /* this word is the next linked address */
|
||||
int wTargetOffset = buf[wj]&0xFFFF;
|
||||
wNextOffset = buf[wj]>>16;
|
||||
lua_assert(!wNextOffset || (wNextOffset>(wi+wj) && wNextOffset<size/sizeof(lu_int32)));
|
||||
buf[wj] = cast(lu_int32, flashAddr + wTargetOffset*sizeof(lu_int32));
|
||||
}
|
||||
}
|
||||
flashBlock(buf, blen);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Library function called by node.flash.load(filename).
|
||||
*/
|
||||
LUALIB_API int luaN_reload_reboot (lua_State *L) {
|
||||
int fd, status;
|
||||
FlashHeader fh;
|
||||
|
||||
const char *fn = lua_tostring(L, 1);
|
||||
if (!fn || !(fd = vfs_open(fn, "r")))
|
||||
return 0;
|
||||
|
||||
if (vfs_read(fd, &fh, sizeof(fh)) != sizeof(fh) ||
|
||||
fh.flash_sig != FLASH_SIG)
|
||||
return 0;
|
||||
|
||||
if (vfs_lseek(fd, -1, VFS_SEEK_END) != fh.flash_size-1 ||
|
||||
vfs_lseek(fd, 0, VFS_SEEK_SET) != 0)
|
||||
return 0;
|
||||
|
||||
lu_int32 *buffer = luaM_newvector(L, FLASH_PAGE_SIZE / sizeof(lu_int32), lu_int32);
|
||||
|
||||
/*
|
||||
* This is the point of no return. We attempt to rebuild the flash. If there
|
||||
* are any problems them the Flash is going to be corrupt, so the only fallback
|
||||
* is to erase it and reboot with a clean but blank flash. Otherwise the reboot
|
||||
* will load the new LFS.
|
||||
*
|
||||
* Note that the Lua state is not passed into the lua core because from this
|
||||
* point on, we make no calls on the Lua RTS.
|
||||
*/
|
||||
flashErase(0,-1);
|
||||
if (rebuild_core(fd, fh.flash_size, buffer) != fh.flash_size)
|
||||
flashErase(0,-1);
|
||||
/*
|
||||
* Forcing a H/W timeout is the only robust way to insure that other interrupts
|
||||
* and callbacks don't fire and attempt to reference to old LFS context.
|
||||
*/
|
||||
while (1) {}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a C closure pointing to the Flash Index function
|
||||
*/
|
||||
LUAI_FUNC int luaN_index (lua_State *L) {
|
||||
int i;
|
||||
if(G(L)->ROpvmain) {
|
||||
Closure *cl = luaF_newLclosure(L, 0, hvalue(gt(L)));
|
||||
cl->l.p = G(L)->ROpvmain;
|
||||
lua_settop(L, 1);
|
||||
setclvalue(L, L->top-1, cl);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -146,7 +146,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
|
|||
luaM_freearray(L, f->k, f->sizek, TValue);
|
||||
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
|
||||
luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
|
||||
if (!proto_is_readonly(f)) {
|
||||
if (!proto_isreadonly(f)) {
|
||||
luaM_freearray(L, f->code, f->sizecode, Instruction);
|
||||
#ifdef LUA_OPTIMIZE_DEBUG
|
||||
if (f->packedlineinfo) {
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
|
||||
cast(int, sizeof(TValue *)*((n)-1)))
|
||||
|
||||
#define proto_readonly(p) l_setbit((p)->marked, READONLYBIT)
|
||||
#define proto_is_readonly(p) testbit((p)->marked, READONLYBIT)
|
||||
|
||||
LUAI_FUNC Proto *luaF_newproto (lua_State *L);
|
||||
LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
|
||||
LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#define GCSWEEPCOST 10
|
||||
#define GCFINALIZECOST 100
|
||||
|
||||
#if READONLYMASK != (1<<READONLYBIT) || (defined(LUA_FLASH_STORE) && LFSMASK != (1<<LFSBIT))
|
||||
#error "lgc.h and object.h out of sync on READONLYMASK / LFSMASK"
|
||||
#endif
|
||||
|
||||
#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
|
||||
|
||||
|
@ -37,7 +40,7 @@
|
|||
#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
|
||||
#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
|
||||
|
||||
#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
|
||||
#define stringmark(s) if (!isLFSobject(&(s)->tsv)) {reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT);}
|
||||
|
||||
|
||||
#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
|
||||
|
@ -61,12 +64,17 @@
|
|||
|
||||
static void removeentry (Node *n) {
|
||||
lua_assert(ttisnil(gval(n)));
|
||||
if (iscollectable(gkey(n)))
|
||||
if (ttype(gkey(n)) != LUA_TDEADKEY && iscollectable(gkey(n)))
|
||||
lua_assert(!isLFSobject(&((gkey(n))->value.gc->gch)));
|
||||
setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
|
||||
}
|
||||
|
||||
|
||||
static void reallymarkobject (global_State *g, GCObject *o) {
|
||||
/* don't mark LFS Protos (or strings) */
|
||||
if (o->gch.tt == LUA_TPROTO && isLFSobject(&(o->gch)))
|
||||
return;
|
||||
|
||||
lua_assert(iswhite(o) && !isdead(g, o));
|
||||
white2gray(o);
|
||||
switch (o->gch.tt) {
|
||||
|
@ -180,6 +188,8 @@ static int traversetable (global_State *g, Table *h) {
|
|||
while (i--)
|
||||
markvalue(g, &h->array[i]);
|
||||
}
|
||||
if (luaH_isdummy (h->node))
|
||||
return weakkey || weakvalue;
|
||||
i = sizenode(h);
|
||||
while (i--) {
|
||||
Node *n = gnode(h, i);
|
||||
|
@ -202,6 +212,8 @@ static int traversetable (global_State *g, Table *h) {
|
|||
*/
|
||||
static void traverseproto (global_State *g, Proto *f) {
|
||||
int i;
|
||||
if (isLFSobject(f))
|
||||
return; /* don't traverse Protos in LFS */
|
||||
if (f->source) stringmark(f->source);
|
||||
for (i=0; i<f->sizek; i++) /* mark literals */
|
||||
markvalue(g, &f->k[i]);
|
||||
|
@ -317,7 +329,7 @@ static l_mem propagatemark (global_State *g) {
|
|||
sizeof(TValue) * p->sizek +
|
||||
sizeof(LocVar) * p->sizelocvars +
|
||||
sizeof(TString *) * p->sizeupvalues +
|
||||
(proto_is_readonly(p) ? 0 : sizeof(Instruction) * p->sizecode +
|
||||
(proto_isreadonly(p) ? 0 : sizeof(Instruction) * p->sizecode +
|
||||
#ifdef LUA_OPTIMIZE_DEBUG
|
||||
(p->packedlineinfo ?
|
||||
c_strlen(cast(char *, p->packedlineinfo))+1 :
|
||||
|
@ -388,7 +400,10 @@ static void cleartable (GCObject *l) {
|
|||
|
||||
static void freeobj (lua_State *L, GCObject *o) {
|
||||
switch (o->gch.tt) {
|
||||
case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
|
||||
case LUA_TPROTO:
|
||||
lua_assert(!isLFSobject(&(o->gch)));
|
||||
luaF_freeproto(L, gco2p(o));
|
||||
break;
|
||||
case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
|
||||
case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
|
||||
case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
|
||||
|
@ -398,6 +413,7 @@ static void freeobj (lua_State *L, GCObject *o) {
|
|||
break;
|
||||
}
|
||||
case LUA_TSTRING: {
|
||||
lua_assert(!isLFSobject(&(o->gch)));
|
||||
G(L)->strt.nuse--;
|
||||
luaM_freemem(L, o, sizestring(gco2ts(o)));
|
||||
break;
|
||||
|
@ -420,6 +436,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
|
|||
global_State *g = G(L);
|
||||
int deadmask = otherwhite(g);
|
||||
while ((curr = *p) != NULL && count-- > 0) {
|
||||
lua_assert(!isLFSobject(&(curr->gch)) || curr->gch.tt == LUA_TTHREAD);
|
||||
if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
|
||||
sweepwholelist(L, &gco2th(curr)->openupval);
|
||||
if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
|
||||
|
@ -538,7 +555,7 @@ static void atomic (lua_State *L) {
|
|||
size_t udsize; /* total size of userdata to be finalized */
|
||||
/* remark occasional upvalues of (maybe) dead threads */
|
||||
remarkupvals(g);
|
||||
/* traverse objects cautch by write barrier and by 'remarkupvals' */
|
||||
/* traverse objects caucht by write barrier and by 'remarkupvals' */
|
||||
propagateall(g);
|
||||
/* remark weak tables */
|
||||
g->gray = g->weak;
|
||||
|
@ -694,10 +711,10 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
|
|||
global_State *g = G(L);
|
||||
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
|
||||
lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
|
||||
lua_assert(ttype(&o->gch) != LUA_TTABLE);
|
||||
lua_assert(o->gch.tt != LUA_TTABLE);
|
||||
/* must keep invariant? */
|
||||
if (g->gcstate == GCSpropagate)
|
||||
reallymarkobject(g, v); /* restore invariant */
|
||||
reallymarkobject(g, v); /* Restore invariant */
|
||||
else /* don't mind */
|
||||
makewhite(g, o); /* mark as white just to avoid other barriers */
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#define VALUEWEAKBIT 4
|
||||
#define FIXEDBIT 5
|
||||
#define SFIXEDBIT 6
|
||||
#define LFSBIT 6
|
||||
#define READONLYBIT 7
|
||||
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
|
||||
|
||||
|
@ -100,6 +101,13 @@
|
|||
#define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT)
|
||||
#define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT)
|
||||
#define unfixedstack(x) resetbit((x)->marked, FIXEDSTACKBIT)
|
||||
#ifdef LUA_FLASH_STORE
|
||||
#define isLFSobject(x) testbit((x)->marked, LFSBIT)
|
||||
#define stringfix(s) if (!test2bits((s)->tsv.marked, FIXEDBIT, LFSBIT)) {l_setbit((s)->tsv.marked, FIXEDBIT);}
|
||||
#else
|
||||
#define isLFSobject(x) (0)
|
||||
#define stringfix(s) {l_setbit((s)->tsv.marked, FIXEDBIT);}
|
||||
#endif
|
||||
|
||||
#define luaC_checkGC(L) { \
|
||||
condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
|
||||
** Initialization of libraries for lua.c
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#define linit_c
|
||||
#define LUA_LIB
|
||||
#define LUAC_CROSS_FILE
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
#include "luaconf.h"
|
||||
#include "module.h"
|
||||
#if defined(LUA_CROSS_COMPILER)
|
||||
BUILTIN_LIB( start_list, NULL, NULL);
|
||||
BUILTIN_LIB_INIT( start_list, NULL, NULL);
|
||||
#endif
|
||||
extern const luaR_entry strlib[], tab_funcs[], dblib[],
|
||||
co_funcs[], math_map[], syslib[];
|
||||
|
||||
BUILTIN_LIB_INIT( BASE, "", luaopen_base);
|
||||
BUILTIN_LIB_INIT( LOADLIB, LUA_LOADLIBNAME, luaopen_package);
|
||||
|
||||
BUILTIN_LIB( STRING, LUA_STRLIBNAME, strlib);
|
||||
BUILTIN_LIB_INIT( STRING, LUA_STRLIBNAME, luaopen_string);
|
||||
|
||||
BUILTIN_LIB( TABLE, LUA_TABLIBNAME, tab_funcs);
|
||||
BUILTIN_LIB_INIT( TABLE, LUA_TABLIBNAME, luaopen_table);
|
||||
|
||||
BUILTIN_LIB( DBG, LUA_DBLIBNAME, dblib);
|
||||
BUILTIN_LIB_INIT( DBG, LUA_DBLIBNAME, luaopen_debug);
|
||||
|
||||
BUILTIN_LIB( CO, LUA_COLIBNAME, co_funcs);
|
||||
|
||||
BUILTIN_LIB( MATH, LUA_MATHLIBNAME, math_map);
|
||||
|
||||
#if defined(LUA_CROSS_COMPILER)
|
||||
extern const luaR_entry syslib[], iolib[];
|
||||
BUILTIN_LIB( OS, LUA_OSLIBNAME, syslib);
|
||||
BUILTIN_LIB_INIT( IO, LUA_IOLIBNAME, luaopen_io);
|
||||
BUILTIN_LIB( end_list, NULL, NULL);
|
||||
BUILTIN_LIB_INIT( end_list, NULL, NULL);
|
||||
/*
|
||||
* These base addresses are internal to this module for cross compile builds
|
||||
* This also exploits feature of the GCC code generator that the variables are
|
||||
* emitted in either normal OR reverse order within PSECT.
|
||||
*/
|
||||
#define isascending(n) ((&(n ## _end_list)-&(n ## _start_list))>0)
|
||||
static const luaL_Reg *lua_libs;
|
||||
const luaR_table *lua_rotable;
|
||||
#else
|
||||
/* These base addresses are Xtensa toolchain linker constants for Firmware builds */
|
||||
extern const luaL_Reg lua_libs_base[];
|
||||
extern const luaR_table lua_rotable_base[];
|
||||
static const luaL_Reg *lua_libs = lua_libs_base;
|
||||
const luaR_table *lua_rotable = lua_rotable_base;
|
||||
#endif
|
||||
|
||||
void luaL_openlibs (lua_State *L) {
|
||||
#if defined(LUA_CROSS_COMPILER)
|
||||
lua_libs = (isascending(lua_lib) ? &lua_lib_start_list : &lua_lib_end_list) + 1;
|
||||
lua_rotable = (isascending(lua_rotable) ? &lua_rotable_start_list : &lua_rotable_end_list) + 1;
|
||||
#endif
|
||||
const luaL_Reg *lib = lua_libs;
|
||||
for (; lib->name; lib++) {
|
||||
if (lib->func)
|
||||
{
|
||||
lua_pushcfunction(L, lib->func);
|
||||
lua_pushstring(L, lib->name);
|
||||
lua_call(L, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -326,7 +326,7 @@ const LUA_REG_TYPE math_map[] = {
|
|||
{LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)},
|
||||
{LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)},
|
||||
#if LUA_OPTIMIZE_MEMORY > 0
|
||||
{LSTRKEY("huge"), LNUMVAL(LONG_MAX)},
|
||||
{LSTRKEY("huge"), LNUMVAL(INT_MAX)},
|
||||
#endif
|
||||
#else
|
||||
{LSTRKEY("abs"), LFUNCVAL(math_abs)},
|
||||
|
@ -374,7 +374,7 @@ const LUA_REG_TYPE math_map[] = {
|
|||
*/
|
||||
|
||||
#if defined LUA_NUMBER_INTEGRAL
|
||||
# include "c_limits.h" /* for LONG_MAX */
|
||||
# include "c_limits.h" /* for INT_MAX */
|
||||
#endif
|
||||
|
||||
LUALIB_API int luaopen_math (lua_State *L) {
|
||||
|
@ -383,7 +383,7 @@ LUALIB_API int luaopen_math (lua_State *L) {
|
|||
#else
|
||||
luaL_register(L, LUA_MATHLIBNAME, math_map);
|
||||
# if defined LUA_NUMBER_INTEGRAL
|
||||
lua_pushnumber(L, LONG_MAX);
|
||||
lua_pushnumber(L, INT_MAX);
|
||||
lua_setfield(L, -2, "huge");
|
||||
# else
|
||||
lua_pushnumber(L, PI);
|
||||
|
|
|
@ -53,7 +53,8 @@ int luaO_fb2int (int x) {
|
|||
|
||||
|
||||
int luaO_log2 (unsigned int x) {
|
||||
static const lu_byte log_2[256] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = {
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
static const lu_byte log_2[256] = {
|
||||
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
|
@ -65,10 +66,12 @@ int luaO_log2 (unsigned int x) {
|
|||
};
|
||||
int l = -1;
|
||||
while (x >= 256) { l += 8; x >>= 8; }
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
return l + log_2[x];
|
||||
#else
|
||||
return l + byte_of_aligned_array(log_2,x);
|
||||
/* Use Normalization Shift Amount Unsigned: 0x1=>31 up to 0xffffffff =>0
|
||||
* See Xtensa Instruction Set Architecture (ISA) Refman P 462 */
|
||||
asm volatile ("nsau %0, %1;" :"=r"(x) : "r"(x));
|
||||
return 32 - x;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -103,7 +106,7 @@ int luaO_str2d (const char *s, lua_Number *result) {
|
|||
#if defined(LUA_CROSS_COMPILER)
|
||||
{
|
||||
long lres = strtoul(s, &endptr, 16);
|
||||
#if LONG_MAX != 2147483647L
|
||||
#if INT_MAX != 2147483647L
|
||||
if (lres & ~0xffffffffL)
|
||||
*result = cast_num(-1);
|
||||
else if (lres & 0x80000000L)
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
|
||||
#define NUM_TAGS (LAST_TAG+1)
|
||||
|
||||
/* mask for 'read-only' objects. must match READONLYBIT in lgc.h' */
|
||||
#define READONLYMASK 128
|
||||
|
||||
|
||||
#define READONLYMASK (1<<7) /* denormalised bitmask for READONLYBIT and */
|
||||
#ifdef LUA_FLASH_STORE
|
||||
#define LFSMASK (1<<6) /* LFSBIT to avoid include proliferation */
|
||||
#endif
|
||||
/*
|
||||
** Extra tags for non-values
|
||||
*/
|
||||
|
@ -55,86 +55,33 @@ typedef struct GCheader {
|
|||
CommonHeader;
|
||||
} GCheader;
|
||||
|
||||
|
||||
#if defined(LUA_PACK_VALUE) || defined(ELUA_ENDIAN_BIG) || defined(ELUA_ENDIAN_SMALL)
|
||||
# error "NodeMCU does not support the eLua LUA_PACK_VALUE and ELUA_ENDIAN defines"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Union of all Lua values
|
||||
*/
|
||||
#if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
|
||||
typedef union {
|
||||
struct {
|
||||
int _pad0;
|
||||
GCObject *gc;
|
||||
};
|
||||
struct {
|
||||
int _pad1;
|
||||
void *p;
|
||||
};
|
||||
lua_Number n;
|
||||
struct {
|
||||
int _pad2;
|
||||
int b;
|
||||
};
|
||||
} Value;
|
||||
#else // #if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
|
||||
typedef union {
|
||||
GCObject *gc;
|
||||
void *p;
|
||||
lua_Number n;
|
||||
int b;
|
||||
} Value;
|
||||
#endif // #if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
|
||||
|
||||
/*
|
||||
** Tagged Values
|
||||
*/
|
||||
|
||||
#ifndef LUA_PACK_VALUE
|
||||
#define TValuefields Value value; int tt
|
||||
#define LUA_TVALUE_NIL {NULL}, LUA_TNIL
|
||||
|
||||
typedef struct lua_TValue {
|
||||
TValuefields;
|
||||
} TValue;
|
||||
#else // #ifndef LUA_PACK_VALUE
|
||||
#ifdef ELUA_ENDIAN_LITTLE
|
||||
#define TValuefields union { \
|
||||
struct { \
|
||||
int _pad0; \
|
||||
int tt_sig; \
|
||||
} _ts; \
|
||||
struct { \
|
||||
int _pad; \
|
||||
short tt; \
|
||||
short sig; \
|
||||
} _t; \
|
||||
Value value; \
|
||||
}
|
||||
#define LUA_TVALUE_NIL {0, add_sig(LUA_TNIL)}
|
||||
#else // #ifdef ELUA_ENDIAN_LITTLE
|
||||
#define TValuefields union { \
|
||||
struct { \
|
||||
int tt_sig; \
|
||||
int _pad0; \
|
||||
} _ts; \
|
||||
struct { \
|
||||
short sig; \
|
||||
short tt; \
|
||||
int _pad; \
|
||||
} _t; \
|
||||
Value value; \
|
||||
}
|
||||
#define LUA_TVALUE_NIL {add_sig(LUA_TNIL), 0}
|
||||
#endif // #ifdef ELUA_ENDIAN_LITTLE
|
||||
#define LUA_NOTNUMBER_SIG (-1)
|
||||
#define add_sig(tt) ( 0xffff0000 | (tt) )
|
||||
|
||||
typedef TValuefields TValue;
|
||||
#endif // #ifndef LUA_PACK_VALUE
|
||||
|
||||
/* Macros to test type */
|
||||
#ifndef LUA_PACK_VALUE
|
||||
#define ttisnil(o) (ttype(o) == LUA_TNIL)
|
||||
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
|
||||
#define ttisstring(o) (ttype(o) == LUA_TSTRING)
|
||||
|
@ -146,27 +93,11 @@ typedef TValuefields TValue;
|
|||
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
|
||||
#define ttisrotable(o) (ttype(o) == LUA_TROTABLE)
|
||||
#define ttislightfunction(o) (ttype(o) == LUA_TLIGHTFUNCTION)
|
||||
#else // #ifndef LUA_PACK_VALUE
|
||||
#define ttisnil(o) (ttype_sig(o) == add_sig(LUA_TNIL))
|
||||
#define ttisnumber(o) ((o)->_t.sig != LUA_NOTNUMBER_SIG)
|
||||
#define ttisstring(o) (ttype_sig(o) == add_sig(LUA_TSTRING))
|
||||
#define ttistable(o) (ttype_sig(o) == add_sig(LUA_TTABLE))
|
||||
#define ttisfunction(o) (ttype_sig(o) == add_sig(LUA_TFUNCTION))
|
||||
#define ttisboolean(o) (ttype_sig(o) == add_sig(LUA_TBOOLEAN))
|
||||
#define ttisuserdata(o) (ttype_sig(o) == add_sig(LUA_TUSERDATA))
|
||||
#define ttisthread(o) (ttype_sig(o) == add_sig(LUA_TTHREAD))
|
||||
#define ttislightuserdata(o) (ttype_sig(o) == add_sig(LUA_TLIGHTUSERDATA))
|
||||
#define ttisrotable(o) (ttype_sig(o) == add_sig(LUA_TROTABLE))
|
||||
#define ttislightfunction(o) (ttype_sig(o) == add_sig(LUA_TLIGHTFUNCTION))
|
||||
#endif // #ifndef LUA_PACK_VALUE
|
||||
|
||||
|
||||
/* Macros to access values */
|
||||
#ifndef LUA_PACK_VALUE
|
||||
#define ttype(o) ((o)->tt)
|
||||
#else // #ifndef LUA_PACK_VALUE
|
||||
#define ttype(o) ((o)->_t.sig == LUA_NOTNUMBER_SIG ? (o)->_t.tt : LUA_TNUMBER)
|
||||
#define ttype_sig(o) ((o)->_ts.tt_sig)
|
||||
#endif // #ifndef LUA_PACK_VALUE
|
||||
|
||||
#define ttype(o) ((void) (o)->value, (o)->tt)
|
||||
#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
|
||||
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
|
||||
#define rvalue(o) check_exp(ttisrotable(o), (o)->value.p)
|
||||
|
@ -186,24 +117,15 @@ typedef TValuefields TValue;
|
|||
/*
|
||||
** for internal debug only
|
||||
*/
|
||||
#ifndef LUA_PACK_VALUE
|
||||
|
||||
#define checkconsistency(obj) \
|
||||
lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
|
||||
|
||||
#define checkliveness(g,obj) \
|
||||
lua_assert(!iscollectable(obj) || \
|
||||
((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
|
||||
#else // #ifndef LUA_PACK_VALUE
|
||||
#define checkconsistency(obj) \
|
||||
lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch._t.tt))
|
||||
|
||||
#define checkliveness(g,obj) \
|
||||
lua_assert(!iscollectable(obj) || \
|
||||
((ttype(obj) == (obj)->value.gc->gch._t.tt) && !isdead(g, (obj)->value.gc)))
|
||||
#endif // #ifndef LUA_PACK_VALUE
|
||||
|
||||
/* Macros to set values */
|
||||
#ifndef LUA_PACK_VALUE
|
||||
#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
|
||||
|
||||
#define setnvalue(obj,x) \
|
||||
|
@ -257,69 +179,10 @@ typedef TValuefields TValue;
|
|||
i_o->value.gc=i_x; i_o->tt=LUA_TPROTO; \
|
||||
checkliveness(G(L),i_o); }
|
||||
|
||||
|
||||
|
||||
|
||||
#define setobj(L,obj1,obj2) \
|
||||
{ const TValue *o2=(obj2); TValue *o1=(obj1); \
|
||||
o1->value = o2->value; o1->tt=o2->tt; \
|
||||
checkliveness(G(L),o1); }
|
||||
#else // #ifndef LUA_PACK_VALUE
|
||||
#define setnilvalue(obj) ( ttype_sig(obj) = add_sig(LUA_TNIL) )
|
||||
|
||||
#define setnvalue(obj,x) \
|
||||
{ TValue *i_o=(obj); i_o->value.n=(x); }
|
||||
|
||||
#define setpvalue(obj,x) \
|
||||
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->_ts.tt_sig=add_sig(LUA_TLIGHTUSERDATA);}
|
||||
|
||||
#define setrvalue(obj,x) \
|
||||
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->_ts.tt_sig=add_sig(LUA_TROTABLE);}
|
||||
|
||||
#define setfvalue(obj,x) \
|
||||
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->_ts.tt_sig=add_sig(LUA_TLIGHTFUNCTION);}
|
||||
|
||||
#define setbvalue(obj,x) \
|
||||
{ TValue *i_o=(obj); i_o->value.b=(x); i_o->_ts.tt_sig=add_sig(LUA_TBOOLEAN);}
|
||||
|
||||
#define setsvalue(L,obj,x) \
|
||||
{ TValue *i_o=(obj); \
|
||||
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TSTRING); \
|
||||
checkliveness(G(L),i_o); }
|
||||
|
||||
#define setuvalue(L,obj,x) \
|
||||
{ TValue *i_o=(obj); \
|
||||
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TUSERDATA); \
|
||||
checkliveness(G(L),i_o); }
|
||||
|
||||
#define setthvalue(L,obj,x) \
|
||||
{ TValue *i_o=(obj); \
|
||||
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TTHREAD); \
|
||||
checkliveness(G(L),i_o); }
|
||||
|
||||
#define setclvalue(L,obj,x) \
|
||||
{ TValue *i_o=(obj); \
|
||||
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TFUNCTION); \
|
||||
checkliveness(G(L),i_o); }
|
||||
|
||||
#define sethvalue(L,obj,x) \
|
||||
{ TValue *i_o=(obj); \
|
||||
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TTABLE); \
|
||||
checkliveness(G(L),i_o); }
|
||||
|
||||
#define setptvalue(L,obj,x) \
|
||||
{ TValue *i_o=(obj); \
|
||||
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TPROTO); \
|
||||
checkliveness(G(L),i_o); }
|
||||
|
||||
|
||||
|
||||
|
||||
#define setobj(L,obj1,obj2) \
|
||||
{ const TValue *o2=(obj2); TValue *o1=(obj1); \
|
||||
o1->value = o2->value; \
|
||||
checkliveness(G(L),o1); }
|
||||
#endif // #ifndef LUA_PACK_VALUE
|
||||
|
||||
/*
|
||||
** different types of sets, according to destination
|
||||
|
@ -340,13 +203,7 @@ typedef TValuefields TValue;
|
|||
#define setobj2n setobj
|
||||
#define setsvalue2n setsvalue
|
||||
|
||||
#ifndef LUA_PACK_VALUE
|
||||
#define setttype(obj, tt) (ttype(obj) = (tt))
|
||||
#else // #ifndef LUA_PACK_VALUE
|
||||
/* considering it used only in lgc to set LUA_TDEADKEY */
|
||||
/* we could define it this way */
|
||||
#define setttype(obj, _tt) ( ttype_sig(obj) = add_sig(_tt) )
|
||||
#endif // #ifndef LUA_PACK_VALUE
|
||||
#define setttype(obj, stt) ((void) (obj)->value, (obj)->tt = (stt))
|
||||
|
||||
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
|
||||
|
||||
|
@ -367,9 +224,16 @@ typedef union TString {
|
|||
} tsv;
|
||||
} TString;
|
||||
|
||||
|
||||
#define getstr(ts) (((ts)->tsv.marked & READONLYMASK) ? cast(const char *, *(const char**)((ts) + 1)) : cast(const char *, (ts) + 1))
|
||||
#define svalue(o) getstr(rawtsvalue(o))
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
#define isreadonly(o) (0)
|
||||
#else
|
||||
#define isreadonly(o) ((o).marked & READONLYMASK)
|
||||
#endif
|
||||
#define ts_isreadonly(ts) isreadonly((ts)->tsv)
|
||||
#define getstr(ts) (ts_isreadonly(ts) ? \
|
||||
cast(const char *, *(const char**)((ts) + 1)) : \
|
||||
cast(const char *, (ts) + 1))
|
||||
#define svalue(o) getstr(rawtsvalue(o))
|
||||
|
||||
|
||||
|
||||
|
@ -418,6 +282,7 @@ typedef struct Proto {
|
|||
lu_byte is_vararg;
|
||||
lu_byte maxstacksize;
|
||||
} Proto;
|
||||
#define proto_isreadonly(p) isreadonly(*(p))
|
||||
|
||||
|
||||
/* masks for new-style vararg */
|
||||
|
@ -487,7 +352,6 @@ typedef union Closure {
|
|||
** Tables
|
||||
*/
|
||||
|
||||
#ifndef LUA_PACK_VALUE
|
||||
typedef union TKey {
|
||||
struct {
|
||||
TValuefields;
|
||||
|
@ -497,16 +361,6 @@ typedef union TKey {
|
|||
} TKey;
|
||||
|
||||
#define LUA_TKEY_NIL {LUA_TVALUE_NIL, NULL}
|
||||
#else // #ifndef LUA_PACK_VALUE
|
||||
typedef struct TKey {
|
||||
TValue tvk;
|
||||
struct {
|
||||
struct Node *next; /* for chaining */
|
||||
} nk;
|
||||
} TKey;
|
||||
|
||||
#define LUA_TKEY_NIL {LUA_TVALUE_NIL}, {NULL}
|
||||
#endif // #ifndef LUA_PACK_VALUE
|
||||
|
||||
typedef struct Node {
|
||||
TValue i_val;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#undef LNILVAL
|
||||
#undef LREGISTER
|
||||
|
||||
#if (MIN_OPT_LEVEL > 0) && (LUA_OPTIMIZE_MEMORY >= MIN_OPT_LEVEL)
|
||||
#if LUA_OPTIMIZE_MEMORY >=1
|
||||
#define LUA_REG_TYPE luaR_entry
|
||||
#define LSTRKEY LRO_STRKEY
|
||||
#define LNUMKEY LRO_NUMKEY
|
||||
|
|
|
@ -14,11 +14,10 @@
|
|||
#define LUAR_FINDVALUE 1
|
||||
|
||||
/* Externally defined read-only table array */
|
||||
extern const luaR_table lua_rotable[];
|
||||
extern const luaR_table *lua_rotable;
|
||||
|
||||
/* Find a global "read only table" in the constant lua_rotable array */
|
||||
void* luaR_findglobal(const char *name, unsigned len) {
|
||||
#ifndef LUA_CROSS_COMPILER
|
||||
unsigned i;
|
||||
|
||||
if (c_strlen(name) > LUA_MAX_ROTABLE_NAME)
|
||||
|
@ -27,7 +26,6 @@ void* luaR_findglobal(const char *name, unsigned len) {
|
|||
if (*lua_rotable[i].name != '\0' && c_strlen(lua_rotable[i].name) == len && !c_strncmp(lua_rotable[i].name, name, len)) {
|
||||
return (void*)(lua_rotable[i].pentries);
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -87,7 +85,7 @@ static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos,
|
|||
if (pentries[pos].key.type != LUA_TNIL) {
|
||||
/* Found an entry */
|
||||
if (pentries[pos].key.type == LUA_TSTRING)
|
||||
setsvalue(L, key, luaS_newro(L, pentries[pos].key.id.strkey))
|
||||
setsvalue(L, key, luaS_new(L, pentries[pos].key.id.strkey))
|
||||
else
|
||||
setnvalue(key, (lua_Number)pentries[pos].key.id.numkey)
|
||||
setobj2s(L, val, &pentries[pos].value);
|
||||
|
@ -129,10 +127,15 @@ void luaR_getcstr(char *dest, const TString *src, size_t maxsize) {
|
|||
|
||||
/* Return 1 if the given pointer is a rotable */
|
||||
#ifdef LUA_META_ROTABLES
|
||||
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
extern char edata[];
|
||||
int luaR_isrotable(void *p) {
|
||||
return (char*)p <= edata;
|
||||
}
|
||||
#else
|
||||
#include "compiler.h"
|
||||
|
||||
int luaR_isrotable(void *p) {
|
||||
return RODATA_START_ADDRESS <= (char*)p && (char*)p <= RODATA_END_ADDRESS;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -4,32 +4,16 @@
|
|||
#define lrotable_h
|
||||
|
||||
#include "lua.h"
|
||||
#include "llimits.h"
|
||||
#include "lobject.h"
|
||||
#include "luaconf.h"
|
||||
#include "lobject.h"
|
||||
#include "llimits.h"
|
||||
|
||||
/* Macros one can use to define rotable entries */
|
||||
#ifndef LUA_PACK_VALUE
|
||||
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
|
||||
#define LRO_LUDATA(v) {{.p = v}, LUA_TLIGHTUSERDATA}
|
||||
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
|
||||
#define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE}
|
||||
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
|
||||
#else // #ifndef LUA_PACK_VALUE
|
||||
#define LRO_NUMVAL(v) {.value.n = v}
|
||||
#ifdef ELUA_ENDIAN_LITTLE
|
||||
#define LRO_FUNCVAL(v) {{(int)v, add_sig(LUA_TLIGHTFUNCTION)}}
|
||||
#define LRO_LUDATA(v) {{(int)v, add_sig(LUA_TLIGHTUSERDATA)}}
|
||||
#define LRO_ROVAL(v) {{(int)v, add_sig(LUA_TROTABLE)}}
|
||||
#define LRO_NILVAL {{0, add_sig(LUA_TNIL)}}
|
||||
#else // #ifdef ELUA_ENDIAN_LITTLE
|
||||
#define LRO_FUNCVAL(v) {{add_sig(LUA_TLIGHTFUNCTION), (int)v}}
|
||||
#define LRO_LUDATA(v) {{add_sig(LUA_TLIGHTUSERDATA), (int)v}}
|
||||
#define LRO_ROVAL(v) {{add_sig(LUA_TROTABLE), (int)v}}
|
||||
#define LRO_NILVAL {{add_sig(LUA_TNIL), 0}}
|
||||
#endif // #ifdef ELUA_ENDIAN_LITTLE
|
||||
#endif // #ifndef LUA_PACK_VALUE
|
||||
|
||||
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = k}}
|
||||
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
|
||||
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "ldebug.h"
|
||||
#include "ldo.h"
|
||||
#include "lflash.h"
|
||||
#include "lfunc.h"
|
||||
#include "lgc.h"
|
||||
#include "llex.h"
|
||||
|
@ -72,9 +73,12 @@ static void f_luaopen (lua_State *L, void *ud) {
|
|||
sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
|
||||
sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
|
||||
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
|
||||
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
|
||||
luaN_init(L); /* optionally map RO string table */
|
||||
#endif
|
||||
luaT_init(L);
|
||||
luaX_init(L);
|
||||
luaS_fix(luaS_newliteral(L, MEMERRMSG));
|
||||
stringfix(luaS_newliteral(L, MEMERRMSG));
|
||||
g->GCthreshold = 4*g->totalbytes;
|
||||
}
|
||||
|
||||
|
@ -191,6 +195,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
|||
g->memlimit = EGC_INITIAL_MEMLIMIT;
|
||||
#else
|
||||
g->memlimit = 0;
|
||||
#endif
|
||||
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
|
||||
g->ROstrt.size = 0;
|
||||
g->ROstrt.nuse = 0;
|
||||
g->ROstrt.hash = NULL;
|
||||
g->ROpvmain = NULL;
|
||||
#endif
|
||||
for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
|
||||
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
|
||||
|
|
|
@ -94,6 +94,10 @@ typedef struct global_State {
|
|||
UpVal uvhead; /* head of double-linked list of all open upvalues */
|
||||
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
|
||||
TString *tmname[TM_N]; /* array with tag-method names */
|
||||
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
|
||||
stringtable ROstrt; /* Flash-based hash table for RO strings */
|
||||
Proto *ROpvmain; /* Flash-based Proto main */
|
||||
#endif
|
||||
} global_State;
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
|
|||
tb = &G(L)->strt;
|
||||
if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
|
||||
luaS_resize(L, tb->size*2); /* too crowded */
|
||||
ts = cast(TString *, luaM_malloc(L, readonly ? sizeof(char**)+sizeof(TString) : (l+1)*sizeof(char)+sizeof(TString)));
|
||||
ts = cast(TString *, luaM_malloc(L, sizeof(TString) + (readonly ? sizeof(char**) : (l+1)*sizeof(char))));
|
||||
ts->tsv.len = l;
|
||||
ts->tsv.hash = h;
|
||||
ts->tsv.marked = luaC_white(G(L));
|
||||
|
@ -71,7 +71,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
|
|||
((char *)(ts+1))[l] = '\0'; /* ending 0 */
|
||||
} else {
|
||||
*(char **)(ts+1) = (char *)str;
|
||||
luaS_readonly(ts);
|
||||
l_setbit((ts)->tsv.marked, READONLYBIT);
|
||||
}
|
||||
h = lmod(h, tb->size);
|
||||
ts->tsv.next = tb->hash[h]; /* chain new entry */
|
||||
|
@ -80,14 +80,29 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
|
|||
return ts;
|
||||
}
|
||||
|
||||
#include "compiler.h"
|
||||
static int lua_is_ptr_in_ro_area(const char *p) {
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
return 0;
|
||||
#else
|
||||
return p >= RODATA_START_ADDRESS && p <= RODATA_END_ADDRESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, int readonly) {
|
||||
/*
|
||||
* The string algorithm has been modified to be LFS-friendly. The previous eLua
|
||||
* algo used the address of the string was in flash and the string was >4 bytes
|
||||
* This creates miminal savings and prevents the use of LFS based strings
|
||||
*/
|
||||
|
||||
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
|
||||
GCObject *o;
|
||||
unsigned int h = cast(unsigned int, l); /* seed */
|
||||
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
|
||||
size_t l1;
|
||||
for (l1=l; l1>=step; l1-=step) /* compute hash */
|
||||
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
|
||||
|
||||
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
|
||||
o != NULL;
|
||||
o = o->gch.next) {
|
||||
|
@ -98,35 +113,27 @@ static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, in
|
|||
return ts;
|
||||
}
|
||||
}
|
||||
return newlstr(L, str, l, h, readonly); /* not found */
|
||||
}
|
||||
|
||||
static int lua_is_ptr_in_ro_area(const char *p) {
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
return 0;
|
||||
#else
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
return p >= RODATA_START_ADDRESS && p <= RODATA_END_ADDRESS;
|
||||
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
|
||||
/*
|
||||
* The RAM strt is searched first since RAM access is faster tham Flash access.
|
||||
* If a miss, then search the RO string table.
|
||||
*/
|
||||
if (G(L)->ROstrt.hash) {
|
||||
for (o = G(L)->ROstrt.hash[lmod(h, G(L)->ROstrt.size)];
|
||||
o != NULL;
|
||||
o = o->gch.next) {
|
||||
TString *ts = rawgco2ts(o);
|
||||
if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
|
||||
return ts;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
|
||||
// If the pointer is in a read-only memory and the string is at least 4 chars in length,
|
||||
// create it as a read-only string instead
|
||||
if(lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) && l == c_strlen(str))
|
||||
return luaS_newlstr_helper(L, str, l, LUAS_READONLY_STRING);
|
||||
else
|
||||
return luaS_newlstr_helper(L, str, l, LUAS_REGULAR_STRING);
|
||||
}
|
||||
|
||||
|
||||
LUAI_FUNC TString *luaS_newrolstr (lua_State *L, const char *str, size_t l) {
|
||||
if(l+1 > sizeof(char**) && l == c_strlen(str))
|
||||
return luaS_newlstr_helper(L, str, l, LUAS_READONLY_STRING);
|
||||
else // no point in creating a RO string, as it would actually be larger
|
||||
return luaS_newlstr_helper(L, str, l, LUAS_REGULAR_STRING);
|
||||
/* New additions to the RAM strt are tagged as readonly if the string address
|
||||
* is in the CTEXT segment (target only, not luac.cross) */
|
||||
int readonly = (lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) &&
|
||||
l == c_strlen(str) ? LUAS_READONLY_STRING : LUAS_REGULAR_STRING);
|
||||
return newlstr(L, str, l, h, readonly); /* not found */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,22 +13,16 @@
|
|||
#include "lstate.h"
|
||||
|
||||
|
||||
#define sizestring(s) (sizeof(union TString)+(luaS_isreadonly(s) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
|
||||
#define sizestring(s) (sizeof(union TString)+(testbit((s)->marked, READONLYBIT) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
|
||||
|
||||
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
|
||||
|
||||
#define luaS_new(L, s) (luaS_newlstr(L, s, c_strlen(s)))
|
||||
#define luaS_newro(L, s) (luaS_newrolstr(L, s, c_strlen(s)))
|
||||
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
|
||||
(sizeof(s)/sizeof(char))-1))
|
||||
|
||||
#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
|
||||
#define luaS_readonly(s) l_setbit((s)->tsv.marked, READONLYBIT)
|
||||
#define luaS_isreadonly(s) testbit((s)->marked, READONLYBIT)
|
||||
|
||||
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
|
||||
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
|
||||
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
|
||||
LUAI_FUNC TString *luaS_newrolstr (lua_State *L, const char *str, size_t l);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -749,12 +749,12 @@ int luaH_getn_ro (void *t) {
|
|||
return len;
|
||||
}
|
||||
|
||||
#if defined(LUA_DEBUG)
|
||||
int luaH_isdummy (Node *n) { return n == dummynode; }
|
||||
|
||||
#if defined(LUA_DEBUG)
|
||||
Node *luaH_mainposition (const Table *t, const TValue *key) {
|
||||
return mainposition(t, key);
|
||||
}
|
||||
|
||||
int luaH_isdummy (Node *n) { return n == dummynode; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -34,11 +34,9 @@ LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
|
|||
LUAI_FUNC int luaH_next_ro (lua_State *L, void *t, StkId key);
|
||||
LUAI_FUNC int luaH_getn (Table *t);
|
||||
LUAI_FUNC int luaH_getn_ro (void *t);
|
||||
LUAI_FUNC int luaH_isdummy (Node *n);
|
||||
|
||||
#if defined(LUA_DEBUG)
|
||||
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
|
||||
LUAI_FUNC int luaH_isdummy (Node *n);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
#include "lgc.h"
|
||||
#include "lstring.h"
|
||||
#include "ltable.h"
|
||||
#include "ltm.h"
|
||||
|
@ -39,7 +40,7 @@ void luaT_init (lua_State *L) {
|
|||
int i;
|
||||
for (i=0; i<TM_N; i++) {
|
||||
G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
|
||||
luaS_fix(G(L)->tmname[i]); /* never collect these names */
|
||||
stringfix(G(L)->tmname[i]); /* never collect these names */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
178
app/lua/lua.c
178
app/lua/lua.c
|
@ -13,6 +13,7 @@
|
|||
#include "user_version.h"
|
||||
#include "driver/readline.h"
|
||||
#include "driver/uart.h"
|
||||
#include "platform.h"
|
||||
|
||||
#define lua_c
|
||||
|
||||
|
@ -21,7 +22,9 @@
|
|||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "legc.h"
|
||||
|
||||
#ifdef LUA_FLASH_STORE
|
||||
#include "lflash.h"
|
||||
#endif
|
||||
#include "os_type.h"
|
||||
|
||||
lua_State *globalL = NULL;
|
||||
|
@ -30,44 +33,6 @@ lua_Load gLoad;
|
|||
|
||||
static const char *progname = LUA_PROGNAME;
|
||||
|
||||
#if 0
|
||||
static void lstop (lua_State *L, lua_Debug *ar) {
|
||||
(void)ar; /* unused arg. */
|
||||
lua_sethook(L, NULL, 0, 0);
|
||||
luaL_error(L, "interrupted!");
|
||||
}
|
||||
|
||||
|
||||
static void laction (int i) {
|
||||
// signal(i, SIG_DFL);
|
||||
/* if another SIGINT happens before lstop,
|
||||
terminate process (default action) */
|
||||
lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
|
||||
}
|
||||
|
||||
|
||||
static void print_usage (void) {
|
||||
#if defined(LUA_USE_STDIO)
|
||||
c_fprintf(c_stderr,
|
||||
#else
|
||||
luai_writestringerror(
|
||||
#endif
|
||||
"usage: %s [options] [script [args]].\n"
|
||||
"Available options are:\n"
|
||||
" -e stat execute string " LUA_QL("stat") "\n"
|
||||
" -l name require library " LUA_QL("name") "\n"
|
||||
" -m limit set memory limit. (units are in Kbytes)\n"
|
||||
" -i enter interactive mode after executing " LUA_QL("script") "\n"
|
||||
" -v show version information\n"
|
||||
" -- stop handling options\n"
|
||||
" - execute stdin and stop handling options\n"
|
||||
,
|
||||
progname);
|
||||
#if defined(LUA_USE_STDIO)
|
||||
c_fflush(c_stderr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void l_message (const char *pname, const char *msg) {
|
||||
#if defined(LUA_USE_STDIO)
|
||||
|
@ -154,17 +119,11 @@ static int getargs (lua_State *L, char **argv, int n) {
|
|||
return narg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int dofile (lua_State *L, const char *name) {
|
||||
int status = luaL_loadfile(L, name) || docall(L, 0, 1);
|
||||
return report(L, status);
|
||||
}
|
||||
#else
|
||||
static int dofsfile (lua_State *L, const char *name) {
|
||||
int status = luaL_loadfsfile(L, name) || docall(L, 0, 1);
|
||||
return report(L, status);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int dostring (lua_State *L, const char *s, const char *name) {
|
||||
int status = luaL_loadbuffer(L, s, c_strlen(s), name) || docall(L, 0, 1);
|
||||
|
@ -201,92 +160,6 @@ static int incomplete (lua_State *L, int status) {
|
|||
return 0; /* else... */
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int pushline (lua_State *L, int firstline) {
|
||||
char buffer[LUA_MAXINPUT];
|
||||
char *b = buffer;
|
||||
size_t l;
|
||||
const char *prmt = get_prompt(L, firstline);
|
||||
if (lua_readline(L, b, prmt) == 0)
|
||||
return 0; /* no input */
|
||||
l = c_strlen(b);
|
||||
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
|
||||
b[l-1] = '\0'; /* remove it */
|
||||
if (firstline && b[0] == '=') /* first line starts with `=' ? */
|
||||
lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
|
||||
else
|
||||
lua_pushstring(L, b);
|
||||
lua_freeline(L, b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int loadline (lua_State *L) {
|
||||
int status;
|
||||
lua_settop(L, 0);
|
||||
if (!pushline(L, 1))
|
||||
return -1; /* no input */
|
||||
for (;;) { /* repeat until gets a complete line */
|
||||
status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
|
||||
if (!incomplete(L, status)) break; /* cannot try to add lines? */
|
||||
if (!pushline(L, 0)) /* no more input? */
|
||||
return -1;
|
||||
lua_pushliteral(L, "\n"); /* add a new line... */
|
||||
lua_insert(L, -2); /* ...between the two lines */
|
||||
lua_concat(L, 3); /* join them */
|
||||
}
|
||||
lua_saveline(L, 1);
|
||||
lua_remove(L, 1); /* remove line */
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static void dotty (lua_State *L) {
|
||||
int status;
|
||||
const char *oldprogname = progname;
|
||||
progname = NULL;
|
||||
while ((status = loadline(L)) != -1) {
|
||||
if (status == 0) status = docall(L, 0, 0);
|
||||
report(L, status);
|
||||
if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
|
||||
lua_getglobal(L, "print");
|
||||
lua_insert(L, 1);
|
||||
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
|
||||
l_message(progname, lua_pushfstring(L,
|
||||
"error calling " LUA_QL("print") " (%s)",
|
||||
lua_tostring(L, -1)));
|
||||
}
|
||||
}
|
||||
lua_settop(L, 0); /* clear stack */
|
||||
|
||||
#if defined(LUA_USE_STDIO)
|
||||
c_fputs("\n", c_stdout);
|
||||
c_fflush(c_stdout);
|
||||
#else
|
||||
luai_writeline();
|
||||
#endif
|
||||
|
||||
progname = oldprogname;
|
||||
}
|
||||
|
||||
|
||||
static int handle_script (lua_State *L, char **argv, int n) {
|
||||
int status;
|
||||
const char *fname;
|
||||
int narg = getargs(L, argv, n); /* collect arguments */
|
||||
lua_setglobal(L, "arg");
|
||||
fname = argv[n];
|
||||
if (c_strcmp(fname, "-") == 0 && c_strcmp(argv[n-1], "--") != 0)
|
||||
fname = NULL; /* stdin */
|
||||
status = luaL_loadfile(L, fname);
|
||||
lua_insert(L, -(narg+1));
|
||||
if (status == 0)
|
||||
status = docall(L, narg, 0);
|
||||
else
|
||||
lua_pop(L, narg);
|
||||
return report(L, status);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check that argument has no extra characters at the end */
|
||||
#define notail(x) {if ((x)[2] != '\0') return -1;}
|
||||
|
@ -368,11 +241,7 @@ static int handle_luainit (lua_State *L) {
|
|||
const char *init = c_getenv(LUA_INIT);
|
||||
if (init == NULL) return 0; /* status OK */
|
||||
else if (init[0] == '@')
|
||||
#if 0
|
||||
return dofile(L, init+1);
|
||||
#else
|
||||
return dofsfile(L, init+1);
|
||||
#endif
|
||||
else
|
||||
return dostring(L, init, "=" LUA_INIT);
|
||||
}
|
||||
|
@ -397,34 +266,13 @@ static int pmain (lua_State *L) {
|
|||
lua_gc(L, LUA_GCRESTART, 0);
|
||||
print_version(L);
|
||||
s->status = handle_luainit(L);
|
||||
#if 0
|
||||
if (s->status != 0) return 0;
|
||||
#endif
|
||||
script = collectargs(argv, &has_i, &has_v, &has_e);
|
||||
if (script < 0) { /* invalid args? */
|
||||
#if 0
|
||||
print_usage();
|
||||
#endif
|
||||
s->status = 1;
|
||||
return 0;
|
||||
}
|
||||
// if (has_v) print_version();
|
||||
s->status = runargs(L, argv, (script > 0) ? script : s->argc);
|
||||
if (s->status != 0) return 0;
|
||||
#if 0
|
||||
if (script)
|
||||
s->status = handle_script(L, argv, script);
|
||||
if (s->status != 0) return 0;
|
||||
if (has_i)
|
||||
dotty(L);
|
||||
else if (script == 0 && !has_e && !has_v) {
|
||||
if (lua_stdin_is_tty()) {
|
||||
print_version();
|
||||
dotty(L);
|
||||
}
|
||||
else dofile(L, NULL); /* executes stdin as a file */
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -439,6 +287,12 @@ int lua_main (int argc, char **argv) {
|
|||
#endif
|
||||
int status;
|
||||
struct Smain s;
|
||||
|
||||
#if defined(NODE_DEBUG) && defined(DEVELOPMENT_USE_GDB) && BREAK_ON_STARTUP_PIN > 0
|
||||
platform_gpio_mode( BREAK_ON_STARTUP_PIN, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP );
|
||||
lua_assert(platform_gpio_read(BREAK_ON_STARTUP_PIN)); // Break if pin pulled low
|
||||
#endif
|
||||
|
||||
lua_State *L = lua_open(); /* create state */
|
||||
if (L == NULL) {
|
||||
l_message(argv[0], "cannot create state: not enough memory");
|
||||
|
@ -446,7 +300,9 @@ int lua_main (int argc, char **argv) {
|
|||
}
|
||||
s.argc = argc;
|
||||
s.argv = argv;
|
||||
|
||||
status = lua_cpcall(L, &pmain, &s);
|
||||
|
||||
report(L, status);
|
||||
|
||||
gLoad.L = L;
|
||||
|
@ -468,11 +324,8 @@ int lua_main (int argc, char **argv) {
|
|||
|
||||
void lua_handle_input (bool force)
|
||||
{
|
||||
while (gLoad.L && (force || readline (&gLoad)))
|
||||
{
|
||||
if (gLoad.L && (force || readline (&gLoad)))
|
||||
dojob (&gLoad);
|
||||
force = false;
|
||||
}
|
||||
}
|
||||
|
||||
void donejob(lua_Load *load){
|
||||
|
@ -602,12 +455,11 @@ static bool readline(lua_Load *load){
|
|||
{
|
||||
/* Get a empty line, then go to get a new line */
|
||||
c_puts(load->prmt);
|
||||
continue;
|
||||
} else {
|
||||
load->done = 1;
|
||||
need_dojob = true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* other control character or not an acsii character */
|
||||
|
|
|
@ -173,7 +173,6 @@ LUA_API void (lua_pushnil) (lua_State *L);
|
|||
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
|
||||
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
|
||||
LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
|
||||
LUA_API void (lua_pushrolstring) (lua_State *L, const char *s, size_t l);
|
||||
LUA_API void (lua_pushstring) (lua_State *L, const char *s);
|
||||
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
|
||||
va_list argp);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#define c_freopen freopen
|
||||
#define c_getc getc
|
||||
#define c_getenv getenv
|
||||
#define c_malloc malloc
|
||||
#define c_memcmp memcmp
|
||||
#define c_memcpy memcpy
|
||||
#define c_printf printf
|
||||
|
|
|
@ -7,30 +7,29 @@
|
|||
.NOTPARALLEL:
|
||||
|
||||
CCFLAGS:= -I.. -I../../include -I../../../include -I ../../libc
|
||||
LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm
|
||||
LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm -Wl,-Map=mapfile
|
||||
|
||||
CCFLAGS += -Wall
|
||||
|
||||
DEFINES += -DLUA_CROSS_COMPILER
|
||||
DEFINES += -DLUA_CROSS_COMPILER -DLUA_OPTIMIZE_MEMORY=2
|
||||
|
||||
TARGET = host
|
||||
|
||||
ifeq ($(FLAVOR),release)
|
||||
ifeq ($(FLAVOR),debug)
|
||||
CCFLAGS += -O0 -g
|
||||
TARGET_LDFLAGS += -O0 -g
|
||||
else
|
||||
FLAVOR = release
|
||||
CCFLAGS += -O2
|
||||
TARGET_LDFLAGS += -O2
|
||||
else
|
||||
FLAVOR = debug
|
||||
CCFLAGS += -O2 -g
|
||||
TARGET_LDFLAGS += -O2 -g
|
||||
endif
|
||||
|
||||
LUACSRC := luac.c lflashimg.c loslib.c print.c
|
||||
LUASRC := lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c \
|
||||
ldebug.c ldo.c ldump.c lfunc.c lgc.c \
|
||||
llex.c lmathlib.c lmem.c loadlib.c lobject.c \
|
||||
lopcodes.c lparser.c lrotable.c lstate.c lstring.c \
|
||||
lstrlib.c ltable.c ltablib.c ltm.c lundump.c \
|
||||
lvm.c lzio.c
|
||||
LUACSRC := luac.c lflashimg.c liolib.c loslib.c print.c
|
||||
LUASRC := lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c \
|
||||
ldo.c ldump.c lfunc.c lgc.c linit.c llex.c \
|
||||
lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c lparser.c \
|
||||
lrotable.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c \
|
||||
ltm.c lundump.c lvm.c lzio.c
|
||||
LIBCSRC := c_stdlib.c
|
||||
|
||||
#
|
||||
|
@ -83,6 +82,3 @@ $(ODIR)/%.d: %.c
|
|||
$(CC) -M $(CFLAGS) $< > $@.$$$$; \
|
||||
sed 's,\($*\.o\)[ :]*,$(ODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \
|
||||
rm -f $@.$$$$
|
||||
|
||||
# echo 's,\($*\.o\)[ :]*,$(ODIR)/\1 $@ : ,g'; \
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ static void createROstrt(lua_State *L, FlashHeader *fh) {
|
|||
toFlashAddr(L, *e, fts); // add reference to TS to lookup vector
|
||||
toFlashAddr(L, fts->next, last); // and chain to previous entry if any
|
||||
fts->tt = LUA_TSTRING; // Set as String
|
||||
fts->marked = bitmask(FIXEDBIT); // Fixed with no Whitebits set
|
||||
fts->marked = bitmask(LFSBIT); // LFS string with no Whitebits set
|
||||
fts->hash = hash; // add hash
|
||||
fts->len = len; // and length
|
||||
memcpy(flashAlloc(L, ALIGN(len+1)), p, ALIGN(len+1)); // copy string
|
||||
|
@ -262,14 +262,21 @@ static void *resolveTString(lua_State* L, TString *s) {
|
|||
* src Source of record
|
||||
* returns Address of destination record
|
||||
*/
|
||||
#define TARGET_TV_SIZE (2*sizeof(lua_Number))
|
||||
static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
|
||||
/* ToS is the string address mapping table */
|
||||
if (n == 0)
|
||||
return NULL;
|
||||
int i;
|
||||
int i, recsize;
|
||||
void *newts;
|
||||
// A bit of a botch because fmt is either "V" or a string of WORDSIZE specifiers */
|
||||
int recsize = fmt[0]=='V' ? 16 : WORDSIZE * strlen(fmt);
|
||||
/* A bit of a botch because fmt is either "V" or a string of WORDSIZE specifiers */
|
||||
/* The size 8 for integer builds and 16 for float ones on both architectures */
|
||||
if (fmt[0]=='V') {
|
||||
lua_assert(fmt[1] == 0); /* V formats must be singetons */
|
||||
recsize = TARGET_TV_SIZE;
|
||||
} else {
|
||||
recsize = WORDSIZE * strlen(fmt);
|
||||
}
|
||||
|
||||
uint *d = cast(uint *, flashAlloc(L, n * recsize));
|
||||
uint *dest = d;
|
||||
|
@ -284,8 +291,8 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
|
|||
switch (*p++) {
|
||||
case 'A':
|
||||
toFlashAddr(L, *d, *cast(void**, s));
|
||||
d++;
|
||||
s += FLASH_WORDS(size_t);
|
||||
d++;
|
||||
break;
|
||||
case 'I':
|
||||
*d++ = *s++;
|
||||
|
@ -293,22 +300,23 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
|
|||
case 'S':
|
||||
newts = resolveTString(L, *cast(TString **, s));
|
||||
toFlashAddr(L, *d, newts);
|
||||
d++;
|
||||
s += FLASH_WORDS(size_t);
|
||||
d++;
|
||||
break;
|
||||
case 'V':
|
||||
memcpy(d, s, sizeof(TValue));
|
||||
/* This code has to work for both Integer and Float build variants */
|
||||
memset(d, 0, TARGET_TV_SIZE);
|
||||
TValue *sv = cast(TValue *, s);
|
||||
if (ttisstring(sv)) {
|
||||
newts = resolveTString(L, rawtsvalue(sv));
|
||||
toFlashAddr(L, *d, newts);
|
||||
d[1] = 0;
|
||||
} else {
|
||||
toFlashAddr(L, *d, resolveTString(L, rawtsvalue(sv)));
|
||||
} else { /* non-collectable types all of size lua_Number */
|
||||
lua_assert(!iscollectable(sv));
|
||||
*cast(lua_Number*,d) = *cast(lua_Number*,s);
|
||||
}
|
||||
d += FLASH_WORDS(TValue);
|
||||
*cast(int *,cast(lua_Number*,d)+1) = ttype(sv);
|
||||
s += FLASH_WORDS(TValue);
|
||||
break;
|
||||
d += TARGET_TV_SIZE/WORDSIZE;
|
||||
break;
|
||||
default:
|
||||
lua_assert (0);
|
||||
}
|
||||
|
@ -334,7 +342,7 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
|
|||
memcpy (&f, orig, sizeof(Proto));
|
||||
f.gclist = NULL;
|
||||
f.next = NULL;
|
||||
l_setbit(f.marked, FIXEDBIT);
|
||||
l_setbit(f.marked, LFSBIT); /* OK to set the LFSBIT on a stack-cloned copy */
|
||||
|
||||
if (f.sizep) { /* clone included Protos */
|
||||
Proto **p = luaM_newvector(L, f.sizep, Proto *);
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
*/
|
||||
|
||||
|
||||
// #include "c_errno.h"
|
||||
#include "c_stdio.h"
|
||||
#include "c_stdlib.h"
|
||||
#include "c_string.h"
|
||||
#include "vfs.h"
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define liolib_c
|
||||
#define LUA_LIB
|
||||
#define LUA_OPTIMIZE_MEMORY 2
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
|
@ -20,26 +20,21 @@
|
|||
#include "lualib.h"
|
||||
#include "lrotable.h"
|
||||
|
||||
|
||||
#define IO_INPUT 1
|
||||
#define IO_OUTPUT 2
|
||||
#define IO_STDERR 0
|
||||
|
||||
#if LUA_OPTIMIZE_MEMORY != 2
|
||||
#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_ENVIRONINDEX, f)
|
||||
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_ENVIRONINDEX, f)
|
||||
#else
|
||||
#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_REGISTRYINDEX, liolib_keys[f])
|
||||
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[f])
|
||||
#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
|
||||
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
|
||||
|
||||
/* "Pseudo-random" keys for the registry */
|
||||
static const int liolib_keys[] = {(int)&luaL_callmeta, (int)&luaL_typerror, (int)&luaL_argerror};
|
||||
#endif
|
||||
static const size_t liolib_keys[] = {(size_t)&luaL_callmeta, (size_t)&luaL_typerror, (size_t)&luaL_argerror};
|
||||
|
||||
static const char *const fnames[] = {"input", "output"};
|
||||
|
||||
|
||||
static int pushresult (lua_State *L, int i, const char *filename) {
|
||||
int en = vfs_ferrno(0); /* calls to Lua API may change this value */
|
||||
int en = errno; /* calls to Lua API may change this value */
|
||||
if (i) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
|
@ -47,9 +42,9 @@ static int pushresult (lua_State *L, int i, const char *filename) {
|
|||
else {
|
||||
lua_pushnil(L);
|
||||
if (filename)
|
||||
lua_pushfstring(L, "%s: err(%d)", filename, en);
|
||||
lua_pushfstring(L, "%s: %s", filename, strerror(en));
|
||||
else
|
||||
lua_pushfstring(L, "err(%d)", en);
|
||||
lua_pushfstring(L, "%s", strerror(en));
|
||||
lua_pushinteger(L, en);
|
||||
return 3;
|
||||
}
|
||||
|
@ -57,12 +52,12 @@ static int pushresult (lua_State *L, int i, const char *filename) {
|
|||
|
||||
|
||||
static void fileerror (lua_State *L, int arg, const char *filename) {
|
||||
lua_pushfstring(L, "%s: err(%d)", filename, vfs_ferrno(0));
|
||||
lua_pushfstring(L, "%s: %s", filename, strerror(errno));
|
||||
luaL_argerror(L, arg, lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
|
||||
#define tofilep(L) ((int *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
|
||||
#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
|
||||
|
||||
|
||||
static int io_type (lua_State *L) {
|
||||
|
@ -72,7 +67,7 @@ static int io_type (lua_State *L) {
|
|||
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
|
||||
if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
|
||||
lua_pushnil(L); /* not a file */
|
||||
else if (*((int *)ud) < FS_OPEN_OK)
|
||||
else if (*((FILE **)ud) == NULL)
|
||||
lua_pushliteral(L, "closed file");
|
||||
else
|
||||
lua_pushliteral(L, "file");
|
||||
|
@ -80,9 +75,9 @@ static int io_type (lua_State *L) {
|
|||
}
|
||||
|
||||
|
||||
static int tofile (lua_State *L) {
|
||||
int *f = tofilep(L);
|
||||
if (*f < FS_OPEN_OK)
|
||||
static FILE *tofile (lua_State *L) {
|
||||
FILE **f = tofilep(L);
|
||||
if (*f == NULL)
|
||||
luaL_error(L, "attempt to use a closed file");
|
||||
return *f;
|
||||
}
|
||||
|
@ -94,91 +89,52 @@ static int tofile (lua_State *L) {
|
|||
** before opening the actual file; so, if there is a memory error, the
|
||||
** file is not left opened.
|
||||
*/
|
||||
static int *newfile (lua_State *L) {
|
||||
int *pf = (int *)lua_newuserdata(L, sizeof(int));
|
||||
*pf = FS_OPEN_OK - 1; /* file handle is currently `closed' */
|
||||
static FILE **newfile (lua_State *L) {
|
||||
FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
|
||||
*pf = NULL; /* file handle is currently `closed' */
|
||||
luaL_getmetatable(L, LUA_FILEHANDLE);
|
||||
lua_setmetatable(L, -2);
|
||||
return pf;
|
||||
}
|
||||
|
||||
|
||||
#if LUA_OPTIMIZE_MEMORY != 2
|
||||
/*
|
||||
** function to (not) close the standard files stdin, stdout, and stderr
|
||||
*/
|
||||
static int io_noclose (lua_State *L) {
|
||||
lua_pushnil(L);
|
||||
lua_pushliteral(L, "cannot close standard file");
|
||||
return 2;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** function to close 'popen' files
|
||||
*/
|
||||
static int io_pclose (lua_State *L) {
|
||||
int *p = tofilep(L);
|
||||
int ok = lua_pclose(L, *p);
|
||||
*p = FS_OPEN_OK - 1;
|
||||
return pushresult(L, ok, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** function to close regular files
|
||||
*/
|
||||
static int io_fclose (lua_State *L) {
|
||||
int *p = tofilep(L);
|
||||
int ok = (vfs_close(*p) == 0);
|
||||
*p = FS_OPEN_OK - 1;
|
||||
return pushresult(L, ok, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int aux_close (lua_State *L) {
|
||||
#if LUA_OPTIMIZE_MEMORY != 2
|
||||
lua_getfenv(L, 1);
|
||||
lua_getfield(L, -1, "__close");
|
||||
return (lua_tocfunction(L, -1))(L);
|
||||
#else
|
||||
int *p = tofilep(L);
|
||||
if(*p == c_stdin || *p == c_stdout || *p == c_stderr)
|
||||
FILE **p = tofilep(L);
|
||||
if(*p == stdin || *p == stdout || *p == stderr)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushliteral(L, "cannot close standard file");
|
||||
return 2;
|
||||
}
|
||||
int ok = (vfs_close(*p) == 0);
|
||||
*p = FS_OPEN_OK - 1;
|
||||
int ok = (fclose(*p) == 0);
|
||||
*p = NULL;
|
||||
return pushresult(L, ok, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int io_close (lua_State *L) {
|
||||
if (lua_isnone(L, 1))
|
||||
LUA_IO_GETFIELD(IO_OUTPUT);
|
||||
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
|
||||
tofile(L); /* make sure argument is a file */
|
||||
return aux_close(L);
|
||||
}
|
||||
|
||||
|
||||
static int io_gc (lua_State *L) {
|
||||
int f = *tofilep(L);
|
||||
FILE *f = *tofilep(L);
|
||||
/* ignore closed files */
|
||||
if (f != FS_OPEN_OK - 1)
|
||||
if (f != NULL)
|
||||
aux_close(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int io_tostring (lua_State *L) {
|
||||
int f = *tofilep(L);
|
||||
if (f == FS_OPEN_OK - 1)
|
||||
FILE *f = *tofilep(L);
|
||||
if (f == NULL)
|
||||
lua_pushliteral(L, "file (closed)");
|
||||
else
|
||||
lua_pushfstring(L, "file (%i)", f);
|
||||
lua_pushfstring(L, "file (%p)", f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -186,42 +142,19 @@ static int io_tostring (lua_State *L) {
|
|||
static int io_open (lua_State *L) {
|
||||
const char *filename = luaL_checkstring(L, 1);
|
||||
const char *mode = luaL_optstring(L, 2, "r");
|
||||
int *pf = newfile(L);
|
||||
*pf = vfs_open(filename, mode);
|
||||
return (*pf == FS_OPEN_OK - 1) ? pushresult(L, 0, filename) : 1;
|
||||
FILE **pf = newfile(L);
|
||||
*pf = fopen(filename, mode);
|
||||
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** this function has a separated environment, which defines the
|
||||
** correct __close for 'popen' files
|
||||
*/
|
||||
#if 0
|
||||
static int io_popen (lua_State *L) {
|
||||
const char *filename = luaL_checkstring(L, 1);
|
||||
const char *mode = luaL_optstring(L, 2, "r");
|
||||
int *pf = newfile(L);
|
||||
*pf = lua_popen(L, filename, fs_mode2flags(mode));
|
||||
return (*pf == FS_OPEN_OK - 1) ? pushresult(L, 0, filename) : 1;
|
||||
}
|
||||
|
||||
|
||||
static int io_tmpfile (lua_State *L) {
|
||||
int *pf = newfile(L);
|
||||
*pf = tmpfile();
|
||||
return (*pf == FS_OPEN_OK - 1) ? pushresult(L, 0, NULL) : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int getiofile (lua_State *L, int findex) {
|
||||
int *pf;
|
||||
LUA_IO_GETFIELD(findex);
|
||||
pf = (int *)lua_touserdata(L, -1);
|
||||
if (pf == NULL || *pf == FS_OPEN_OK - 1){
|
||||
luaL_error(L, "default %s file is closed", fnames[findex - 1]);
|
||||
return FS_OPEN_OK - 1;
|
||||
}
|
||||
return *pf;
|
||||
static FILE *getiofile (lua_State *L, int findex) {
|
||||
FILE *f;
|
||||
lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
|
||||
f = *(FILE **)lua_touserdata(L, -1);
|
||||
if (f == NULL)
|
||||
luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -229,19 +162,19 @@ static int g_iofile (lua_State *L, int f, const char *mode) {
|
|||
if (!lua_isnoneornil(L, 1)) {
|
||||
const char *filename = lua_tostring(L, 1);
|
||||
if (filename) {
|
||||
int *pf = newfile(L);
|
||||
*pf = vfs_open(filename, mode);
|
||||
if (*pf == FS_OPEN_OK - 1)
|
||||
FILE **pf = newfile(L);
|
||||
*pf = fopen(filename, mode);
|
||||
if (*pf == NULL)
|
||||
fileerror(L, 1, filename);
|
||||
}
|
||||
else {
|
||||
tofile(L); /* check that it's a valid file handle */
|
||||
lua_pushvalue(L, 1);
|
||||
}
|
||||
LUA_IO_SETFIELD(f);
|
||||
lua_rawseti(L, LUA_ENVIRONINDEX, f);
|
||||
}
|
||||
/* return current value */
|
||||
LUA_IO_GETFIELD(f);
|
||||
lua_rawgeti(L, LUA_ENVIRONINDEX, f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -276,14 +209,14 @@ static int f_lines (lua_State *L) {
|
|||
static int io_lines (lua_State *L) {
|
||||
if (lua_isnoneornil(L, 1)) { /* no arguments? */
|
||||
/* will iterate over default input */
|
||||
LUA_IO_GETFIELD(IO_INPUT);
|
||||
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
|
||||
return f_lines(L);
|
||||
}
|
||||
else {
|
||||
const char *filename = luaL_checkstring(L, 1);
|
||||
int *pf = newfile(L);
|
||||
*pf = vfs_open(filename, "r");
|
||||
if (*pf == FS_OPEN_OK - 1)
|
||||
FILE **pf = newfile(L);
|
||||
*pf = fopen(filename, "r");
|
||||
if (*pf == NULL)
|
||||
fileerror(L, 1, filename);
|
||||
aux_lines(L, lua_gettop(L), 1);
|
||||
return 1;
|
||||
|
@ -297,10 +230,10 @@ static int io_lines (lua_State *L) {
|
|||
** =======================================================
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static int read_number (lua_State *L, int f) {
|
||||
|
||||
static int read_number (lua_State *L, FILE *f) {
|
||||
lua_Number d;
|
||||
if (fs_scanf(f, LUA_NUMBER_SCAN, &d) == 1) {
|
||||
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
|
||||
lua_pushnumber(L, d);
|
||||
return 1;
|
||||
}
|
||||
|
@ -309,27 +242,27 @@ static int read_number (lua_State *L, int f) {
|
|||
return 0; /* read fails */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_eof (lua_State *L, int f) {
|
||||
int c = vfs_getc(f);
|
||||
vfs_ungetc(c, f);
|
||||
|
||||
static int test_eof (lua_State *L, FILE *f) {
|
||||
int c = getc(f);
|
||||
ungetc(c, f);
|
||||
lua_pushlstring(L, NULL, 0);
|
||||
return (c != EOF);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int read_line (lua_State *L, int f) {
|
||||
|
||||
static int read_line (lua_State *L, FILE *f) {
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
for (;;) {
|
||||
size_t l;
|
||||
char *p = luaL_prepbuffer(&b);
|
||||
if (fs_gets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
|
||||
if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
|
||||
luaL_pushresult(&b); /* close buffer */
|
||||
return (lua_objlen(L, -1) > 0); /* check whether read something */
|
||||
}
|
||||
l = c_strlen(p);
|
||||
l = strlen(p);
|
||||
if (l == 0 || p[l-1] != '\n')
|
||||
luaL_addsize(&b, l);
|
||||
else {
|
||||
|
@ -339,27 +272,9 @@ static int read_line (lua_State *L, int f) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static int read_line (lua_State *L, int f) {
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
signed char c;
|
||||
do {
|
||||
c = (signed char)vfs_getc(f);
|
||||
if (c==EOF) {
|
||||
break;
|
||||
}
|
||||
if (c != '\n') {
|
||||
luaL_addchar(&b, c);
|
||||
}
|
||||
} while (c != '\n');
|
||||
|
||||
luaL_pushresult(&b); /* close buffer */
|
||||
return (lua_objlen(L, -1) > 0); /* check whether read something */
|
||||
}
|
||||
#endif
|
||||
|
||||
static int read_chars (lua_State *L, int f, size_t n) {
|
||||
static int read_chars (lua_State *L, FILE *f, size_t n) {
|
||||
size_t rlen; /* how much to read */
|
||||
size_t nr; /* number of chars actually read */
|
||||
luaL_Buffer b;
|
||||
|
@ -368,7 +283,7 @@ static int read_chars (lua_State *L, int f, size_t n) {
|
|||
do {
|
||||
char *p = luaL_prepbuffer(&b);
|
||||
if (rlen > n) rlen = n; /* cannot read more than asked */
|
||||
nr = vfs_read(f, p, rlen);
|
||||
nr = fread(p, sizeof(char), rlen, f);
|
||||
luaL_addsize(&b, nr);
|
||||
n -= nr; /* still have to read `n' chars */
|
||||
} while (n > 0 && nr == rlen); /* until end of count or eof */
|
||||
|
@ -377,11 +292,11 @@ static int read_chars (lua_State *L, int f, size_t n) {
|
|||
}
|
||||
|
||||
|
||||
static int g_read (lua_State *L, int f, int first) {
|
||||
static int g_read (lua_State *L, FILE *f, int first) {
|
||||
int nargs = lua_gettop(L) - 1;
|
||||
int success;
|
||||
int n;
|
||||
//vfs_clearerr(f);
|
||||
clearerr(f);
|
||||
if (nargs == 0) { /* no arguments? */
|
||||
success = read_line(L, f);
|
||||
n = first+1; /* to return 1 result */
|
||||
|
@ -398,11 +313,9 @@ static int g_read (lua_State *L, int f, int first) {
|
|||
const char *p = lua_tostring(L, n);
|
||||
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
|
||||
switch (p[1]) {
|
||||
#if 0
|
||||
case 'n': /* number */
|
||||
success = read_number(L, f);
|
||||
break;
|
||||
#endif
|
||||
case 'l': /* line */
|
||||
success = read_line(L, f);
|
||||
break;
|
||||
|
@ -416,7 +329,7 @@ static int g_read (lua_State *L, int f, int first) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (vfs_ferrno(f))
|
||||
if (ferror(f))
|
||||
return pushresult(L, 0, NULL);
|
||||
if (!success) {
|
||||
lua_pop(L, 1); /* remove last result */
|
||||
|
@ -437,15 +350,13 @@ static int f_read (lua_State *L) {
|
|||
|
||||
|
||||
static int io_readline (lua_State *L) {
|
||||
int *pf = (int *)lua_touserdata(L, lua_upvalueindex(1));
|
||||
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
|
||||
int sucess;
|
||||
if (pf == NULL || *pf == FS_OPEN_OK - 1){ /* file is already closed? */
|
||||
if (f == NULL) /* file is already closed? */
|
||||
luaL_error(L, "file is already closed");
|
||||
return 0;
|
||||
}
|
||||
sucess = read_line(L, *pf);
|
||||
if (vfs_ferrno(*pf))
|
||||
return luaL_error(L, "err(%d)", vfs_ferrno(*pf));
|
||||
sucess = read_line(L, f);
|
||||
if (ferror(f))
|
||||
return luaL_error(L, "%s", strerror(errno));
|
||||
if (sucess) return 1;
|
||||
else { /* EOF */
|
||||
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
|
||||
|
@ -460,22 +371,19 @@ static int io_readline (lua_State *L) {
|
|||
/* }====================================================== */
|
||||
|
||||
|
||||
static int g_write (lua_State *L, int f, int arg) {
|
||||
static int g_write (lua_State *L, FILE *f, int arg) {
|
||||
int nargs = lua_gettop(L) - 1;
|
||||
int status = 1;
|
||||
for (; nargs--; arg++) {
|
||||
#if 0
|
||||
if (lua_type(L, arg) == LUA_TNUMBER) {
|
||||
/* optimization: could be done exactly as for strings */
|
||||
status = status &&
|
||||
fs_printf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
|
||||
fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
else {
|
||||
size_t l;
|
||||
const char *s = luaL_checklstring(L, arg, &l);
|
||||
status = status && (vfs_write(f, s, l) == l);
|
||||
status = status && (fwrite(s, sizeof(char), l, f) == l);
|
||||
}
|
||||
}
|
||||
return pushresult(L, status, NULL);
|
||||
|
@ -493,159 +401,103 @@ static int f_write (lua_State *L) {
|
|||
|
||||
|
||||
static int f_seek (lua_State *L) {
|
||||
static const int mode[] = {VFS_SEEK_SET, VFS_SEEK_CUR, VFS_SEEK_END};
|
||||
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
static const char *const modenames[] = {"set", "cur", "end", NULL};
|
||||
int f = tofile(L);
|
||||
FILE *f = tofile(L);
|
||||
int op = luaL_checkoption(L, 2, "cur", modenames);
|
||||
long offset = luaL_optlong(L, 3, 0);
|
||||
op = vfs_lseek(f, offset, mode[op]);
|
||||
op = fseek(f, offset, mode[op]);
|
||||
if (op)
|
||||
return pushresult(L, 0, NULL); /* error */
|
||||
else {
|
||||
lua_pushinteger(L, vfs_tell(f));
|
||||
lua_pushinteger(L, ftell(f));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static int f_setvbuf (lua_State *L) {
|
||||
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
|
||||
static const char *const modenames[] = {"no", "full", "line", NULL};
|
||||
int f = tofile(L);
|
||||
FILE *f = tofile(L);
|
||||
int op = luaL_checkoption(L, 2, NULL, modenames);
|
||||
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
|
||||
int res = setvbuf(f, NULL, mode[op], sz);
|
||||
return pushresult(L, res == 0, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int io_flush (lua_State *L) {
|
||||
return pushresult(L, vfs_flush(getiofile(L, IO_OUTPUT)) == 0, NULL);
|
||||
return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int f_flush (lua_State *L) {
|
||||
return pushresult(L, vfs_flush(tofile(L)) == 0, NULL);
|
||||
return pushresult(L, fflush(tofile(L)) == 0, NULL);
|
||||
}
|
||||
|
||||
#undef MIN_OPT_LEVEL
|
||||
#define MIN_OPT_LEVEL 2
|
||||
#include "lrodefs.h"
|
||||
#if LUA_OPTIMIZE_MEMORY == 2
|
||||
const LUA_REG_TYPE iolib_funcs[] = {
|
||||
#else
|
||||
const LUA_REG_TYPE iolib[] = {
|
||||
#endif
|
||||
{LSTRKEY("close"), LFUNCVAL(io_close)},
|
||||
{LSTRKEY("flush"), LFUNCVAL(io_flush)},
|
||||
{LSTRKEY("input"), LFUNCVAL(io_input)},
|
||||
{LSTRKEY("lines"), LFUNCVAL(io_lines)},
|
||||
{LSTRKEY("open"), LFUNCVAL(io_open)},
|
||||
{LSTRKEY("output"), LFUNCVAL(io_output)},
|
||||
// {LSTRKEY("popen"), LFUNCVAL(io_popen)},
|
||||
{LSTRKEY("read"), LFUNCVAL(io_read)},
|
||||
// {LSTRKEY("tmpfile"), LFUNCVAL(io_tmpfile)},
|
||||
{LSTRKEY("type"), LFUNCVAL(io_type)},
|
||||
{LSTRKEY("write"), LFUNCVAL(io_write)},
|
||||
{LSTRKEY("close"), LFUNCVAL(io_close)},
|
||||
{LSTRKEY("flush"), LFUNCVAL(io_flush)},
|
||||
{LSTRKEY("input"), LFUNCVAL(io_input)},
|
||||
{LSTRKEY("lines"), LFUNCVAL(io_lines)},
|
||||
{LSTRKEY("open"), LFUNCVAL(io_open)},
|
||||
{LSTRKEY("output"), LFUNCVAL(io_output)},
|
||||
{LSTRKEY("read"), LFUNCVAL(io_read)},
|
||||
{LSTRKEY("type"), LFUNCVAL(io_type)},
|
||||
{LSTRKEY("write"), LFUNCVAL(io_write)},
|
||||
{LSTRKEY("__index"), LROVAL(iolib_funcs)},
|
||||
{LNILKEY, LNILVAL}
|
||||
};
|
||||
|
||||
#if LUA_OPTIMIZE_MEMORY == 2
|
||||
static int luaL_index(lua_State *L)
|
||||
/* Note that IO objects use a RAM metatable created to allow extensibility */
|
||||
|
||||
static int io_index(lua_State *L)
|
||||
{
|
||||
return luaR_findfunction(L, iolib_funcs);
|
||||
}
|
||||
|
||||
const luaL_Reg iolib[] = {
|
||||
{"__index", luaL_index},
|
||||
{"__index", io_index},
|
||||
{NULL, NULL}
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef MIN_OPT_LEVEL
|
||||
#define MIN_OPT_LEVEL 1
|
||||
#include "lrodefs.h"
|
||||
const LUA_REG_TYPE flib[] = {
|
||||
{LSTRKEY("close"), LFUNCVAL(io_close)},
|
||||
{LSTRKEY("flush"), LFUNCVAL(f_flush)},
|
||||
{LSTRKEY("lines"), LFUNCVAL(f_lines)},
|
||||
{LSTRKEY("read"), LFUNCVAL(f_read)},
|
||||
{LSTRKEY("seek"), LFUNCVAL(f_seek)},
|
||||
// {LSTRKEY("setvbuf"), LFUNCVAL(f_setvbuf)},
|
||||
{LSTRKEY("write"), LFUNCVAL(f_write)},
|
||||
{LSTRKEY("__gc"), LFUNCVAL(io_gc)},
|
||||
{LSTRKEY("close"), LFUNCVAL(io_close)},
|
||||
{LSTRKEY("flush"), LFUNCVAL(f_flush)},
|
||||
{LSTRKEY("lines"), LFUNCVAL(f_lines)},
|
||||
{LSTRKEY("read"), LFUNCVAL(f_read)},
|
||||
{LSTRKEY("seek"), LFUNCVAL(f_seek)},
|
||||
{LSTRKEY("setvbuf"), LFUNCVAL(f_setvbuf)},
|
||||
{LSTRKEY("write"), LFUNCVAL(f_write)},
|
||||
{LSTRKEY("__gc"), LFUNCVAL(io_gc)},
|
||||
{LSTRKEY("__tostring"), LFUNCVAL(io_tostring)},
|
||||
#if LUA_OPTIMIZE_MEMORY > 0
|
||||
{LSTRKEY("__index"), LROVAL(flib)},
|
||||
#endif
|
||||
{LSTRKEY("__index"), LROVAL(flib)},
|
||||
{LNILKEY, LNILVAL}
|
||||
};
|
||||
|
||||
static void createmeta (lua_State *L) {
|
||||
#if LUA_OPTIMIZE_MEMORY == 0
|
||||
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
|
||||
lua_pushvalue(L, -1); /* push metatable */
|
||||
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
|
||||
luaL_register(L, NULL, flib); /* file methods */
|
||||
#else
|
||||
luaL_rometatable(L, LUA_FILEHANDLE, (void*)flib); /* create metatable for file handles */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void createstdfile (lua_State *L, int f, int k, const char *fname) {
|
||||
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
|
||||
*newfile(L) = f;
|
||||
#if LUA_OPTIMIZE_MEMORY != 2
|
||||
if (k > 0) {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawseti(L, LUA_ENVIRONINDEX, k);
|
||||
}
|
||||
lua_pushvalue(L, -2); /* copy environment */
|
||||
lua_setfenv(L, -2); /* set it */
|
||||
lua_setfield(L, -3, fname);
|
||||
#else
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[k]);
|
||||
lua_setfield(L, -2, fname);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LUA_OPTIMIZE_MEMORY != 2
|
||||
static void newfenv (lua_State *L, lua_CFunction cls) {
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_pushcfunction(L, cls);
|
||||
lua_setfield(L, -2, "__close");
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, (int)(liolib_keys[k]));
|
||||
lua_setfield(L, -2, fname);
|
||||
}
|
||||
#endif
|
||||
|
||||
LUALIB_API int luaopen_io (lua_State *L) {
|
||||
createmeta(L);
|
||||
#if LUA_OPTIMIZE_MEMORY != 2
|
||||
/* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
|
||||
newfenv(L, io_fclose);
|
||||
lua_replace(L, LUA_ENVIRONINDEX);
|
||||
/* open library */
|
||||
luaL_register(L, LUA_IOLIBNAME, iolib);
|
||||
newfenv(L, io_noclose); /* close function for default files */
|
||||
#else
|
||||
luaL_rometatable(L, LUA_FILEHANDLE, (void*)flib); /* create metatable for file handles */
|
||||
luaL_register_light(L, LUA_IOLIBNAME, iolib);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setmetatable(L, -2);
|
||||
#endif
|
||||
#if 0
|
||||
/* create (and set) default files */
|
||||
createstdfile(L, c_stdin, IO_INPUT, "stdin");
|
||||
createstdfile(L, c_stdout, IO_OUTPUT, "stdout");
|
||||
createstdfile(L, c_stderr, IO_STDERR, "stderr");
|
||||
|
||||
#if LUA_OPTIMIZE_MEMORY != 2
|
||||
lua_pop(L, 1); /* pop environment for default files */
|
||||
lua_getfield(L, -1, "popen");
|
||||
newfenv(L, io_pclose); /* create environment for 'popen' */
|
||||
lua_setfenv(L, -2); /* set fenv for 'popen' */
|
||||
lua_pop(L, 1); /* pop 'popen' */
|
||||
#endif
|
||||
#endif
|
||||
createstdfile(L, stdin, IO_INPUT, "stdin");
|
||||
createstdfile(L, stdout, IO_OUTPUT, "stdout");
|
||||
createstdfile(L, stderr, 0, "stderr");
|
||||
return 1;
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include "lualib.h"
|
||||
#include "ldo.h"
|
||||
#include "lfunc.h"
|
||||
#include "lmem.h"
|
||||
|
@ -37,6 +37,7 @@ static int flash=0; /* output flash image */
|
|||
static int lookup=0; /* output lookup-style master combination header */
|
||||
static char Output[]={ OUTPUT }; /* default output file name */
|
||||
static const char* output=Output; /* actual output file name */
|
||||
static const char* execute; /* executed a Lua file */
|
||||
static const char* progname=PROGNAME; /* actual program name */
|
||||
static DumpTargetInfo target;
|
||||
|
||||
|
@ -66,6 +67,7 @@ static void usage(const char* message)
|
|||
" - process stdin\n"
|
||||
" -l list\n"
|
||||
" -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
|
||||
" -e name execute a lua source file\n"
|
||||
" -f output a flash image file\n"
|
||||
" -i generate lookup combination master (default with option -f)\n"
|
||||
" -p parse only\n"
|
||||
|
@ -93,8 +95,14 @@ static int doargs(int argc, char* argv[])
|
|||
if (version) ++version;
|
||||
break;
|
||||
}
|
||||
else if (IS("-")) /* end of options; use stdin */
|
||||
else if (IS("-")) /* end of options; use stdin */
|
||||
break;
|
||||
else if (IS("-e")) /* execute a lua source file file */
|
||||
{
|
||||
execute=argv[++i];
|
||||
if (execute ==NULL || *execute==0 || *execute=='-' )
|
||||
usage(LUA_QL("-e") " needs argument");
|
||||
}
|
||||
else if (IS("-f")) /* Flash image file */
|
||||
{
|
||||
flash=1;
|
||||
|
@ -242,12 +250,25 @@ static int pmain(lua_State* L)
|
|||
const Proto* f;
|
||||
int i;
|
||||
if (!lua_checkstack(L,argc)) fatal("too many input files");
|
||||
if (execute)
|
||||
{
|
||||
if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
|
||||
luaL_openlibs(L);
|
||||
lua_pushstring(L, execute);
|
||||
if (lua_pcall(L, 1, 1, 0)) fatal(lua_tostring(L,-1));
|
||||
if (!lua_isfunction(L, -1))
|
||||
{
|
||||
lua_pop(L,1);
|
||||
if(argc == 0) return 0;
|
||||
execute = NULL;
|
||||
}
|
||||
}
|
||||
for (i=0; i<argc; i++)
|
||||
{
|
||||
const char* filename=IS("-") ? NULL : argv[i];
|
||||
if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
|
||||
}
|
||||
f=combine(L,argc,lookup);
|
||||
f=combine(L,argc + (execute ? 1: 0), lookup);
|
||||
if (listing) luaU_print(f,listing>1);
|
||||
if (dumping)
|
||||
{
|
||||
|
@ -286,7 +307,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
int i=doargs(argc,argv);
|
||||
argc-=i; argv+=i;
|
||||
if (argc<=0) usage("no input files given");
|
||||
if (argc<=0 && execute==0) usage("no input files given");
|
||||
L=lua_open();
|
||||
if (L==NULL) fatal("not enough memory for state");
|
||||
s.argc=argc;
|
||||
|
|
|
@ -167,7 +167,7 @@
|
|||
#define LUA_INTEGER ptrdiff_t
|
||||
#else
|
||||
#if !defined LUA_INTEGRAL_LONGLONG
|
||||
#define LUA_INTEGER long
|
||||
#define LUA_INTEGER int
|
||||
#else
|
||||
#define LUA_INTEGER long long
|
||||
#endif // #if !defined LUA_INTEGRAL_LONGLONG
|
||||
|
@ -487,7 +487,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
|
|||
/* 16-bit ints */
|
||||
#define LUAI_UINT32 unsigned long
|
||||
#define LUAI_INT32 long
|
||||
#define LUAI_MAXINT32 LONG_MAX
|
||||
#define LUAI_MAXINT32 INT_MAX
|
||||
#define LUAI_UMEM unsigned long
|
||||
#define LUAI_MEM long
|
||||
#endif
|
||||
|
@ -607,8 +607,8 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
|
|||
*/
|
||||
#if defined LUA_NUMBER_INTEGRAL
|
||||
#if !defined LUA_INTEGRAL_LONGLONG
|
||||
#define LUA_NUMBER_SCAN "%ld"
|
||||
#define LUA_NUMBER_FMT "%ld"
|
||||
#define LUA_NUMBER_SCAN "%d"
|
||||
#define LUA_NUMBER_FMT "%d"
|
||||
#else
|
||||
#define LUA_NUMBER_SCAN "%lld"
|
||||
#define LUA_NUMBER_FMT "%lld"
|
||||
|
@ -894,7 +894,7 @@ union luai_Cast { double l_d; long l_l; };
|
|||
/* If you define the next macro you'll get the ability to set rotables as
|
||||
metatables for tables/userdata/types (but the VM might run slower)
|
||||
*/
|
||||
#if (LUA_OPTIMIZE_MEMORY == 2) && !defined(LUA_CROSS_COMPILER)
|
||||
#if (LUA_OPTIMIZE_MEMORY == 2)
|
||||
#define LUA_META_ROTABLES
|
||||
#endif
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ static TString* LoadString(LoadState* S)
|
|||
} else {
|
||||
s = (char*)luaZ_get_crt_address(S->Z);
|
||||
LoadBlock(S,NULL,size);
|
||||
return luaS_newrolstr(S->L,s,size-1);
|
||||
return luaS_newlstr(S->L,s,size-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ static Proto* LoadFunction(LoadState* S, TString* p)
|
|||
Proto* f;
|
||||
if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
|
||||
f=luaF_newproto(S->L);
|
||||
if (luaZ_direct_mode(S->Z)) proto_readonly(f);
|
||||
if (luaZ_direct_mode(S->Z)) l_setbit((f)->marked, READONLYBIT);
|
||||
setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
|
||||
f->source=LoadString(S); if (f->source==NULL) f->source=p;
|
||||
f->linedefined=LoadInt(S);
|
||||
|
|
|
@ -41,7 +41,7 @@ LUA_NUMBER luai_ipow(LUA_NUMBER a, LUA_NUMBER b) {
|
|||
LUA_NUMBER c = 1;
|
||||
for (;;) {
|
||||
if (b & 1)
|
||||
c *= a;
|
||||
c *= a;
|
||||
b = b >> 1;
|
||||
if (b == 0)
|
||||
return c;
|
||||
|
|
|
@ -50,7 +50,7 @@ INCLUDES += -I ../pcm
|
|||
INCLUDES += -I ../platform
|
||||
INCLUDES += -I ../spiffs
|
||||
INCLUDES += -I ../smart
|
||||
INCLUDES += -I ../dhtlib
|
||||
INCLUDES += -I ../dht
|
||||
INCLUDES += -I ../fatfs
|
||||
INCLUDES += -I ../http
|
||||
INCLUDES += -I ../sjson
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
|
||||
** Initialization of libraries for lua.c
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#define linit_c
|
||||
#define LUA_LIB
|
||||
#define LUAC_CROSS_FILE
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
#include "luaconf.h"
|
||||
#include "module.h"
|
||||
|
||||
|
||||
BUILTIN_LIB_INIT( BASE, "", luaopen_base);
|
||||
BUILTIN_LIB_INIT( LOADLIB, LUA_LOADLIBNAME, luaopen_package);
|
||||
|
||||
#if defined(LUA_USE_BUILTIN_IO)
|
||||
BUILTIN_LIB_INIT( IO, LUA_IOLIBNAME, luaopen_io);
|
||||
#endif
|
||||
|
||||
#if defined (LUA_USE_BUILTIN_STRING)
|
||||
extern const luaR_entry strlib[];
|
||||
BUILTIN_LIB_INIT( STRING, LUA_STRLIBNAME, luaopen_string);
|
||||
BUILTIN_LIB( STRING, LUA_STRLIBNAME, strlib);
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_BUILTIN_TABLE)
|
||||
extern const luaR_entry tab_funcs[];
|
||||
BUILTIN_LIB_INIT( TABLE, LUA_TABLIBNAME, luaopen_table);
|
||||
BUILTIN_LIB( TABLE, LUA_TABLIBNAME, tab_funcs);
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_BUILTIN_DEBUG) || defined(LUA_USE_BUILTIN_DEBUG_MINIMAL)
|
||||
extern const luaR_entry dblib[];
|
||||
BUILTIN_LIB_INIT( DBG, LUA_DBLIBNAME, luaopen_debug);
|
||||
BUILTIN_LIB( DBG, LUA_DBLIBNAME, dblib);
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_BUILTIN_OS)
|
||||
extern const luaR_entry syslib[];
|
||||
BUILTIN_LIB( OS, LUA_OSLIBNAME, syslib);
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_BUILTIN_COROUTINE)
|
||||
extern const luaR_entry co_funcs[];
|
||||
BUILTIN_LIB( CO, LUA_COLIBNAME, co_funcs);
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_BUILTIN_MATH)
|
||||
extern const luaR_entry math_map[];
|
||||
BUILTIN_LIB( MATH, LUA_MATHLIBNAME, math_map);
|
||||
#endif
|
||||
|
||||
#ifdef LUA_CROSS_COMPILER
|
||||
const luaL_Reg lua_libs[] = {{NULL, NULL}};
|
||||
const luaR_table lua_rotable[] = {{NULL, NULL}};
|
||||
#else
|
||||
extern const luaL_Reg lua_libs[];
|
||||
#endif
|
||||
|
||||
void luaL_openlibs (lua_State *L) {
|
||||
const luaL_Reg *lib = lua_libs;
|
||||
for (; lib->name; lib++) {
|
||||
if (lib->func)
|
||||
{
|
||||
lua_pushcfunction(L, lib->func);
|
||||
lua_pushstring(L, lib->name);
|
||||
lua_call(L, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,9 @@
|
|||
|
||||
#include "platform.h"
|
||||
#include "lrodefs.h"
|
||||
|
||||
#ifdef LUA_FLASH_STORE
|
||||
#include "lflash.h"
|
||||
#endif
|
||||
#include "c_types.h"
|
||||
#include "c_string.h"
|
||||
#include "driver/uart.h"
|
||||
|
@ -134,7 +136,6 @@ static int node_chipid( lua_State* L )
|
|||
// lua_pushinteger(L, vdd33);
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
// Lua: flashid()
|
||||
static int node_flashid( lua_State* L )
|
||||
{
|
||||
|
@ -574,6 +575,13 @@ static const LUA_REG_TYPE node_task_map[] = {
|
|||
{ LSTRKEY( "HIGH_PRIORITY" ), LNUMVAL( TASK_PRIORITY_HIGH ) },
|
||||
{ LNILKEY, LNILVAL }
|
||||
};
|
||||
#ifdef LUA_FLASH_STORE
|
||||
static const LUA_REG_TYPE node_flash_map[] = {
|
||||
{ LSTRKEY( "reload" ), LFUNCVAL( luaN_reload_reboot ) },
|
||||
{ LSTRKEY( "index" ), LFUNCVAL( luaN_index ) },
|
||||
{ LNILKEY, LNILVAL }
|
||||
};
|
||||
#endif
|
||||
|
||||
static const LUA_REG_TYPE node_map[] =
|
||||
{
|
||||
|
@ -601,6 +609,9 @@ static const LUA_REG_TYPE node_map[] =
|
|||
{ LSTRKEY( "random" ), LFUNCVAL( node_random) },
|
||||
#ifdef LUA_OPTIMIZE_DEBUG
|
||||
{ LSTRKEY( "stripdebug" ), LFUNCVAL( node_stripdebug ) },
|
||||
#endif
|
||||
#ifdef LUA_FLASH_STORE
|
||||
{ LSTRKEY( "flash") , LROVAL( node_flash_map ) },
|
||||
#endif
|
||||
{ LSTRKEY( "egc" ), LROVAL( node_egc_map ) },
|
||||
{ LSTRKEY( "task" ), LROVAL( node_task_map ) },
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = mqtt.a
|
||||
GEN_LIBS = libmqtt.a
|
||||
endif
|
||||
|
||||
STD_CFLAGS=-std=gnu11 -Wimplicit
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = pcm.a
|
||||
GEN_LIBS = libpcm.a
|
||||
endif
|
||||
|
||||
STD_CFLAGS=-std=gnu11 -Wimplicit
|
||||
|
|
|
@ -67,22 +67,54 @@ uint32_t platform_flash_get_num_sectors(void)
|
|||
#endif // #ifdef INTERNAL_FLASH_SECTOR_SIZE
|
||||
}
|
||||
|
||||
static uint32_t allocated = 0;
|
||||
static uint32_t phys_flash_used_end = 0; //Phyiscal address of last byte in last flash used sector
|
||||
|
||||
uint32_t platform_flash_reserve_section( uint32_t regsize, uint32_t *start )
|
||||
{
|
||||
// Return Flash sector no (and optional flash mapped address of first allocated byte)
|
||||
|
||||
if(phys_flash_used_end == 0)
|
||||
flashh_find_sector(platform_flash_mapped2phys( (uint32_t)_flash_used_end - 1), NULL, &phys_flash_used_end );
|
||||
|
||||
/* find sector and last byte address of previous allocation */
|
||||
uint32_t end;
|
||||
uint32_t sect = flashh_find_sector( phys_flash_used_end + allocated, NULL, &end );
|
||||
if(start)
|
||||
*start = end + 1;
|
||||
|
||||
/* allocated regions are always sector aligned */
|
||||
flashh_find_sector( phys_flash_used_end + allocated + regsize, NULL, &end );
|
||||
allocated = end - phys_flash_used_end;
|
||||
|
||||
NODE_DBG("Flash base: %08x %08x %08x\n", regsize, allocated, phys_flash_used_end);
|
||||
return sect + 1;
|
||||
}
|
||||
|
||||
uint32_t platform_flash_get_first_free_block_address( uint32_t *psect )
|
||||
{
|
||||
// Round the total used flash size to the closest flash block address
|
||||
uint32_t start, end, sect;
|
||||
NODE_DBG("_flash_used_end:%08x\n", (uint32_t)_flash_used_end);
|
||||
#if 0
|
||||
if(_flash_used_end>0){ // find the used sector
|
||||
sect = flashh_find_sector( platform_flash_mapped2phys ( (uint32_t)_flash_used_end - 1), NULL, &end );
|
||||
if( psect )
|
||||
*psect = sect + 1;
|
||||
return end + 1;
|
||||
sect++;
|
||||
start = end + 1;
|
||||
}else{
|
||||
sect = flashh_find_sector( 0, &start, NULL ); // find the first free sector
|
||||
if( psect )
|
||||
*psect = sect;
|
||||
return start;
|
||||
}
|
||||
if(_flash_used_end>0){ // find the used sector
|
||||
uint32_t sta1, sec1;
|
||||
sec1 = platform_flash_reserve_section( 0, &sta1 );
|
||||
NODE_DBG("Flash base: %p %p %p %p\n", sect, start, sec1, sta1);
|
||||
}
|
||||
#endif
|
||||
sect = _flash_used_end ? platform_flash_reserve_section( 0, &start ) :
|
||||
flashh_find_sector( 0, &start, NULL );
|
||||
if( psect )
|
||||
*psect = sect;
|
||||
return start;
|
||||
}
|
||||
|
||||
uint32_t platform_flash_write( const void *from, uint32_t toaddr, uint32_t size )
|
||||
|
|
|
@ -879,7 +879,7 @@ uint32_t platform_s_flash_write( const void *from, uint32_t toaddr, uint32_t siz
|
|||
if(SPI_FLASH_RESULT_OK == r)
|
||||
return size;
|
||||
else{
|
||||
NODE_ERR( "ERROR in flash_write: r=%d at %08X\n", ( int )r, ( unsigned )toaddr);
|
||||
NODE_ERR( "ERROR in flash_write: r=%d at %p\n", ( int )r, ( unsigned )toaddr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -917,7 +917,7 @@ uint32_t platform_s_flash_read( void *to, uint32_t fromaddr, uint32_t size )
|
|||
if(SPI_FLASH_RESULT_OK == r)
|
||||
return size;
|
||||
else{
|
||||
NODE_ERR( "ERROR in flash_read: r=%d at %08X\n", ( int )r, ( unsigned )fromaddr);
|
||||
NODE_ERR( "ERROR in flash_read: r=%d at %p\n", ( int )r, ( unsigned )fromaddr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -928,15 +928,26 @@ int platform_flash_erase_sector( uint32_t sector_id )
|
|||
return flash_erase( sector_id ) == SPI_FLASH_RESULT_OK ? PLATFORM_OK : PLATFORM_ERR;
|
||||
}
|
||||
|
||||
uint32_t platform_flash_mapped2phys (uint32_t mapped_addr)
|
||||
static uint32_t flash_map_meg_offset ()
|
||||
{
|
||||
uint32_t cache_ctrl = READ_PERI_REG(CACHE_FLASH_CTRL_REG);
|
||||
if (!(cache_ctrl & CACHE_FLASH_ACTIVE))
|
||||
return -1;
|
||||
bool b0 = (cache_ctrl & CACHE_FLASH_MAPPED0) ? 1 : 0;
|
||||
bool b1 = (cache_ctrl & CACHE_FLASH_MAPPED1) ? 1 : 0;
|
||||
uint32_t meg = (b1 << 1) | b0;
|
||||
return mapped_addr - INTERNAL_FLASH_MAPPED_ADDRESS + meg * 0x100000;
|
||||
return ((b1 << 1) | b0) * 0x100000;
|
||||
}
|
||||
|
||||
uint32_t platform_flash_mapped2phys (uint32_t mapped_addr)
|
||||
{
|
||||
uint32_t meg = flash_map_meg_offset();
|
||||
return (meg&1) ? -1 : mapped_addr - INTERNAL_FLASH_MAPPED_ADDRESS + meg ;
|
||||
}
|
||||
|
||||
uint32_t platform_flash_phys2mapped (uint32_t phys_addr)
|
||||
{
|
||||
uint32_t meg = flash_map_meg_offset();
|
||||
return (meg&1) ? -1 : phys_addr + INTERNAL_FLASH_MAPPED_ADDRESS - meg;
|
||||
}
|
||||
|
||||
void* platform_print_deprecation_note( const char *msg, const char *time_frame)
|
||||
|
|
|
@ -268,8 +268,11 @@ uint32_t platform_eth_get_elapsed_time(void);
|
|||
// *****************************************************************************
|
||||
// Internal flash erase/write functions
|
||||
|
||||
uint32_t platform_flash_reserve_section( uint32_t regsize, uint32_t *start );
|
||||
uint32_t platform_flash_get_first_free_block_address( uint32_t *psect );
|
||||
uint32_t platform_flash_get_sector_of_address( uint32_t addr );
|
||||
uint32_t platform_flash_mapped2phys (uint32_t mapped_addr);
|
||||
uint32_t platform_flash_phys2mapped (uint32_t phys_addr);
|
||||
uint32_t platform_flash_write( const void *from, uint32_t toaddr, uint32_t size );
|
||||
uint32_t platform_flash_read( void *to, uint32_t fromaddr, uint32_t size );
|
||||
uint32_t platform_s_flash_write( const void *from, uint32_t toaddr, uint32_t size );
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = tsl2561lib.a
|
||||
GEN_LIBS = libtsl2561.a
|
||||
endif
|
||||
|
||||
STD_CFLAGS=-std=gnu11 -Wimplicit
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = u8glib.a
|
||||
GEN_LIBS = libu8glib.a
|
||||
endif
|
||||
|
||||
STD_CFLAGS=-std=gnu11 -Wimplicit
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = ucglib.a
|
||||
GEN_LIBS = libucglib.a
|
||||
endif
|
||||
|
||||
STD_CFLAGS=-std=gnu11 -Wimplicit
|
||||
|
|
|
@ -240,6 +240,7 @@ user_rf_cal_sector_set(void)
|
|||
return rf_cal_sec;
|
||||
}
|
||||
|
||||
extern void luaN_user_init(void);
|
||||
/******************************************************************************
|
||||
* FunctionName : user_init
|
||||
* Description : entry of user application, init user function here
|
||||
|
@ -261,5 +262,9 @@ void user_init(void)
|
|||
system_set_os_print(0);
|
||||
#endif
|
||||
|
||||
#ifdef LUA_FLASH_STORE
|
||||
luaN_user_init();
|
||||
#endif
|
||||
|
||||
system_init_done_cb(nodemcu_init);
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ system heap size left in bytes (number)
|
|||
|
||||
## node.info()
|
||||
|
||||
Returns NodeMCU version, chipid, flashid, flash size, flash mode, flash speed.
|
||||
Returns NodeMCU version, chipid, flashid, flash size, flash mode, flash speed, and Lua File Store (LFS) usage statics.
|
||||
|
||||
#### Syntax
|
||||
`node.info()`
|
||||
|
@ -496,6 +496,37 @@ provides more detailed information on the EGC.
|
|||
`node.egc.setmode(node.egc.ALWAYS, 4096) -- This is the default setting at startup.`
|
||||
`node.egc.setmode(node.egc.ON_ALLOC_FAILURE) -- This is the fastest activeEGC mode.`
|
||||
|
||||
# node.flash module
|
||||
|
||||
## node.flash.index()
|
||||
|
||||
Returns the function reference for a function in the LFS (Lua Flash Store).
|
||||
|
||||
#### Syntax
|
||||
`node.flash.index()`
|
||||
|
||||
#### Parameters
|
||||
None
|
||||
|
||||
#### Returns
|
||||
- In the case where the LFS in not loaded, `node.flash.index` evaluates to `nil`
|
||||
- If the LFS is loaded, this returns the index function within the LFS which indexes its contents. This index function can itself to called to interrogate or access the LFS contents:
|
||||
- In that case where the function is called with the name of a valid module in the LFS, the function is returned in the same way the `load()` and the other Lua load functions do.
|
||||
- Otherwise the function returns a list of module names in the LFS. Note that the first entry in the list is the Unix datetime of he build.
|
||||
|
||||
## node.flash.reload()
|
||||
|
||||
Reload the LFS (Lua Flash Store) with the flash image provided. Flash images are generated on the host machine using the `luac.cross`commnad.
|
||||
|
||||
#### Syntax
|
||||
`node.flash.rebuild(imageName)`
|
||||
|
||||
#### Parameters
|
||||
`imageName` The of name of a image file in the filesystem to be loaded into the LFS.
|
||||
|
||||
#### Returns
|
||||
_Not applicable_. The ESP will load the LFS image and immediately reboot. Control is not returned to the calling application.
|
||||
|
||||
# node.task module
|
||||
|
||||
## node.task.post()
|
||||
|
|
|
@ -234,11 +234,11 @@ SECTIONS
|
|||
|
||||
/* Link-time arrays containing the defs for the included modules */
|
||||
. = ALIGN(4);
|
||||
lua_libs = ABSOLUTE(.);
|
||||
lua_libs_base = ABSOLUTE(.);
|
||||
/* Allow either empty define or defined-to-1 to include the module */
|
||||
KEEP(*(.lua_libs))
|
||||
LONG(0) LONG(0) /* Null-terminate the array */
|
||||
lua_rotable = ABSOLUTE(.);
|
||||
lua_rotable_base = ABSOLUTE(.);
|
||||
KEEP(*(.lua_rotable))
|
||||
LONG(0) LONG(0) /* Null-terminate the array */
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
FSSOURCE ?= ../local/fs/
|
||||
LUASOURCE ?= ../local/lua/
|
||||
FLASHSIZE ?= 4mb 32mb 8mb
|
||||
FLASH_SW = -S
|
||||
SUBDIRS =
|
||||
HOSTCC ?= gcc
|
||||
|
||||
OBJDUMP = $(or $(shell which objdump),xtensa-lx106-elf-objdump)
|
||||
|
||||
|
@ -20,16 +20,16 @@ SPIFFSFILES ?= $(patsubst $(FSSOURCE)%,%,$(shell find $(FSSOURCE) -name '*' '!'
|
|||
# Get the filesize of /bin/0x10000.bin and SPIFFS sizing
|
||||
#
|
||||
|
||||
FLASH_USED_END := $$((0x`$(OBJDUMP) -t ../app/.output/eagle/debug/image/eagle.app.v6.out |grep _flash_used_end |cut -f1 -d" "` - 0x40200000))
|
||||
FLASH_FS_SIZE := $(shell $(HOSTCC) -E -dM - <../app/include/user_config.h | grep SPIFFS_MAX_FILESYSTEM_SIZE| cut -d ' ' -f 3)
|
||||
FLASH_FS_LOC := $(shell $(HOSTCC) -E -dM - <../app/include/user_config.h | grep SPIFFS_FIXED_LOCATION| cut -d ' ' -f 3)
|
||||
FLASH_FS_SIZE := $(shell $(CC) -E -dM - <../app/include/user_config.h | grep SPIFFS_MAX_FILESYSTEM_SIZE| cut -d ' ' -f 3)
|
||||
|
||||
ifneq (FLASH_FS_SIZE,'')
|
||||
ifneq ($(strip $(FLASH_FS_SIZE)),)
|
||||
FLASHSIZE = $(shell printf "0x%x" $(FLASH_FS_SIZE))
|
||||
FLASH_SW = -c
|
||||
endif
|
||||
|
||||
ifeq (FLASH_FS_LOC,'')
|
||||
FLASH_FS_LOC := $(FLASH_USED_END)
|
||||
FLASH_FS_LOC := $(shell $(CC) -E -dM - <../app/include/user_config.h | grep SPIFFS_FIXED_LOCATION| cut -d ' ' -f 3)
|
||||
ifeq ($(strip $(FLASH_FS_LOC)),)
|
||||
FLASH_FS_LOC := $(shell printf "0x%x" $$((0x$(shell $(OBJDUMP) -t ../app/.output/eagle/debug/image/eagle.app.v6.out |grep " _flash_used_end" |cut -f1 -d" ") - 0x40200000)))
|
||||
else
|
||||
FLASH_FS_LOC := $(shell printf "0x%x" $(FLASH_FS_LOC))
|
||||
endif
|
||||
|
@ -42,6 +42,16 @@ endif
|
|||
|
||||
all: spiffsscript
|
||||
|
||||
.PHONY: TEST
|
||||
|
||||
TEST:
|
||||
@echo $(FLASHSIZE)
|
||||
@echo $(FLASH_FS_SIZE)
|
||||
@echo $(FLASH_FS_LOC)
|
||||
@echo $(FLASH_USED_END)
|
||||
|
||||
spiffsimg/spiffsimg:
|
||||
|
||||
.PHONY: spiffsimg
|
||||
|
||||
.PHONY: spiffsimg/spiffsimg
|
||||
|
@ -56,7 +66,7 @@ spiffsscript: remove-image LFSimage spiffsimg/spiffsimg
|
|||
rm -f ./spiffsimg/spiffs.lst
|
||||
@echo "" >> ./spiffsimg/spiffs.lst
|
||||
@$(foreach f, $(SPIFFSFILES), echo "import $(FSSOURCE)$(f) $(f)" >> ./spiffsimg/spiffs.lst ;)
|
||||
$(foreach sz, $(FLASHSIZE), spiffsimg/spiffsimg -f ../bin/0x%x-$(sz).img -c $(sz) -U $(FLASH_FS_LOC) -r ./spiffsimg/spiffs.lst -d; )
|
||||
$(foreach sz, $(FLASHSIZE), spiffsimg/spiffsimg -f ../bin/0x%x-$(sz).img $(FLASH_SW) $(sz) -U $(FLASH_FS_LOC) -r ./spiffsimg/spiffs.lst -d; )
|
||||
@$(foreach sz, $(FLASHSIZE), if [ -r ../bin/spiffs-$(sz).dat ]; then echo Built $$(cat ../bin/spiffs-$(sz).dat)-$(sz).bin; fi; )
|
||||
|
||||
LFSimage: $(LUASOURCE)*.lua
|
||||
|
|
Loading…
Reference in New Issue