Commit 4ae52c23 authored by TerryE's avatar TerryE
Browse files

Alpha working wersion for third party evaluation

parent e00d927a
...@@ -5,6 +5,15 @@ ...@@ -5,6 +5,15 @@
# single hardware breakpoint which can be used as an hb or a wa. You have to # 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. # 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 confirm off
set print null-stop set print null-stop
define br define br
...@@ -13,10 +22,30 @@ define br ...@@ -13,10 +22,30 @@ define br
end end
set pagination off 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 define prTV
if $arg0 if $arg0
set $type = $arg0.tt set $type = ($arg0).tt
set $val = $arg0.value set $val = ($arg0).value
if $type == 0 if $type == 0
# NIL # NIL
...@@ -24,34 +53,33 @@ define prTV ...@@ -24,34 +53,33 @@ define prTV
end end
if $type == 1 if $type == 1
# Boolean # Boolean
printf "Boolean: %u\n", $val->n printf "Boolean: %u\n", $val.n
end end
if $type == 2 if $type == 2
# ROTable # ROTable
printf "ROTable: %p\n", $val->p printf "ROTable: %p\n", $val.p
end end
if $type == 3 if $type == 3
# Light Function # Light Function
printf "Light Func: %p\n",p $arg $val->p printf "Light Func: %p\n", $val.p
end end
if $type == 4 if $type == 4
# Light User Data # Light User Data
printf "Light Udata: %p\n", $val->pend printf "Light Udata: %p\n", $val.p
end end
if $type == 5 if $type == 5
# Number # Number
printf "Boolean: %u\n", $val->n printf "Number: %u\n", $val.n
end end
if $type == 6 if $type == 6
# TString prTS $arg0
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)
end end
if $type == 7 if $type == 7
# Table # Table
__printComHdr $arg0 set $o = &($val->gc.h)
set $ts = (TString *)$val->p 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 end
if $type == 8 if $type == 8
# Function # Function
...@@ -106,6 +134,25 @@ define dumpRAMstrt ...@@ -106,6 +134,25 @@ define dumpRAMstrt
dumpstrt &(L->l_G->strt) dumpstrt &(L->l_G->strt)
end 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 save on
set history size 1000 set history size 1000
...@@ -26,7 +26,7 @@ ifdef DEBUG ...@@ -26,7 +26,7 @@ ifdef DEBUG
CCFLAGS += -ggdb -O0 CCFLAGS += -ggdb -O0
LDFLAGS += -ggdb LDFLAGS += -ggdb
else else
CCFLAGS += -Os CCFLAGS += -O2
endif endif
############################################################# #############################################################
......
...@@ -20,93 +20,64 @@ FLAVOR = debug ...@@ -20,93 +20,64 @@ FLAVOR = debug
ifndef PDIR # { ifndef PDIR # {
GEN_IMAGES= eagle.app.v6.out GEN_IMAGES= eagle.app.v6.out
GEN_BINS= eagle.app.v6.bin 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= \ SUBDIRS= \
user \ user \
driver \ driver \
pcm \
mbedtls \ mbedtls \
platform \ platform \
libc \ libc \
lua \ lua \
lwip \ lwip \
coap \
mqtt \
task \ task \
u8glib \
ucglib \
smart \ smart \
modules \ modules \
spiffs \ spiffs \
crypto \
dhtlib \
tsl2561 \
net \ net \
http \
fatfs \ fatfs \
esp-gdbstub \ esp-gdbstub \
websocket \
swTimer \ swTimer \
misc \ misc \
pm \ pm \
sjson \ $(OPT_SEL_MKTARGETS)
sqlite3 \
endif # } PDIR endif # } PDIR
APPDIR = . APPDIR = .
LDDIR = ../ld LDDIR = ../ld
CCFLAGS += -Os
TARGET_LDFLAGS = \ TARGET_LDFLAGS = \
-nostdlib \ -nostdlib \
-Wl,-EL \ -Wl,-EL \
--longcalls \ --longcalls \
--text-section-literals --text-section-literals
ifeq ($(FLAVOR),debug)
TARGET_LDFLAGS += -g -Os
endif
ifeq ($(FLAVOR),release)
TARGET_LDFLAGS += -Os
endif
LD_FILE = $(LDDIR)/nodemcu.ld LD_FILE = $(LDDIR)/nodemcu.ld
COMPONENTS_eagle.app.v6 = \ COMPONENTS_eagle.app.v6 = \
user/libuser.a \ user/libuser.a \
driver/libdriver.a \ driver/libdriver.a \
pcm/pcm.a \
platform/libplatform.a \ platform/libplatform.a \
task/libtask.a \ task/libtask.a \
libc/liblibc.a \ libc/liblibc.a \
lua/liblua.a \ lua/liblua.a \
lwip/liblwip.a \ lwip/liblwip.a \
coap/coap.a \
mqtt/mqtt.a \
u8glib/u8glib.a \
ucglib/ucglib.a \
smart/smart.a \ smart/smart.a \
spiffs/spiffs.a \ spiffs/spiffs.a \
fatfs/libfatfs.a \ fatfs/libfatfs.a \
crypto/libcrypto.a \
dhtlib/libdhtlib.a \
tsl2561/tsl2561lib.a \
http/libhttp.a \
pm/libpm.a \ pm/libpm.a \
websocket/libwebsocket.a \
esp-gdbstub/libgdbstub.a \ esp-gdbstub/libgdbstub.a \
net/libnodemcu_net.a \ net/libnodemcu_net.a \
mbedtls/libmbedtls.a \ mbedtls/libmbedtls.a \
modules/libmodules.a \ modules/libmodules.a \
swTimer/libswtimer.a \ swTimer/libswtimer.a \
misc/libmisc.a \ misc/libmisc.a \
sjson/libsjson.a \ $(OPT_SEL_COMPONENTS)
sqlite3/libsqlite3.a \
# Inspect the modules library and work out which modules need to be linked. # 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 # For each enabled module, a symbol name of the form XYZ_module_selected is
...@@ -194,6 +165,5 @@ INCLUDES += -I ./ ...@@ -194,6 +165,5 @@ INCLUDES += -I ./
PDIR := ../$(PDIR) PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile sinclude $(PDIR)Makefile
.PHONY: FORCE .PHONY: FORCE
FORCE: FORCE:
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# a generated lib/image xxx.a () # a generated lib/image xxx.a ()
# #
ifndef PDIR ifndef PDIR
GEN_LIBS = coap.a GEN_LIBS = libcoap.a
endif endif
############################################################# #############################################################
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# a generated lib/image xxx.a () # a generated lib/image xxx.a ()
# #
ifndef PDIR ifndef PDIR
GEN_LIBS = libdhtlib.a GEN_LIBS = libdht.a
endif endif
......
#if !defined(__MODULE_H_) && !defined(LUA_CROSS_COMPILER) #ifndef __MODULE_H__
#define __MODULE_H__ #define __MODULE_H__
#include "user_modules.h" #include "user_modules.h"
...@@ -38,8 +38,11 @@ ...@@ -38,8 +38,11 @@
#define MODULE_PASTE_(x,y) x##y #define MODULE_PASTE_(x,y) x##y
#define MODULE_EXPAND_PASTE_(x,y) MODULE_PASTE_(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): /* For the ROM table, we name the variable according to ( | denotes concat):
* cfgname | _module_selected | LUA_USE_MODULES_##cfgname * cfgname | _module_selected | LUA_USE_MODULES_##cfgname
* where the LUA_USE_MODULES_XYZ macro is first expanded to yield either * where the LUA_USE_MODULES_XYZ macro is first expanded to yield either
...@@ -51,20 +54,20 @@ ...@@ -51,20 +54,20 @@
* to be linked in. * to be linked in.
*/ */
#define NODEMCU_MODULE(cfgname, luaname, map, initfunc) \ #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 }; \ 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))) \ luaR_table MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
= { luaname, map } = { luaname, map }
/* System module registration support, not using LUA_USE_MODULES_XYZ. */ /* System module registration support, not using LUA_USE_MODULES_XYZ. */
#define BUILTIN_LIB_INIT(name, luaname, initfunc) \ #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 } luaL_Reg MODULE_PASTE_(lua_lib_,name) = { luaname, initfunc }
#define BUILTIN_LIB(name, luaname, map) \ #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 } luaR_table MODULE_PASTE_(lua_rotable_,name) = { luaname, map }
#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2) #if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
......
...@@ -12,8 +12,9 @@ ...@@ -12,8 +12,9 @@
// This adds the asserts in LUA. It also adds some useful extras to the // 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 // 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) // 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 // You can either set these defines here to operate globally or you edit the
// Makefile for ony one subdirectory. If you want to use the remote GDB to // 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 // handle breaks and failed assetions then enable DEVELOPMENT_USE GDB
//#define DEVELOPMENT_TOOLS //#define DEVELOPMENT_TOOLS
//#define DEVELOPMENT_USE_GDB //#define DEVELOPMENT_USE_GDB
...@@ -54,6 +55,8 @@ extern void luaL_dbgbreak(void); ...@@ -54,6 +55,8 @@ extern void luaL_dbgbreak(void);
#define NODE_ERR #define NODE_ERR
#endif /* NODE_ERROR */ #endif /* NODE_ERROR */
#define LUA_USE_BUILTIN_DEBUG_MINIMAL // for debug.getregistry() and debug.traceback()
#define GPIO_INTERRUPT_ENABLE #define GPIO_INTERRUPT_ENABLE
#define GPIO_INTERRUPT_HOOK_ENABLE #define GPIO_INTERRUPT_HOOK_ENABLE
// #define GPIO_SAFE_NO_INTR_ENABLE // #define GPIO_SAFE_NO_INTR_ENABLE
...@@ -86,18 +89,22 @@ extern void luaL_dbgbreak(void); ...@@ -86,18 +89,22 @@ extern void luaL_dbgbreak(void);
// maximum number of open files for SPIFFS // maximum number of open files for SPIFFS
#define SPIFFS_MAX_OPEN_FILES 4 #define SPIFFS_MAX_OPEN_FILES 4
// Uncomment this next line for fastest startup // Uncomment this next line for fastest startup and set the FS only to what
// It reduces the format time dramatically // your application needs. This reduces the format time dramatically
// #define SPIFFS_MAX_FILESYSTEM_SIZE 32768 //#define SPIFFS_MAX_FILESYSTEM_SIZE 0x10000
// //
// You can force the spiffs file system to be at a fixed location // 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 // 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 // (minus the 16k parameter space). THis is useful for certain OTA scenarios
// #define SPIFFS_SIZE_1M_BOUNDARY // #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 READLINE_INTERVAL 80
#define LUA_TASK_PRIO USER_TASK_PRIO_0 #define LUA_TASK_PRIO USER_TASK_PRIO_0
......
#ifndef __USER_MODULES_H__ #ifndef __USER_MODULES_H__
#define __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 #ifndef LUA_CROSS_COMPILER
...@@ -65,13 +57,13 @@ ...@@ -65,13 +57,13 @@
//#define LUA_USE_MODULES_SJSON //#define LUA_USE_MODULES_SJSON
//#define LUA_USE_MODULES_SNTP //#define LUA_USE_MODULES_SNTP
//#define LUA_USE_MODULES_SOMFY //#define LUA_USE_MODULES_SOMFY
#define LUA_USE_MODULES_SPI //#define LUA_USE_MODULES_SPI
//#define LUA_USE_MODULES_SQLITE3 //#define LUA_USE_MODULES_SQLITE3
//#define LUA_USE_MODULES_STRUCT //#define LUA_USE_MODULES_STRUCT
//#define LUA_USE_MODULES_SWITEC //#define LUA_USE_MODULES_SWITEC
// #define LUA_USE_MODULES_TCS34725 //#define LUA_USE_MODULES_TCS34725
//#define LUA_USE_MODULES_TM1829 //#define LUA_USE_MODULES_TM1829
#define LUA_USE_MODULES_TLS //#define LUA_USE_MODULES_TLS
#define LUA_USE_MODULES_TMR #define LUA_USE_MODULES_TMR
//#define LUA_USE_MODULES_TSL2561 //#define LUA_USE_MODULES_TSL2561
//#define LUA_USE_MODULES_U8G //#define LUA_USE_MODULES_U8G
......
...@@ -25,7 +25,8 @@ STD_CFLAGS=-std=gnu11 -Wimplicit ...@@ -25,7 +25,8 @@ STD_CFLAGS=-std=gnu11 -Wimplicit
# makefile at its root level - these are then overridden # makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein # 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!! # Recursion Magic - Don't touch this!!
......
...@@ -414,7 +414,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { ...@@ -414,7 +414,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
case LUA_TROTABLE: case LUA_TROTABLE:
return rvalue(o); return rvalue(o);
case LUA_TLIGHTFUNCTION: case LUA_TLIGHTFUNCTION:
return pvalue(o); return fvalue(o);
default: return NULL; default: return NULL;
} }
} }
...@@ -459,15 +459,6 @@ LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { ...@@ -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) { LUA_API void lua_pushstring (lua_State *L, const char *s) {
if (s == NULL) if (s == NULL)
lua_pushnil(L); lua_pushnil(L);
......
...@@ -46,6 +46,13 @@ ...@@ -46,6 +46,13 @@
//#define DEBUG_ALLOCATOR //#define DEBUG_ALLOCATOR
#ifdef 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 ** Diagnosticd version for realloc. This is enabled only if the
...@@ -56,31 +63,72 @@ ...@@ -56,31 +63,72 @@
** ======================================================================= ** =======================================================================
*/ */
#define this_realloc debug_realloc #define this_realloc debug_realloc
#define ASSERT(s) if (!(s)) {asm ("break 0,0" ::);}
#define MARK 0x55 /* 01010101 (a nice pattern) */ #define MARK 0x55 /* 01010101 (a nice pattern) */
#define MARK4 0x55555555 #define MARKSIZE 2*sizeof(size_t) /* size of marks after each block */
#define MARKSIZE 4 /* size of marks after each block */ #define fillmem(mem,size) memset(mem, ~MARK, size)
#define fillmem(mem,size) memset(mem, -MARK, size)
typedef struct Memcontrol { /* memory-allocator control variables */ typedef union MemHeader MemHeader;
uint32_t numblocks; union MemHeader {
uint32_t total;
uint32_t maxmem;
uint32_t memlimit;
} Memcontrol;
static Memcontrol mc = {0,0,0,32768};
typedef union MemHeader {
L_Umaxalign a; /* ensures maximum alignment for Header */ L_Umaxalign a; /* ensures maximum alignment for Header */
struct { struct {
size_t size; size_t size;
int mark; MemHeader *next;
} d; size_t mark[2];
} MemHeader; };
};
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) { static void freeblock (MemHeader *block) {
if (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 */ fillmem(block, sizeof(MemHeader) + size + MARKSIZE); /* erase block */
c_free(block); /* actually free block */ c_free(block); /* actually free block */
mc.numblocks--; /* update counts */ mc.numblocks--; /* update counts */
...@@ -88,18 +136,17 @@ static void freeblock (MemHeader *block) { ...@@ -88,18 +136,17 @@ static void freeblock (MemHeader *block) {
} }
} }
void *debug_realloc (void *b, size_t oldsize, size_t size) { void *debug_realloc (void *b, size_t oldsize, size_t size) {
MemHeader *block = cast(MemHeader *, b); MemHeader *block = cast(MemHeader *, b);
int i; ASSERT(checkBlocks());
if (!marker[0]) memset(marker, MARK, MARKSIZE);
if (block == NULL) { if (block == NULL) {
oldsize = 0; oldsize = 0;
} else { } else {
block--; /* go to real header */ block--; /* go to real header */
ASSERT(block->d.mark == MARK4); ASSERT(!memcmp(block->mark, marker, MARKSIZE))
ASSERT(oldsize == block->d.size); ASSERT(oldsize == block->size);
for (i = 0; i < MARKSIZE; i++) /* check marks after block */ ASSERT(!memcmp(cast(char *, b)+oldsize, marker, MARKSIZE));
ASSERT (cast(char *, b)[oldsize + i] == MARK);
} }
if (size == 0) { if (size == 0) {
freeblock(block); freeblock(block);
...@@ -108,7 +155,6 @@ void *debug_realloc (void *b, size_t oldsize, size_t size) { ...@@ -108,7 +155,6 @@ void *debug_realloc (void *b, size_t oldsize, size_t size) {
return NULL; /* fake a memory allocation error */ return NULL; /* fake a memory allocation error */
else { else {
MemHeader *newblock; MemHeader *newblock;
int i;
size_t commonsize = (oldsize < size) ? oldsize : size; size_t commonsize = (oldsize < size) ? oldsize : size;
size_t realsize = sizeof(MemHeader) + size + MARKSIZE; size_t realsize = sizeof(MemHeader) + size + MARKSIZE;
newblock = cast(MemHeader *, c_malloc(realsize)); /* alloc a new block */ 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) { ...@@ -119,12 +165,14 @@ void *debug_realloc (void *b, size_t oldsize, size_t size) {
freeblock(block); /* erase (and check) old copy */ freeblock(block); /* erase (and check) old copy */
} }
/* initialize new part of the block with something weird */ /* 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 */ /* initialize marks after block */
newblock->d.mark = MARK4; memset(newblock->mark, MARK, MARKSIZE);
newblock->d.size = size; newblock->size = size;
for (i = 0; i < MARKSIZE; i++) newblock->next = mc.start;
cast(char *, newblock + 1)[size + i] = MARK; mc.start = newblock;
memset(cast(char *, newblock + 1)+ size, MARK, MARKSIZE);
mc.total += size; mc.total += size;
if (mc.total > mc.maxmem) if (mc.total > mc.maxmem)
mc.maxmem = mc.total; mc.maxmem = mc.total;
......
...@@ -712,10 +712,5 @@ static void base_open (lua_State *L) { ...@@ -712,10 +712,5 @@ static void base_open (lua_State *L) {
LUALIB_API int luaopen_base (lua_State *L) { LUALIB_API int luaopen_base (lua_State *L) {
base_open(L); base_open(L);
#if LUA_OPTIMIZE_MEMORY == 0
luaL_register(L, LUA_COLIBNAME, co_funcs);
return 2;
#else
return 1; return 1;
#endif
} }
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h" #include "lrotable.h"
#include "lstring.h"
#include "lflash.h"
#include "user_modules.h" #include "user_modules.h"
...@@ -26,6 +28,39 @@ static int db_getregistry (lua_State *L) { ...@@ -26,6 +28,39 @@ static int db_getregistry (lua_State *L) {
return 1; 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 #ifndef LUA_USE_BUILTIN_DEBUG_MINIMAL
static int db_getmetatable (lua_State *L) { static int db_getmetatable (lua_State *L) {
...@@ -395,6 +430,7 @@ const LUA_REG_TYPE dblib[] = { ...@@ -395,6 +430,7 @@ const LUA_REG_TYPE dblib[] = {
{LSTRKEY("getlocal"), LFUNCVAL(db_getlocal)}, {LSTRKEY("getlocal"), LFUNCVAL(db_getlocal)},
#endif #endif
{LSTRKEY("getregistry"), LFUNCVAL(db_getregistry)}, {LSTRKEY("getregistry"), LFUNCVAL(db_getregistry)},
{LSTRKEY("getstrings"), LFUNCVAL(db_getstrings)},
#ifndef LUA_USE_BUILTIN_DEBUG_MINIMAL #ifndef LUA_USE_BUILTIN_DEBUG_MINIMAL
{LSTRKEY("getmetatable"), LFUNCVAL(db_getmetatable)}, {LSTRKEY("getmetatable"), LFUNCVAL(db_getmetatable)},
{LSTRKEY("getupvalue"), LFUNCVAL(db_getupvalue)}, {LSTRKEY("getupvalue"), LFUNCVAL(db_getupvalue)},
......
/*
** $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) { ...@@ -146,7 +146,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->k, f->sizek, TValue); luaM_freearray(L, f->k, f->sizek, TValue);
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); 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); luaM_freearray(L, f->code, f->sizecode, Instruction);
#ifdef LUA_OPTIMIZE_DEBUG #ifdef LUA_OPTIMIZE_DEBUG
if (f->packedlineinfo) { if (f->packedlineinfo) {
......
...@@ -18,9 +18,6 @@ ...@@ -18,9 +18,6 @@
#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
cast(int, sizeof(TValue *)*((n)-1))) 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 Proto *luaF_newproto (lua_State *L);
LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
#define GCSWEEPCOST 10 #define GCSWEEPCOST 10
#define GCFINALIZECOST 100 #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)) #define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
...@@ -37,7 +40,7 @@ ...@@ -37,7 +40,7 @@
#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) #define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) #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) #define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
...@@ -61,12 +64,17 @@ ...@@ -61,12 +64,17 @@
static void removeentry (Node *n) { static void removeentry (Node *n) {
lua_assert(ttisnil(gval(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 */ setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
} }
static void reallymarkobject (global_State *g, GCObject *o) { 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)); lua_assert(iswhite(o) && !isdead(g, o));
white2gray(o); white2gray(o);
switch (o->gch.tt) { switch (o->gch.tt) {
...@@ -180,6 +188,8 @@ static int traversetable (global_State *g, Table *h) { ...@@ -180,6 +188,8 @@ static int traversetable (global_State *g, Table *h) {
while (i--) while (i--)
markvalue(g, &h->array[i]); markvalue(g, &h->array[i]);
} }
if (luaH_isdummy (h->node))
return weakkey || weakvalue;
i = sizenode(h); i = sizenode(h);
while (i--) { while (i--) {
Node *n = gnode(h, i); Node *n = gnode(h, i);
...@@ -202,6 +212,8 @@ static int traversetable (global_State *g, Table *h) { ...@@ -202,6 +212,8 @@ static int traversetable (global_State *g, Table *h) {
*/ */
static void traverseproto (global_State *g, Proto *f) { static void traverseproto (global_State *g, Proto *f) {
int i; int i;
if (isLFSobject(f))
return; /* don't traverse Protos in LFS */
if (f->source) stringmark(f->source); if (f->source) stringmark(f->source);
for (i=0; i<f->sizek; i++) /* mark literals */ for (i=0; i<f->sizek; i++) /* mark literals */
markvalue(g, &f->k[i]); markvalue(g, &f->k[i]);
...@@ -317,7 +329,7 @@ static l_mem propagatemark (global_State *g) { ...@@ -317,7 +329,7 @@ static l_mem propagatemark (global_State *g) {
sizeof(TValue) * p->sizek + sizeof(TValue) * p->sizek +
sizeof(LocVar) * p->sizelocvars + sizeof(LocVar) * p->sizelocvars +
sizeof(TString *) * p->sizeupvalues + 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 #ifdef LUA_OPTIMIZE_DEBUG
(p->packedlineinfo ? (p->packedlineinfo ?
c_strlen(cast(char *, p->packedlineinfo))+1 : c_strlen(cast(char *, p->packedlineinfo))+1 :
...@@ -388,7 +400,10 @@ static void cleartable (GCObject *l) { ...@@ -388,7 +400,10 @@ static void cleartable (GCObject *l) {
static void freeobj (lua_State *L, GCObject *o) { static void freeobj (lua_State *L, GCObject *o) {
switch (o->gch.tt) { 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_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
case LUA_TTABLE: luaH_free(L, gco2h(o)); break; case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
...@@ -398,6 +413,7 @@ static void freeobj (lua_State *L, GCObject *o) { ...@@ -398,6 +413,7 @@ static void freeobj (lua_State *L, GCObject *o) {
break; break;
} }
case LUA_TSTRING: { case LUA_TSTRING: {
lua_assert(!isLFSobject(&(o->gch)));
G(L)->strt.nuse--; G(L)->strt.nuse--;
luaM_freemem(L, o, sizestring(gco2ts(o))); luaM_freemem(L, o, sizestring(gco2ts(o)));
break; break;
...@@ -420,6 +436,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { ...@@ -420,6 +436,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
global_State *g = G(L); global_State *g = G(L);
int deadmask = otherwhite(g); int deadmask = otherwhite(g);
while ((curr = *p) != NULL && count-- > 0) { 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 */ if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
sweepwholelist(L, &gco2th(curr)->openupval); sweepwholelist(L, &gco2th(curr)->openupval);
if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
...@@ -538,7 +555,7 @@ static void atomic (lua_State *L) { ...@@ -538,7 +555,7 @@ static void atomic (lua_State *L) {
size_t udsize; /* total size of userdata to be finalized */ size_t udsize; /* total size of userdata to be finalized */
/* remark occasional upvalues of (maybe) dead threads */ /* remark occasional upvalues of (maybe) dead threads */
remarkupvals(g); remarkupvals(g);
/* traverse objects cautch by write barrier and by 'remarkupvals' */ /* traverse objects caucht by write barrier and by 'remarkupvals' */
propagateall(g); propagateall(g);
/* remark weak tables */ /* remark weak tables */
g->gray = g->weak; g->gray = g->weak;
...@@ -694,10 +711,10 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { ...@@ -694,10 +711,10 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
global_State *g = G(L); global_State *g = G(L);
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); 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? */ /* must keep invariant? */
if (g->gcstate == GCSpropagate) if (g->gcstate == GCSpropagate)
reallymarkobject(g, v); /* restore invariant */ reallymarkobject(g, v); /* Restore invariant */
else /* don't mind */ else /* don't mind */
makewhite(g, o); /* mark as white just to avoid other barriers */ makewhite(g, o); /* mark as white just to avoid other barriers */
} }
......
...@@ -79,6 +79,7 @@ ...@@ -79,6 +79,7 @@
#define VALUEWEAKBIT 4 #define VALUEWEAKBIT 4
#define FIXEDBIT 5 #define FIXEDBIT 5
#define SFIXEDBIT 6 #define SFIXEDBIT 6
#define LFSBIT 6
#define READONLYBIT 7 #define READONLYBIT 7
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
...@@ -100,6 +101,13 @@ ...@@ -100,6 +101,13 @@
#define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT) #define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT)
#define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT) #define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT)
#define unfixedstack(x) resetbit((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) { \ #define luaC_checkGC(L) { \
condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment