Unverified Commit eaac369d authored by Johny Mattsson's avatar Johny Mattsson Committed by GitHub
Browse files

LFS support for ESP32 NodeMCU (#2801)

* Port LFS from ESP8266 to ESP32
parent 7cb61a27
BASE_NODEMCU_DIR:=$(dir $(lastword $(MAKEFILE_LIST)))
BASE_NODEMCU_BUILD_DIR:=$(BUILD_DIR_BASE)/base_nodemcu
ifeq ($(CONFIG_LUA_EMBED_LFS),y)
NODEMCU_LD_SCRIPT:= nodemcu_rodata_lfs.ld
else
NODEMCU_LD_SCRIPT:= nodemcu_rodata.ld
endif
$(BUILD_DIR_BASE)/$(PROJECT_NAME).elf: $(BASE_NODEMCU_BUILD_DIR)/ld_patched
$(BASE_NODEMCU_BUILD_DIR)/ld_patched: $(BUILD_DIR_BASE)/esp32/esp32.project.ld
"$(BASE_NODEMCU_DIR)/add_rodata_ld.sh" "$<" "$(BASE_NODEMCU_DIR)/ld/nodemcu_rodata.ld"
"$(BASE_NODEMCU_DIR)/add_rodata_ld.sh" "$<" "$(BASE_NODEMCU_DIR)/ld/$(NODEMCU_LD_SCRIPT)"
touch $@
#ifdef LUA_CROSS_COMPILER
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define true 1
#define false 0
#else
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
const char *lua_init_value = "@init.lua";
const char *c_getenv(const char *__string)
{
if (strcmp(__string, "LUA_INIT") == 0)
{
return lua_init_value;
}
return NULL;
}
#endif
#ifndef _SDK_OVERRIDES_STDLIB_H_
#define _SDK_OVERRIDES_STDLIB_H_
extern const char *c_getenv (const char *);
#endif
#ifndef __MODULE_H__
#define __MODULE_H__
#include "lrodefs.h"
#include "sdkconfig.h"
#include "lrotable.h"
/* Registering a module within NodeMCU is really easy these days!
*
......@@ -36,37 +36,37 @@
#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
#ifdef _MSC_VER
//on msvc it is necessary to go through more pre-processor hoops to get the
//section name built; string merging does not happen in the _declspecs.
//NOTE: linker magic is invoked via the magical '$' character. Caveat editor.
#define __TOKIFY(s) .rodata1$##s
#define __TOTOK(s) __TOKIFY(s)
#define __STRINGIFY(x) #x
#define __TOSTRING(x) __STRINGIFY(x)
#define __ROSECNAME(s) __TOSTRING(__TOTOK(s))
#define LOCK_IN_SECTION(s) __declspec ( allocate( __ROSECNAME(s) ) )
#else
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".rodata1." #s)))
#endif
#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 | CONFIG_LUA_MODULE_##cfgname
* where the CONFIG_LUA_MODULE_XYZ macro is first expanded to yield either
* an empty string (or 1) if the module has been enabled, or the literal
* CONFIG_LUA_MODULE_XYZ in the case it hasn't. Thus, the name of the variable
* ends up looking either like XYZ_module_enabled, or if not enabled,
* XYZ_module_enabledLUA_USE_MODULES_XYZ. This forms the basis for
* XYZ_module_enabledCONFIG_LUA_MODULE_XYZ. This forms the basis for
* letting the build system detect automatically (via nm) which modules need
* to be linked in.
*/
#define NODEMCU_MODULE(cfgname, luaname, map, initfunc) \
const LOCK_IN_SECTION(".lua_libs") \
luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
const LOCK_IN_SECTION(".lua_rotable") \
luaR_table MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(CONFIG_LUA_MODULE_,cfgname))) \
= { luaname, map }
/* System module registration support, not using CONFIG_LUA_MODULE_XYZ. */
#define BUILTIN_LIB_INIT(name, luaname, initfunc) \
const LOCK_IN_SECTION(".lua_libs") \
luaL_Reg MODULE_PASTE_(lua_lib_,name) = { luaname, initfunc }
#define BUILTIN_LIB(name, luaname, map) \
const LOCK_IN_SECTION(".lua_rotable") \
luaR_table MODULE_PASTE_(lua_rotable_,name) = { luaname, map }
#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
# error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)"
#endif
const LOCK_IN_SECTION(libs) \
luaR_entry MODULE_PASTE_(lua_lib_,cfgname) = { luaname, LRO_FUNCVAL(initfunc) }; \
const LOCK_IN_SECTION(rotable) \
luaR_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(CONFIG_LUA_MODULE_,cfgname))) \
= {luaname, LRO_ROVAL(map ## _map)}
#endif
/*
* Copyright 2016 Dius Computing Pty Ltd. All rights reserved.
* Copyright 2016-2019 Dius Computing Pty Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -36,6 +36,8 @@
#include "esp_event.h"
#include "module.h"
#include <assert.h>
#include <stdalign.h>
/**
* Similarly to how a NodeMCU module is registered, a module can register
......@@ -66,7 +68,10 @@ typedef struct {
extern nodemcu_esp_event_reg_t esp_event_cb_table;
#define NODEMCU_ESP_EVENT(evcode, func) \
static const LOCK_IN_SECTION(".esp_event_cb_table") \
static const LOCK_IN_SECTION(esp_event_cb_table) \
nodemcu_esp_event_reg_t MODULE_PASTE_(func,evcode) = { evcode, func };
_Static_assert(_Alignof(nodemcu_esp_event_reg_t) == 4, "Unexpected alignment of event registration - update linker script snippets to match!");
_Static_assert(sizeof(nodemcu_esp_event_reg_t) == 8, "Unexpected size of array member - update the linker script snippets to match!");
#endif
/* ----- Begin NodeMCU link-time arrays ------- */
. = ALIGN(4);
/* Don't change the alignment here without also updating the _Static_assert
* over in linit.c! */
. = ALIGN(8);
/* Link-time arrays containing the defs for the included modules */
lua_libs = ABSOLUTE(.);
lua_libs_map = ABSOLUTE(.);
KEEP(*(.lua_libs))
LONG(0) LONG(0) /* Null-terminate the array */
lua_rotable = ABSOLUTE(.);
/* Null-terminate the array, 24 bytes */
LONG(0) LONG(0) LONG(0) LONG(0) LONG(0) LONG(0)
/* Don't change the alignment here without also updating the _Static_assert
* over in linit.c! */
. = ALIGN(8);
lua_rotables_map = ABSOLUTE(.);
KEEP(*(.lua_rotable))
LONG(0) LONG(0) /* Null-terminate the array */
/* Null-terminate the array, 24 bytes */
LONG(0) LONG(0) LONG(0) LONG(0) LONG(0) LONG(0)
/* Don't change the alignment here without also updating the _Static_assert
* over in nodemcu_esp_event.h! */
. = ALIGN(4);
esp_event_cb_table = ABSOLUTE(.);
KEEP(*(.esp_event_cb_table))
LONG(0) LONG(0) /* Null-terminate the array */
KEEP(*(.lua_esp_event_cb_table))
LONG(0) LONG(0) /* Null-terminate the array, 8 bytes */
/* ----- End NodeMCU link-time arrays ------- */
/* ----- Begin NodeMCU link-time arrays ------- */
/* Don't change the alignment here without also updating the _Static_assert
* over in linit.c! */
. = ALIGN(8);
/* Link-time arrays containing the defs for the included modules */
lua_libs_map = ABSOLUTE(.);
KEEP(*(.lua_libs))
/* Null-terminate the array, 24 bytes */
LONG(0) LONG(0) LONG(0) LONG(0) LONG(0) LONG(0)
/* Don't change the alignment here without also updating the _Static_assert
* over in linit.c! */
. = ALIGN(8);
lua_rotables_map = ABSOLUTE(.);
KEEP(*(.lua_rotable))
/* Null-terminate the array, 24 bytes */
LONG(0) LONG(0) LONG(0) LONG(0) LONG(0) LONG(0)
/* Don't change the alignment here without also updating the _Static_assert
* over in nodemcu_esp_event.h! */
. = ALIGN(4);
esp_event_cb_table = ABSOLUTE(.);
KEEP(*(.lua_esp_event_cb_table))
LONG(0) LONG(0) /* Null-terminate the array, 8 bytes */
/* ----- End NodeMCU link-time arrays ------- */
/* ----- NodeMCU embedded LFS reserved area --------- */
. = ALIGN(4096); /* flash page alignment needed */
lua_flash_store_reserved = ABSOLUTE(.);
KEEP(*(.lfs.reserved))
/* ----- End NodeMCU embedded LFS reserved area ----- */
......@@ -15,64 +15,111 @@
#include "lauxlib.h"
#include "luaconf.h"
#include "module.h"
#include "sdkconfig.h"
#include "lstate.h"
#include <assert.h>
#include <stdalign.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 (CONFIG_LUA_BUILTIN_STRING)
extern const luaR_entry strlib[];
BUILTIN_LIB_INIT( STRING, LUA_STRLIBNAME, luaopen_string);
BUILTIN_LIB( STRING, LUA_STRLIBNAME, strlib);
LROT_EXTERN(strlib);
LROT_EXTERN(tab_funcs);
LROT_EXTERN(dblib);
LROT_EXTERN(co_funcs);
LROT_EXTERN(math);
#if defined(LUA_CROSS_COMPILER)
LROT_EXTERN(oslib);
//LROT_EXTERN(iolib);
#endif
/*
* The NodeMCU Lua initalisation has been adapted to use linker-based module
* registration. This uses a PSECT naming convention to allow the ROTable and
* initialisation function entries to be collected by the linker into two
* consoliated ROTables. This significantly simplifies adding new modules and
* configuring builds with a small subset of the total modules.
*
* This linker-based approach is not practical for cross compiler builds which
* must link on a range of platforms, and where we don't have control of PSECT
* placement. However unlike the target builds, the luac.cross builds only
* used a small and fixed list of libraries and so in this case the table can
* be defined in this source file, so in this case all library ROTables are
* defined here, avoiding the need for linker magic is avoided on host builds.
*
* Note that a separate ROTable is defined in lbaselib.c for the base functions
* and there is a metatable index cascade from _G to this base function table to
* the master rotables table. In the target build, the linker marshals the
* table, hence the LROT_BREAK() macros which don't 0 terminate the lists.
*/
#if defined(CONFIG_LUA_BUILTIN_TABLE)
extern const luaR_entry tab_funcs[];
BUILTIN_LIB_INIT( TABLE, LUA_TABLIBNAME, luaopen_table);
BUILTIN_LIB( TABLE, LUA_TABLIBNAME, tab_funcs);
#ifdef _MSC_VER
//MSVC requires us to declare these sections before we refer to them
#pragma section(__ROSECNAME(A), read)
#pragma section(__ROSECNAME(zzzzzzzz), read)
#pragma section(__ROSECNAME(libs), read)
#pragma section(__ROSECNAME(rotable), read)
//These help us to find the beginning and ending of the RO data. NOTE: linker
//magic is used; the section names are lexically sorted, so 'a' and 'z' are
//important to keep the other sections lexically between these two dummy
//variables. Check your mapfile output if you need to fiddle with this stuff.
const LOCK_IN_SECTION(A) char _ro_start[1] = {0};
const LOCK_IN_SECTION(zzzzzzzz) char _ro_end[1] = {0};
#endif
#if defined(CONFIG_LUA_BUILTIN_DEBUG)
extern const luaR_entry dblib[];
BUILTIN_LIB_INIT( DBG, LUA_DBLIBNAME, luaopen_debug);
BUILTIN_LIB( DBG, LUA_DBLIBNAME, dblib);
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(rotable) lua_rotables)
LROT_TABENTRY( string, strlib )
LROT_TABENTRY( table, tab_funcs )
LROT_TABENTRY( debug, dblib)
LROT_TABENTRY( coroutine, co_funcs )
LROT_TABENTRY( math, math )
LROT_TABENTRY( ROM, lua_rotables )
#ifdef LUA_CROSS_COMPILER
LROT_TABENTRY( os, oslib )
//LROT_TABENTRY( io, iolib )
LROT_END(lua_rotables, NULL, 0)
#else
LROT_BREAK(lua_rotables)
#endif
#if defined(LUA_USE_BUILTIN_OS)
extern const luaR_entry syslib[];
BUILTIN_LIB( OS, LUA_OSLIBNAME, syslib);
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(libs) lua_libs)
LROT_FUNCENTRY( _, luaopen_base )
LROT_FUNCENTRY( package, luaopen_package )
LROT_FUNCENTRY( string, luaopen_string )
LROT_FUNCENTRY( table, luaopen_table )
LROT_FUNCENTRY( debug, luaopen_debug )
#ifndef LUA_CROSS_COMPILER
LROT_BREAK(lua_rotables)
#else
LROT_FUNCENTRY( io, luaopen_io )
LROT_END( lua_libs, NULL, 0)
#endif
#if defined(CONFIG_LUA_BUILTIN_COROUTINE)
extern const luaR_entry co_funcs[];
BUILTIN_LIB( CO, LUA_COLIBNAME, co_funcs);
#ifndef LUA_CROSS_COMPILER
extern void luaL_dbgbreak(void);
#endif
#if defined(CONFIG_LUA_BUILTIN_MATH)
extern const luaR_entry math_map[];
BUILTIN_LIB( MATH, LUA_MATHLIBNAME, math_map);
#endif
void luaL_openlibs (lua_State *L) {
#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[];
lua_pushrotable(L, LROT_TABLEREF(lua_libs));
lua_pushnil(L); /* first key */
/* loop round and open libraries */
#ifndef LUA_CROSS_COMPILER
// luaL_dbgbreak(); // This is a test point for debugging library start ups
#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);
while (lua_next(L, -2) != 0) {
if (lua_islightfunction(L,-1) &&
fvalue(L->top-1)) { // only process function entries
lua_pushvalue(L, -2);
lua_call(L, 1, 0); // call luaopen_XXX(libname)
} else {
lua_pop(L, 1);
}
}
lua_pop(L, 1); //cleanup stack
}
#ifndef LUA_CROSS_COMPILER
# ifdef LUA_NUMBER_INTEGRAL
# define COMPARE <=
# else
# define COMPARE ==
# endif
_Static_assert(_Alignof(luaR_entry) COMPARE 8, "Unexpected alignment of module registration - update the linker script snippets to match!");
_Static_assert(sizeof(luaR_entry) COMPARE 24, "Unexpect size of array member - update the linker script snippets to match!");
#endif
......@@ -260,30 +260,29 @@ static int uart_getconfig(lua_State* L) {
}
// Module function map
static const LUA_REG_TYPE uart_map[] = {
{ LSTRKEY( "setup" ), LFUNCVAL( uart_setup ) },
{ LSTRKEY( "write" ), LFUNCVAL( uart_write ) },
{ LSTRKEY( "start" ), LFUNCVAL( uart_start ) },
{ LSTRKEY( "stop" ), LFUNCVAL( uart_stop ) },
{ LSTRKEY( "on" ), LFUNCVAL( uart_on ) },
{ LSTRKEY( "setmode" ), LFUNCVAL( uart_setmode ) },
{ LSTRKEY( "getconfig" ), LFUNCVAL( uart_getconfig ) },
{ LSTRKEY( "STOPBITS_1" ), LNUMVAL( PLATFORM_UART_STOPBITS_1 ) },
{ LSTRKEY( "STOPBITS_1_5" ), LNUMVAL( PLATFORM_UART_STOPBITS_1_5 ) },
{ LSTRKEY( "STOPBITS_2" ), LNUMVAL( PLATFORM_UART_STOPBITS_2 ) },
{ LSTRKEY( "PARITY_NONE" ), LNUMVAL( PLATFORM_UART_PARITY_NONE ) },
{ LSTRKEY( "PARITY_EVEN" ), LNUMVAL( PLATFORM_UART_PARITY_EVEN ) },
{ LSTRKEY( "PARITY_ODD" ), LNUMVAL( PLATFORM_UART_PARITY_ODD ) },
{ LSTRKEY( "FLOWCTRL_NONE" ), LNUMVAL( PLATFORM_UART_FLOW_NONE ) },
{ LSTRKEY( "FLOWCTRL_CTS" ), LNUMVAL( PLATFORM_UART_FLOW_CTS ) },
{ LSTRKEY( "FLOWCTRL_RTS" ), LNUMVAL( PLATFORM_UART_FLOW_RTS ) },
{ LSTRKEY( "MODE_UART" ), LNUMVAL( PLATFORM_UART_MODE_UART ) },
{ LSTRKEY( "MODE_RS485_COLLISION_DETECT" ), LNUMVAL( PLATFORM_UART_MODE_RS485_COLLISION_DETECT ) },
{ LSTRKEY( "MODE_RS485_APP_CONTROL" ), LNUMVAL( PLATFORM_UART_MODE_RS485_APP_CONTROL ) },
{ LSTRKEY( "MODE_RS485_HALF_DUPLEX" ), LNUMVAL( PLATFORM_UART_MODE_HALF_DUPLEX ) },
{ LSTRKEY( "MODE_IRDA" ), LNUMVAL( PLATFORM_UART_MODE_IRDA ) },
{ LNILKEY, LNILVAL }
};
LROT_BEGIN(uart)
LROT_FUNCENTRY( setup, uart_setup )
LROT_FUNCENTRY( write, uart_write )
LROT_FUNCENTRY( start, uart_start )
LROT_FUNCENTRY( stop, uart_stop )
LROT_FUNCENTRY( on, uart_on )
LROT_FUNCENTRY( setmode, uart_setmode )
LROT_FUNCENTRY( getconfig, uart_getconfig )
LROT_NUMENTRY( STOPBITS_1, PLATFORM_UART_STOPBITS_1 )
LROT_NUMENTRY( STOPBITS_1_5, PLATFORM_UART_STOPBITS_1_5 )
LROT_NUMENTRY( STOPBITS_2, PLATFORM_UART_STOPBITS_2 )
LROT_NUMENTRY( PARITY_NONE, PLATFORM_UART_PARITY_NONE )
LROT_NUMENTRY( PARITY_EVEN, PLATFORM_UART_PARITY_EVEN )
LROT_NUMENTRY( PARITY_ODD, PLATFORM_UART_PARITY_ODD )
LROT_NUMENTRY( FLOWCTRL_NONE, PLATFORM_UART_FLOW_NONE )
LROT_NUMENTRY( FLOWCTRL_CTS, PLATFORM_UART_FLOW_CTS )
LROT_NUMENTRY( FLOWCTRL_RTS, PLATFORM_UART_FLOW_RTS )
LROT_NUMENTRY( MODE_UART, PLATFORM_UART_MODE_UART )
LROT_NUMENTRY( MODE_RS485_COLLISION_DETECT, PLATFORM_UART_MODE_RS485_COLLISION_DETECT )
LROT_NUMENTRY( MODE_RS485_APP_CONTROL, PLATFORM_UART_MODE_RS485_APP_CONTROL )
LROT_NUMENTRY( MODE_RS485_HALF_DUPLEX, PLATFORM_UART_MODE_HALF_DUPLEX )
LROT_NUMENTRY( MODE_IRDA, PLATFORM_UART_MODE_IRDA )
LROT_END(uart, NULL, 0)
int luaopen_uart( lua_State *L ) {
uart_status_t *us;
......@@ -297,4 +296,4 @@ int luaopen_uart( lua_State *L ) {
return 0;
}
NODEMCU_MODULE(UART, "uart", uart_map, luaopen_uart);
NODEMCU_MODULE(UART, "uart", uart, luaopen_uart);
SHELL:=/bin/bash
ifeq ($(CONFIG_LUA_EMBED_LFS),y)
COMPONENT_OBJS := $(COMPONENT_BUILD_DIR)/luac_out.o
COMPONENT_EXTRA_CLEAN := $(COMPONENT_OBJS) $(COMPONENT_BUILD_DIR)/luac_out.o.bin
COMPONENT_ADD_LINKER_DEPS := $(COMPONENT_BUILD_DIR)/luac_out.o
EMBEDDED_LFS_DATA:= $(BUILD_DIR_BASE)/luac.out
$(COMPONENT_BUILD_DIR)/luac_out.o: $(EMBEDDED_LFS_DATA)
echo "embedding luac.out into object file $@..."
dd if=/dev/zero bs=1 count=$$(( $(CONFIG_LUA_EMBEDDED_FLASH_STORE) )) of="$@.bin" status=none
dd if="$(EMBEDDED_LFS_DATA)" conv=notrunc of="$@.bin" status=none
cd $(dir $@) && $(OBJCOPY) --input-target binary --output-target elf32-xtensa-le --binary-architecture xtensa --rename-section .data=.lfs.reserved --redefine-sym _binary_luac_out_o_bin_start=lua_flash_store_reserved "$(notdir $@.bin)" "$@"
$(EMBEDDED_LFS_DATA):
touch $@
endif
......@@ -10,9 +10,9 @@
#include "lua.h"
//#include C_HEADER_ASSERT
#include C_HEADER_MATH
#include C_HEADER_STRING
//#include <assert.h>
#include <math.h>
#include <string.h>
#include "lapi.h"
#include "ldebug.h"
#include "ldo.h"
......@@ -412,8 +412,9 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
case LUA_TLIGHTUSERDATA:
return lua_touserdata(L, idx);
case LUA_TROTABLE:
return rvalue(o);
case LUA_TLIGHTFUNCTION:
return pvalue(o);
return fvalue(o);
default: return NULL;
}
}
......@@ -458,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);
......
......@@ -7,12 +7,13 @@
#define LUAC_CROSS_FILE
#include "lua.h"
#include C_HEADER_CTYPE
#include C_HEADER_ERRNO
#include C_HEADER_STDIO
#include C_HEADER_STDLIB
#include C_HEADER_STRING
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef LUA_CROSS_COMPILER
#include "esp_system.h"
#include "vfs.h"
#else
#endif
......@@ -44,6 +45,149 @@
#define LUA_USECCLOSURES 0
#define LUA_USELIGHTFUNCTIONS 1
//#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
** DEBUG_ALLOCATOR is defined. It is a cutdown version of the allocator
** used in the Lua Test Suite -- a compromise between the ability catch
** most alloc/free errors and overruns and working within the RAM limits
** of the ESP8266 architecture. ONLY FOR HEAVY HACKERS
** =======================================================================
*/
#define this_realloc debug_realloc
#define MARK 0x55 /* 01010101 (a nice pattern) */
#define MARKSIZE 2*sizeof(size_t) /* size of marks after each block */
#define fillmem(mem,size) memset(mem, ~MARK, size)
typedef union MemHeader MemHeader;
union MemHeader {
L_Umaxalign a; /* ensures maximum alignment for Header */
struct {
size_t size;
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) ? '>' : ' ';
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) {
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 */
free(block); /* actually free block */
mc.numblocks--; /* update counts */
mc.total -= size;
}
}
void *debug_realloc (void *b, size_t oldsize, size_t size) {
MemHeader *block = cast(MemHeader *, b);
ASSERT(checkBlocks());
if (!marker[0]) memset(marker, MARK, MARKSIZE);
if (block == NULL) {
oldsize = 0;
} else {
block--; /* go to real header */
ASSERT(!memcmp(block->mark, marker, MARKSIZE))
ASSERT(oldsize == block->size);
ASSERT(!memcmp(cast(char *, b)+oldsize, marker, MARKSIZE));
}
if (size == 0) {
freeblock(block);
return NULL;
} else if (size > oldsize && mc.total+size-oldsize > mc.memlimit)
return NULL; /* fake a memory allocation error */
else {
MemHeader *newblock;
size_t commonsize = (oldsize < size) ? oldsize : size;
size_t realsize = sizeof(MemHeader) + size + MARKSIZE;
newblock = cast(MemHeader *, malloc(realsize)); /* alloc a new block */
if (newblock == NULL)
return NULL; /* really out of memory? */
if (block) {
memcpy(newblock + 1, block + 1, commonsize); /* copy old contents */
freeblock(block); /* erase (and check) old copy */
}
/* initialize new part of the block with something weird */
if (size > commonsize)
fillmem(cast(char *, newblock + 1) + commonsize, size - commonsize);
/* initialize marks after block */
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;
mc.numblocks++;
return (newblock + 1);
}
}
/* }====================================================================== */
#else
#define this_realloc(p,os,s) realloc(p,s)
#endif /* DEBUG_ALLOCATOR */
/*
** {======================================================
** Error-report functions
......@@ -270,11 +414,7 @@ LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
LUALIB_API void (luaL_register_light) (lua_State *L, const char *libname,
const luaL_Reg *l) {
#if LUA_OPTIMIZE_MEMORY > 0
luaI_openlib(L, libname, l, 0, LUA_USELIGHTFUNCTIONS);
#else
luaI_openlib(L, libname, l, 0, LUA_USECCLOSURES);
#endif
}
static int libsize (const luaL_Reg *l) {
......@@ -411,14 +551,7 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
if (e == NULL) e = fname + strlen(fname);
lua_pushlstring(L, fname, e - fname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) {
/* If looking for a global variable, check the rotables too */
void *ptable = luaR_findglobal(fname, e - fname);
if (ptable) {
lua_pop(L, 1);
lua_pushrotable(L, ptable);
}
}
if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
......@@ -632,7 +765,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
/* skip eventual `#!...' */
while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) {}
lf.extraline = 0;
}
ungetc(c, lf.f);
......@@ -700,12 +834,12 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) {
lf.f = vfs_open(filename, "r");
if (!lf.f) return errfsfile(L, "open", fnameindex);
}
// if(vfs_size(lf.f)>LUAL_BUFFERSIZE)
// if(fs_size(lf.f)>LUAL_BUFFERSIZE)
// return luaL_error(L, "file is too big");
c = vfs_getc(lf.f);
if (c == '#') { /* Unix exec. file? */
lf.extraline = 1;
while ((c = vfs_getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
while ((c = vfs_getc(lf.f)) != VFS_EOF && c != '\n') ; /* skip first line */
if (c == '\n') c = vfs_getc(lf.f);
}
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
......@@ -713,7 +847,7 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) {
lf.f = vfs_open(filename, "r"); /* reopen in binary mode */
if (!lf.f) return errfsfile(L, "reopen", fnameindex);
/* skip eventual `#!...' */
while ((c = vfs_getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
while ((c = vfs_getc(lf.f)) != VFS_EOF && c != LUA_SIGNATURE[0]) ;
lf.extraline = 0;
}
vfs_ungetc(c, lf.f);
......@@ -786,11 +920,20 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
void *nptr;
if (nsize == 0) {
#ifdef DEBUG_ALLOCATOR
return (void *)this_realloc(ptr, osize, nsize);
#else
free(ptr);
return NULL;
#endif
}
if (L != NULL && (mode & EGC_ALWAYS)) /* always collect memory if requested */
luaC_fullgc(L);
#ifndef LUA_CROSS_COMPILER
if (L != NULL && (mode & EGC_ON_MEM_LIMIT) && G(L)->memlimit < 0 &&
(esp_get_free_heap_size() < (-G(L)->memlimit)))
luaC_fullgc(L);
#endif
if(nsize > osize && L != NULL) {
#if defined(LUA_STRESS_EMERGENCY_GC)
luaC_fullgc(L);
......@@ -798,16 +941,19 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
if(G(L)->memlimit > 0 && (mode & EGC_ON_MEM_LIMIT) && l_check_memlimit(L, nsize - osize))
return NULL;
}
nptr = (void *)realloc(ptr, nsize);
nptr = (void *)this_realloc(ptr, osize, nsize);
if (nptr == NULL && L != NULL && (mode & EGC_ON_ALLOC_FAILURE)) {
luaC_fullgc(L); /* emergency full collection. */
nptr = (void *)realloc(ptr, nsize); /* try allocation again */
nptr = (void *)this_realloc(ptr, osize, nsize); /* try allocation again */
}
return nptr;
}
LUALIB_API void luaL_assertfail(const char *file, int line, const char *message) {
printf("ASSERT@%s(%d): %s\n", file, line, message);
#if defined(LUA_CROSS_COMPILER)
exit(1);
#endif
}
static int panic (lua_State *L) {
......
......@@ -11,9 +11,9 @@
#define LUAC_CROSS_FILE
#include "lua.h"
#include C_HEADER_STDIO
#include C_HEADER_STRING
#include C_HEADER_STDLIB
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
......@@ -462,73 +462,59 @@ static int luaB_newproxy (lua_State *L) {
return 1;
}
#define LUA_BASELIB_FUNCLIST\
{LSTRKEY("assert"), LFUNCVAL(luaB_assert)},\
{LSTRKEY("collectgarbage"), LFUNCVAL(luaB_collectgarbage)},\
{LSTRKEY("dofile"), LFUNCVAL(luaB_dofile)},\
{LSTRKEY("error"), LFUNCVAL(luaB_error)},\
{LSTRKEY("gcinfo"), LFUNCVAL(luaB_gcinfo)},\
{LSTRKEY("getfenv"), LFUNCVAL(luaB_getfenv)},\
{LSTRKEY("getmetatable"), LFUNCVAL(luaB_getmetatable)},\
{LSTRKEY("loadfile"), LFUNCVAL(luaB_loadfile)},\
{LSTRKEY("load"), LFUNCVAL(luaB_load)},\
{LSTRKEY("loadstring"), LFUNCVAL(luaB_loadstring)},\
{LSTRKEY("next"), LFUNCVAL(luaB_next)},\
{LSTRKEY("pcall"), LFUNCVAL(luaB_pcall)},\
{LSTRKEY("print"), LFUNCVAL(luaB_print)},\
{LSTRKEY("rawequal"), LFUNCVAL(luaB_rawequal)},\
{LSTRKEY("rawget"), LFUNCVAL(luaB_rawget)},\
{LSTRKEY("rawset"), LFUNCVAL(luaB_rawset)},\
{LSTRKEY("select"), LFUNCVAL(luaB_select)},\
{LSTRKEY("setfenv"), LFUNCVAL(luaB_setfenv)},\
{LSTRKEY("setmetatable"), LFUNCVAL(luaB_setmetatable)},\
{LSTRKEY("tonumber"), LFUNCVAL(luaB_tonumber)},\
{LSTRKEY("tostring"), LFUNCVAL(luaB_tostring)},\
{LSTRKEY("type"), LFUNCVAL(luaB_type)},\
{LSTRKEY("unpack"), LFUNCVAL(luaB_unpack)},\
{LSTRKEY("xpcall"), LFUNCVAL(luaB_xpcall)}
#if LUA_OPTIMIZE_MEMORY == 2
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE base_funcs_list[] = {
LUA_BASELIB_FUNCLIST,
{LNILKEY, LNILVAL}
};
#endif
#include "lrotable.h"
static int luaB_index(lua_State *L) {
#if LUA_OPTIMIZE_MEMORY == 2
int fres;
if ((fres = luaR_findfunction(L, base_funcs_list)) != 0)
return fres;
#endif
const char *keyname = luaL_checkstring(L, 2);
if (!strcmp(keyname, "_VERSION")) {
lua_pushliteral(L, LUA_VERSION);
return 1;
}
void *res = luaR_findglobal(keyname, strlen(keyname));
if (!res)
return 0;
else {
lua_pushrotable(L, res);
return 1;
}
}
LROT_EXTERN(lua_rotable_base);
static const luaL_Reg base_funcs[] = {
#if LUA_OPTIMIZE_MEMORY != 2
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 0
#include "lrodefs.h"
LUA_BASELIB_FUNCLIST,
#endif
{"__index", luaB_index},
{NULL, NULL}
};
/*
* Separate ROTables are used for the base functions and library ROTables, with
* the base functions ROTable declared below. The library ROTable is chained
* from this using its __index meta-method.
*
* ESP builds use specific linker directives to marshal all the ROTable entries
* for the library modules into a single ROTable in the PSECT ".lua_rotable".
* This is not practical on Posix builds using a standard GNU link, so the
* equivalent ROTable for the core libraries defined in linit.c for the cross-
* compiler build.
*/
LROT_EXTERN(lua_rotables);
LROT_PUBLIC_BEGIN(base_func_meta)
LROT_TABENTRY( __index, lua_rotables )
LROT_END(base_func, base_func_meta, LROT_MASK_INDEX)
LROT_PUBLIC_BEGIN(base_func)
LROT_FUNCENTRY(assert, luaB_assert)
LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage)
LROT_FUNCENTRY(dofile, luaB_dofile)
LROT_FUNCENTRY(error, luaB_error)
LROT_FUNCENTRY(gcinfo, luaB_gcinfo)
LROT_FUNCENTRY(getfenv, luaB_getfenv)
LROT_FUNCENTRY(getmetatable, luaB_getmetatable)
LROT_FUNCENTRY(loadfile, luaB_loadfile)
LROT_FUNCENTRY(load, luaB_load)
LROT_FUNCENTRY(loadstring, luaB_loadstring)
LROT_FUNCENTRY(next, luaB_next)
LROT_FUNCENTRY(pcall, luaB_pcall)
LROT_FUNCENTRY(print, luaB_print)
LROT_FUNCENTRY(rawequal, luaB_rawequal)
LROT_FUNCENTRY(rawget, luaB_rawget)
LROT_FUNCENTRY(rawset, luaB_rawset)
LROT_FUNCENTRY(select, luaB_select)
LROT_FUNCENTRY(setfenv, luaB_setfenv)
LROT_FUNCENTRY(setmetatable, luaB_setmetatable)
LROT_FUNCENTRY(tonumber, luaB_tonumber)
LROT_FUNCENTRY(tostring, luaB_tostring)
LROT_FUNCENTRY(type, luaB_type)
LROT_FUNCENTRY(unpack, luaB_unpack)
LROT_FUNCENTRY(xpcall, luaB_xpcall)
LROT_TABENTRY(__metatable, base_func_meta)
LROT_END(base_func, base_func_meta, LROT_MASK_INDEX)
LROT_BEGIN(G_meta)
LROT_TABENTRY( __index, base_func )
LROT_END(G_meta, NULL, 0)
/*
......@@ -659,18 +645,14 @@ static int luaB_corunning (lua_State *L) {
return 1;
}
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE co_funcs[] = {
{LSTRKEY("create"), LFUNCVAL(luaB_cocreate)},
{LSTRKEY("resume"), LFUNCVAL(luaB_coresume)},
{LSTRKEY("running"), LFUNCVAL(luaB_corunning)},
{LSTRKEY("status"), LFUNCVAL(luaB_costatus)},
{LSTRKEY("wrap"), LFUNCVAL(luaB_cowrap)},
{LSTRKEY("yield"), LFUNCVAL(luaB_yield)},
{LNILKEY, LNILVAL}
};
LROT_PUBLIC_BEGIN(co_funcs)
LROT_FUNCENTRY( create, luaB_cocreate )
LROT_FUNCENTRY( resume, luaB_coresume )
LROT_FUNCENTRY( running, luaB_corunning )
LROT_FUNCENTRY( status, luaB_costatus )
LROT_FUNCENTRY( wrap, luaB_cowrap )
LROT_FUNCENTRY( yield, luaB_yield )
LROT_END (co_funcs, NULL, 0)
/* }====================================================== */
......@@ -682,20 +664,18 @@ static void auxopen (lua_State *L, const char *name,
lua_setfield(L, -2, name);
}
static void base_open (lua_State *L) {
/* set global _G */
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G");
/* open lib into global table */
luaL_register_light(L, "_G", base_funcs);
#if LUA_OPTIMIZE_MEMORY > 0
lua_pushvalue(L, -1);
lua_setmetatable(L, -2);
#else
luaL_register_light(L, "_G", &((luaL_Reg) {0}));
lua_pushrotable(L, LROT_TABLEREF(G_meta));
lua_setmetatable(L, LUA_GLOBALSINDEX);
lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */
#endif
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
auxopen(L, "pairs", luaB_pairs, luaB_next);
......@@ -712,10 +692,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
}
......@@ -10,7 +10,7 @@
#define LUAC_CROSS_FILE
#include "lua.h"
#include C_HEADER_STDLIB
#include <stdlib.h>
#include "lcode.h"
#include "ldebug.h"
......
......@@ -10,12 +10,14 @@
#define LUAC_CROSS_FILE
#include "lua.h"
#include C_HEADER_STDIO
#include C_HEADER_STDLIB
#include C_HEADER_STRING
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "lualib.h"
#include "lstring.h"
#include "lflash.h"
#include "lrotable.h"
#include "sdkconfig.h"
......@@ -25,6 +27,39 @@ static int db_getregistry (lua_State *L) {
return 1;
}
static int db_getstrings (lua_State *L) {
size_t i,n=0;
stringtable *tb;
GCObject *o;
#ifndef 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 CONFIG_LUA_BUILTIN_DEBUG_MINIMAL
static int db_getmetatable (lua_State *L) {
......@@ -384,33 +419,30 @@ static int db_errorfb (lua_State *L) {
return 1;
}
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const LUA_REG_TYPE dblib[] = {
LROT_PUBLIC_BEGIN(dblib)
#ifndef CONFIG_LUA_BUILTIN_DEBUG_MINIMAL
#if defined(LUA_CROSS_COMPILER)
{LSTRKEY("debug"), LFUNCVAL(db_debug)},
#endif // defined(LUA_CROSS_COMPILER)
{LSTRKEY("getfenv"), LFUNCVAL(db_getfenv)},
{LSTRKEY("gethook"), LFUNCVAL(db_gethook)},
{LSTRKEY("getinfo"), LFUNCVAL(db_getinfo)},
{LSTRKEY("getlocal"), LFUNCVAL(db_getlocal)},
LROT_FUNCENTRY( debug, db_debug )
#endif
LROT_FUNCENTRY( getfenv, db_getfenv )
LROT_FUNCENTRY( gethook, db_gethook )
LROT_FUNCENTRY( getinfo, db_getinfo )
LROT_FUNCENTRY( getlocal, db_getlocal )
#endif
{LSTRKEY("getregistry"), LFUNCVAL(db_getregistry)},
LROT_FUNCENTRY( getregistry, db_getregistry )
LROT_FUNCENTRY( getstrings, db_getstrings )
#ifndef CONFIG_LUA_BUILTIN_DEBUG_MINIMAL
{LSTRKEY("getmetatable"), LFUNCVAL(db_getmetatable)},
{LSTRKEY("getupvalue"), LFUNCVAL(db_getupvalue)},
{LSTRKEY("setfenv"), LFUNCVAL(db_setfenv)},
{LSTRKEY("sethook"), LFUNCVAL(db_sethook)},
{LSTRKEY("setlocal"), LFUNCVAL(db_setlocal)},
{LSTRKEY("setmetatable"), LFUNCVAL(db_setmetatable)},
{LSTRKEY("setupvalue"), LFUNCVAL(db_setupvalue)},
LROT_FUNCENTRY( getmetatable, db_getmetatable )
LROT_FUNCENTRY( getupvalue, db_getupvalue )
LROT_FUNCENTRY( setfenv, db_setfenv )
LROT_FUNCENTRY( sethook, db_sethook )
LROT_FUNCENTRY( setlocal, db_setlocal )
LROT_FUNCENTRY( setmetatable, db_setmetatable )
LROT_FUNCENTRY( setupvalue, db_setupvalue )
#endif
{LSTRKEY("traceback"), LFUNCVAL(db_errorfb)},
{LNILKEY, LNILVAL}
};
LROT_FUNCENTRY( traceback, db_errorfb )
LROT_END(dblib, NULL, 0)
LUALIB_API int luaopen_debug (lua_State *L) {
LREGISTER(L, LUA_DBLIBNAME, dblib);
return 0;
}
......@@ -10,7 +10,7 @@
#define LUAC_CROSS_FILE
#include "lua.h"
#include C_HEADER_STRING
#include <string.h>
#include "lapi.h"
#include "lcode.h"
......
......@@ -11,7 +11,7 @@
#define LUAC_CROSS_FILE
#include "lua.h"
#include C_HEADER_STRING
#include <string.h>
#include "ldebug.h"
#include "ldo.h"
......@@ -106,7 +106,7 @@ void luaD_throw (lua_State *L, int errcode) {
lua_unlock(L);
G(L)->panic(L);
}
// c_exit(EXIT_FAILURE);
// exit(EXIT_FAILURE);
}
}
......@@ -144,8 +144,11 @@ static void correctstack (lua_State *L, TValue *oldstack) {
void luaD_reallocstack (lua_State *L, int newsize) {
TValue *oldstack = L->stack;
int realsize = newsize + 1 + EXTRA_STACK;
int block_status = is_block_gc(L);
lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
set_block_gc(L); /* The GC MUST be blocked during stack reallocaiton */
luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
if (!block_status) unset_block_gc(L); /* Honour the previous block status */
L->stacksize = realsize;
L->stack_last = L->stack+newsize;
correctstack(L, oldstack);
......
......@@ -9,7 +9,7 @@
#define LUAC_CROSS_FILE
#include "lua.h"
#include C_HEADER_STRING
#include <string.h>
#include "lobject.h"
#include "lstate.h"
......@@ -47,7 +47,7 @@ static void DumpChar(int y, DumpState* D)
static void Align4(DumpState *D)
{
while(D->wrote&3)
while(D->wrote&3 && D->status==0)
DumpChar(0,D);
}
......
......@@ -3,7 +3,7 @@
#include "legc.h"
#include "lstate.h"
void legc_set_mode(lua_State *L, int mode, unsigned limit) {
void legc_set_mode(lua_State *L, int mode, int limit) {
global_State *g = G(L);
g->egcmode = mode;
......
......@@ -11,7 +11,7 @@
#define EGC_ON_MEM_LIMIT 2 // run EGC when an upper memory limit is hit
#define EGC_ALWAYS 4 // always run EGC before an allocation
void legc_set_mode(lua_State *L, int mode, unsigned limit);
void legc_set_mode(lua_State *L, int mode, int limit);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment