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

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

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

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

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

The uart module got relocated from base_nodemcu to the modules component
properly, after I worked out how to force its inclusion using Kconfig alone.
parent f123d462
// Lua EGC (Emergeny Garbage Collector) interface
#ifndef __LEGC_H__
#define __LEGC_H__
#include "lstate.h"
// EGC operations modes
#define EGC_NOT_ACTIVE 0 // EGC disabled
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
#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, int limit);
#endif
[sections:lua_libs]
entries:
.lua_libs
[sections:lua_libs_end_marker]
entries:
.lua_libs_end_marker
[sections:lua_rotable]
entries:
.lua_rotable
[sections:lua_rotable_end_marker]
entries:
.lua_rotable_end_marker
[scheme:lua_arrays]
entries:
lua_libs -> flash_rodata
lua_libs_end_marker -> flash_rodata
lua_rotable -> flash_rodata
lua_rotable_end_marker -> flash_rodata
# Important: don't change the alignments below without also updating the
# _Static_assert over in linit.c!
[mapping:lua]
archive: *
entries:
* (lua_arrays);
lua_libs -> flash_rodata KEEP() ALIGN(8) SURROUND(lua_libs_map),
lua_libs_end_marker -> flash_rodata KEEP(),
lua_rotable -> flash_rodata KEEP() ALIGN(8) SURROUND(lua_rotables_map),
lua_rotable_end_marker -> flash_rodata KEEP()
/* Read-only tables for Lua */
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
#include "lrotable.h"
#include "lauxlib.h"
#include "lstring.h"
#include "lobject.h"
#include "lapi.h"
#ifdef _MSC_VER
#define ALIGNED_STRING __declspec( align( 4 ) ) char
#else
#define ALIGNED_STRING __attribute__((aligned(4))) char
#endif
#define LA_LINES 32
#define LA_SLOTS 4
//#define COLLECT_STATS
/*
* All keyed ROtable access passes through luaR_findentry(). ROTables
* are simply a list of <key><TValue value> pairs. The existing algo
* did a linear scan of this vector of pairs looking for a match.
*
* A N×M lookaside cache has been added, with a simple hash on the key's
* TString addr and the ROTable addr to identify one of N lines. Each
* line has M slots which are scanned. This is all done in RAM and is
* perhaps 20x faster than the corresponding random Flash accesses which
* will cause flash faults.
*
* If a match is found and the table addresses match, then this entry is
* probed first. In practice the hit-rate here is over 99% so the code
* rarely fails back to doing the linear scan in ROM.
*
* Note that this hash does a couple of prime multiples and a modulus 2^X
* with is all evaluated in H/W, and adequately randomizes the lookup.
*/
#define HASH(a,b) ((((519*(size_t)(a)))>>4) + ((b) ? (b)->tsv.hash: 0))
static struct {
unsigned hash;
unsigned addr:24;
unsigned ndx:8;
} cache[LA_LINES][LA_SLOTS];
#ifdef COLLECT_STATS
unsigned cache_stats[3];
#define COUNT(i) cache_stats[i]++
#else
#define COUNT(i)
#endif
static int lookup_cache(unsigned hash, ROTable *rotable) {
int i = (hash>>2) & (LA_LINES-1), j;
for (j = 0; j<LA_SLOTS; j++) {
if (cache[i][j].hash == hash &&
((size_t)rotable & 0xffffffu) == cache[i][j].addr) {
COUNT(0);
return cache[i][j].ndx;
}
}
COUNT(1);
return -1;
}
static void update_cache(unsigned hash, ROTable *rotable, unsigned ndx) {
int i = (hash)>>2 & (LA_LINES-1), j;
COUNT(2);
if (ndx>0xffu)
return;
for (j = LA_SLOTS-1; j>0; j--)
cache[i][j] = cache[i][j-1];
cache[i][0].hash = hash;
cache[i][0].addr = (size_t) rotable;
cache[i][0].ndx = ndx;
}
/*
* Find a string key entry in a rotable and return it. Note that this internally
* uses a null key to denote a metatable search.
*/
const TValue* luaR_findentry(ROTable *rotable, TString *key, unsigned *ppos) {
const luaR_entry *pentry = rotable;
static const ALIGNED_STRING metatablestr[] = "__metatable";
const char *strkey = key ? getstr(key) : metatablestr;
unsigned hash = HASH(rotable, key);
unsigned i = 0;
int j = lookup_cache(hash, rotable);
unsigned l = key ? key->tsv.len : sizeof("__metatable")-1;
if (pentry) {
if (j >= 0 && !strcmp(pentry[j].key, strkey)) {
if (ppos)
*ppos = j;
//printf("%3d hit %p %s\n", (hash>>2) & (LA_LINES-1), rotable, strkey);
return &pentry[j].value;
}
/*
* The invariants for 1st word comparison are deferred to here since they
* aren't needed if there is a cache hit. Note that the termination null
* is included so a "on\0" has a mask of 0xFFFFFF and "a\0" has 0xFFFF.
*/
unsigned name4, mask4 = l > 2 ? (~0u) : (~0u)>>((3-l)*8);
memcpy(&name4, strkey, sizeof(name4));
for(;pentry->key != NULL; i++, pentry++) {
if (((*(unsigned *)pentry->key ^ name4) & mask4) == 0 &&
!strcmp(pentry->key, strkey)) {
//printf("%p %s hit after %d probes \n", rotable, strkey, (int)(pentry-rotable));
if (ppos)
*ppos = i;
update_cache(hash, rotable, pentry - rotable);
//printf("%3d %3d %p %s\n", (hash>>2) & (LA_LINES-1), (int)(pentry-rotable), rotable, strkey);
return &pentry->value;
}
}
}
//printf("%p %s miss after %d probes \n", rotable, strkey, (int)(pentry-rotable));
return luaO_nilobject;
}
/* Find the metatable of a given table */
void* luaR_getmeta(ROTable *rotable) {
const TValue *res = luaR_findentry(rotable, NULL, NULL);
return res && ttisrotable(res) ? rvalue(res) : NULL;
}
static void luaR_next_helper(lua_State *L, ROTable *pentries, int pos,
TValue *key, TValue *val) {
if (pentries[pos].key) {
/* Found an entry */
setsvalue(L, key, luaS_new(L, pentries[pos].key));
setobj2s(L, val, &pentries[pos].value);
} else {
setnilvalue(key);
setnilvalue(val);
}
}
/* next (used for iteration) */
void luaR_next(lua_State *L, ROTable *rotable, TValue *key, TValue *val) {
unsigned keypos;
/* Special case: if key is nil, return the first element of the rotable */
if (ttisnil(key))
luaR_next_helper(L, rotable, 0, key, val);
else if (ttisstring(key)) {
/* Find the previous key again */
luaR_findentry(rotable, rawtsvalue(key), &keypos);
/* Advance to next key */
keypos ++;
luaR_next_helper(L, rotable, keypos, key, val);
}
}
/* Read-only tables for Lua */
#ifndef lrotable_h
#define lrotable_h
#include "lua.h"
#include "luaconf.h"
#include "lobject.h"
#include "llimits.h"
/* Macros one can use to define rotable entries */
#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}
#ifdef LUA_CROSS_COMPILER
#define LRO_STRKEY(k) k
#else
#define LRO_STRKEY(k) ((__attribute__((aligned(4))) char *) k)
#endif
#define LROT_TABLE(t) static const LUA_REG_TYPE t ## _map[];
#define LROT_PUBLIC_TABLE(t) const LUA_REG_TYPE t ## _map[];
#define LROT_TABLEREF(t) ((void *) t ## _map)
#define LROT_BEGIN(t) static const LUA_REG_TYPE t ## _map [] = {
#define LROT_PUBLIC_BEGIN(t) const LUA_REG_TYPE t ## _map[] = {
#define LROT_EXTERN(t) extern const LUA_REG_TYPE t ## _map[]
#define LROT_TABENTRY(n,t) {LRO_STRKEY(#n), LRO_ROVAL(t ## _map)},
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_NUMENTRY(n,x) {LRO_STRKEY(#n), LRO_NUMVAL(x)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA((void *) x)},
#define LROT_END(t,mt, f) {NULL, LRO_NILVAL} };
#define LROT_BREAK(t) };
#define LUA_REG_TYPE luaR_entry
#define LREGISTER(L, name, table) return 0
/* Maximum length of a rotable name and of a string key*/
#define LUA_MAX_ROTABLE_NAME 32
/* Type of a numeric key in a rotable */
typedef int luaR_numkey;
/* An entry in the read only table */
typedef struct luaR_entry {
const char *key;
const TValue value;
} luaR_entry;
/*
* The current ROTable implmentation is a vector of luaR_entry terminated by a
* nil record. The convention is to use ROtable * to refer to the entire vector
* as a logical ROTable.
*/
typedef const struct luaR_entry ROTable;
const TValue* luaR_findentry(ROTable *tab, TString *key, unsigned *ppos);
const TValue* luaR_findentryN(ROTable *tab, luaR_numkey numkey, unsigned *ppos);
void luaR_next(lua_State *L, ROTable *tab, TValue *key, TValue *val);
void* luaR_getmeta(ROTable *tab);
int luaR_isrotable(void *p);
/*
* Set inRO check depending on platform. Note that this implementation needs
* to work on both the host (luac.cross) and ESP targets. The luac.cross
* VM is used for the -e option, and is primarily used to be able to debug
* VM changes on the more developer-friendly hot gdb environment.
*/
#if defined(LUA_CROSS_COMPILER)
#if defined(_MSC_VER)
//msvc build uses these dummy vars to locate the beginning and ending addresses of the RO data
extern const char _ro_start[], _ro_end[];
#define IN_RODATA_AREA(p) (((const char*)(p)) >= _ro_start && ((const char *)(p)) <= _ro_end)
#else /* one of the POSIX variants */
#if defined(__CYGWIN__)
#define _RODATA_END __end__
#elif defined(__MINGW32__)
#define _RODATA_END end
#else
#define _RODATA_END _edata
#endif
extern const char _RODATA_END[];
#define IN_RODATA_AREA(p) (((const char *)(p)) < _RODATA_END)
#endif /* defined(_MSC_VER) */
#else /* xtensa tool chain for ESP32 target */
#include "compiler.h"
#define IN_RODATA_AREA(p) (((const char *)p) >= RODATA_START_ADDRESS && ((const char *)p) <= RODATA_END_ADDRESS)
#endif /* defined(LUA_CROSS_COMPILER) */
/* Return 1 if the given pointer is a rotable */
#define luaR_isrotable(p) IN_RODATA_AREA(p)
#endif
......@@ -2,72 +2,54 @@ all: build
HOSTCC?=$(PYTHON) -m ziglang cc
# zig cc (0.8.0 at least) seems to get itself all confused with its cache
# when we're running a separate path for dependencies, so we skip them for
# now as for most people they're not needed anyway.
ifeq ($(findstring zig,$(HOSTCC)),zig)
WITHOUT_DEPS:=1
endif
ifeq ($V,)
Q:=@
endif
LUAC_CFLAGS:= -I$(COMPONENT_PATH)/../uzlib -I$(COMPONENT_PATH)/../lua -I$(BUILD_DIR_BASE)/config -I$(COMPONENT_PATH)/../base_nodemcu/include -O2 -g -Wall -Wextra
LUAC_LDFLAGS:= -ldl -lm
LUAC_OBJ_DIR:=$(LUAC_BUILD_DIR)/$(notdir $(LUA_PATH))
LUAC_DEFINES += -DLUA_CROSS_COMPILER -DLUA_USE_STDIO
ifneq ($(CONFIG_LUA_OPTIMIZE_DEBUG),)
LUAC_DEFINES += -DLUA_OPTIMIZE_DEBUG=$(CONFIG_LUA_OPTIMIZE_DEBUG)
endif
LUAC_CFLAGS:= \
-I$(LUAC_BUILD_DIR) \
-I$(LUA_PATH) \
-I$(LUA_PATH)/host \
-I$(LUA_PATH)/../common \
-I$(LUA_PATH)/../../uzlib \
-O2 -g -Wall -Wextra -Wno-sign-compare
vpath %.c $(COMPONENT_PATH) $(COMPONENT_PATH)/../lua $(COMPONENT_PATH)/../uzlib $(COMPONENT_PATH)/../base_nodemcu
LUAC_LDFLAGS:= -ldl -lm
LUAC_LUACSRC:= \
luac.c lflashimg.c loslib.c print.c liolib.c
LUAC_DEFINES += \
-DLUA_CROSS_COMPILER \
-DLUA_USE_HOST \
-DLUA_USE_STDIO \
LUAC_LUASRC:= $(addprefix $(COMPONENT_PATH)/../lua/, \
vpath %.c $(LUA_PATH)/host $(LUA_PATH) $(LUA_PATH)/../common $(LUA_PATH)/../../uzlib
LUA_SRCS:=\
luac.c lflashimg.c loslib.c print.c liolib.c \
lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c \
ldo.c ldump.c lfunc.c lgc.c llex.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 \
)
LUAC_UZSRC:= $(addprefix $(COMPONENT_PATH)/../uzlib/, \
lnodemcu.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c \
ltm.c lundump.c lvm.c lzio.c \
linit.c lpanic.c \
uzlib_deflate.c crc32.c \
)
LUAC_NODEMCUSRC:= $(addprefix $(COMPONENT_PATH)/../base_nodemcu/, \
linit.c \
)
LUAC_BUILD_DIR:=$(BUILD_DIR_BASE)/luac_cross
LUAC_OBJS:=$(LUAC_LUACSRC:%.c=$(LUAC_BUILD_DIR)/%.o)
LUAC_OBJS+=$(LUAC_LUASRC:$(COMPONENT_PATH)/../lua/%.c=$(LUAC_BUILD_DIR)/%.o)
LUAC_OBJS+=$(LUAC_UZSRC:$(COMPONENT_PATH)/../uzlib/%.c=$(LUAC_BUILD_DIR)/%.o)
LUAC_OBJS+=$(LUAC_NODEMCUSRC:$(COMPONENT_PATH)/../base_nodemcu/%.c=$(LUAC_BUILD_DIR)/%.o)
ifneq ($(WITHOUT_DEPS),1)
LUAC_DEPS:=$(LUAC_OBJS:%.o=%.d)
endif
LUAC_OBJS:=$(LUA_SRCS:%.c=$(LUAC_OBJ_DIR)/%.o)
LUAC_CROSS:=$(LUAC_BUILD_DIR)/luac.cross
$(LUAC_BUILD_DIR):
$(LUAC_OBJ_DIR):
@mkdir -p "$@"
$(LUAC_BUILD_DIR)/%.o: %.c | $(LUAC_BUILD_DIR)
$(LUAC_OBJ_DIR)/%.o: %.c | $(LUAC_OBJ_DIR)
@echo '[hostcc] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) "$<" -c -o "$@"
$(LUAC_BUILD_DIR)/%.d: SHELL=/bin/bash
$(LUAC_BUILD_DIR)/%.d: %.c | $(LUAC_BUILD_DIR)
$(LUAC_OBJ_DIR)/%.d: SHELL=/bin/bash
$(LUAC_OBJ_DIR)/%.d: %.c | $(LUAC_OBJ_DIR)
@echo '[ dep] $<'
@rm -f "$@"
$Qset -eo pipefail; $(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) -M "$<" | sed 's,\($*\.o\)[ :]*,$(LUAC_BUILD_DIR)/\1 $@ : ,g' > "$@.tmp"; mv "$@.tmp" "$@"
$Qset -eo pipefail; $(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) -M "$<" | sed 's,\($*\.o\)[ :]*,$(LUAC_OBJ_DIR)/\1 $@ : ,g' > "$@.tmp"; mv "$@.tmp" "$@"
build: $(LUAC_DEPS) $(LUAC_CROSS)
......@@ -75,6 +57,12 @@ $(LUAC_CROSS): $(LUAC_OBJS)
@echo '[ link] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_CFLAGS) $^ $(LUAC_LDFLAGS) -o "$@"
ifneq ($(MAKECMDGOALS),clean)
-include $(LUAC_DEPS)
# zig cc (0.8.0 at least) seems to get itself all confused with its cache
# when we're running a separate path for dependencies, so we skip them for
# now as for most people they're not needed anyway.
ifneq ($(findstring zig,$(HOSTCC)),zig)
LUAC_DEPS:=$(LUAC_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
-include $(LUAC_DEPS)
endif
endif
......@@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -109,10 +108,11 @@ static uint *flashAddrTag = flashImage + LUA_MAX_FLASH_SIZE;
#define setFlashAddrTag(v) flashAddrTag[_TW(v)] |= _TB(v)
#define getFlashAddrTag(v) ((flashAddrTag[_TW(v)]&_TB(v)) != 0)
#define fatal luac_fatal
#ifdef _MSC_VER
extern void __declspec( noreturn ) fatal( const char* message );
extern void __declspec( noreturn ) luac_fatal( const char* message );
#else
extern void __attribute__((noreturn)) fatal(const char* message);
extern void __attribute__((noreturn)) luac_fatal(const char* message);
#endif
#ifdef LOCAL_DEBUG
......@@ -188,10 +188,8 @@ static void scanProtoStrings(lua_State *L, const Proto* f) {
if (f->source)
addTS(L, f->source);
#ifdef LUA_OPTIMIZE_DEBUG
if (f->packedlineinfo)
addTS(L, luaS_new(L, cast(const char *, f->packedlineinfo)));
#endif
for (i = 0; i < f->sizek; i++) {
if (ttisstring(f->k + i))
......@@ -357,11 +355,7 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
}
/* The debug optimised version has a different Proto layout */
#ifdef LUA_OPTIMIZE_DEBUG
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIAI"
#else
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIIAI"
#endif
/*
* Do the actual prototype copy.
......@@ -385,14 +379,10 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
f.k = cast(TValue *, flashCopy(L, f.sizek, "V", f.k));
f.code = cast(Instruction *, flashCopy(L, f.sizecode, "I", f.code));
#ifdef LUA_OPTIMIZE_DEBUG
if (f.packedlineinfo) {
TString *ts=luaS_new(L, cast(const char *,f.packedlineinfo));
f.packedlineinfo = cast(unsigned char *, resolveTString(L, ts)) + sizeof (FlashTS);
}
#else
f.lineinfo = cast(int *, flashCopy(L, f.sizelineinfo, "I", f.lineinfo));
#endif
f.locvars = cast(struct LocVar *, flashCopy(L, f.sizelocvars, "SII", f.locvars));
f.upvalues = cast(TString **, flashCopy(L, f.sizeupvalues, "S", f.upvalues));
return cast(void *, flashCopy(L, 1, PROTO_COPY_MASK, &f));
......@@ -401,10 +391,10 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
void* data, int strip,
lu_int32 address, lu_int32 maxSize) {
(void)strip;
// parameter strip is ignored for now
(void)strip;
FlashHeader *fh = cast(FlashHeader *, flashAlloc(L, sizeof(FlashHeader)));
int status;
int i, status;
lua_newtable(L);
scanProtoStrings(L, main);
createROstrt(L, fh);
......@@ -416,7 +406,7 @@ uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
fatal ("The image is too large for specfied LFS size");
}
if (address) { /* in absolute mode convert addresses to mapped address */
for (uint i = 0 ; i < curOffset; i++)
for (i = 0 ; i < curOffset; i++)
if (getFlashAddrTag(i))
flashImage[i] = 4*flashImage[i] + address;
lua_unlock(L);
......@@ -434,7 +424,7 @@ uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
status = uzlib_compress (&oBuf, &oLen,
(const uint8_t *)flashImage, bmLen+fh->flash_size);
if (status != UZLIB_OK) {
fatal("Out of memory during image compression");
luac_fatal("Out of memory during image compression");
}
lua_unlock(L);
#if 0
......
......@@ -17,7 +17,7 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lnodemcu.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
......@@ -439,7 +439,10 @@ static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL);
}
LROT_PUBLIC_BEGIN(iolib)
LROT_TABLE(iolib);
LROT_BEGIN(iolib, NULL, LROT_MASK_GC_INDEX)
LROT_TABENTRY( __index, iolib )
LROT_FUNCENTRY( close, io_close )
LROT_FUNCENTRY( flush, io_flush )
LROT_FUNCENTRY( input, io_input )
......@@ -449,10 +452,14 @@ LROT_PUBLIC_BEGIN(iolib)
LROT_FUNCENTRY( read, io_read )
LROT_FUNCENTRY( type, io_type )
LROT_FUNCENTRY( write, io_write )
LROT_TABENTRY( __index, iolib )
LROT_END(iolib, NULL, 0)
LROT_END(iolib, NULL, LROT_MASK_GC_INDEX)
LROT_BEGIN(flib)
LROT_TABLE(flib);
LROT_BEGIN(flib, NULL, LROT_MASK_GC_INDEX)
LROT_FUNCENTRY( __gc, io_gc )
LROT_TABENTRY( __index, flib )
LROT_FUNCENTRY( __tostring, io_tostring )
LROT_FUNCENTRY( close, io_close )
LROT_FUNCENTRY( flush, f_flush )
LROT_FUNCENTRY( lines, f_lines )
......@@ -460,9 +467,6 @@ LROT_BEGIN(flib)
LROT_FUNCENTRY( seek, f_seek )
LROT_FUNCENTRY( setvbuf, f_setvbuf )
LROT_FUNCENTRY( write, f_write )
LROT_FUNCENTRY( __gc, io_gc )
LROT_FUNCENTRY( __tostring, io_tostring )
LROT_TABENTRY( __index, flib )
LROT_END(flib, NULL, LROT_MASK_GC_INDEX)
static const luaL_Reg io_base[] = {{NULL, NULL}};
......
......@@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <errno.h>
#include <locale.h>
#include <stdlib.h>
......@@ -20,8 +19,7 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lnodemcu.h"
static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
......@@ -221,32 +219,26 @@ static int os_exit (lua_State *L) {
exit(luaL_optint(L, 1, EXIT_SUCCESS));
}
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrotable.h"
LROT_PUBLIC_BEGIN(oslib)
LROT_FUNCENTRY(clock, os_clock)
LROT_FUNCENTRY(date, os_date)
LROT_BEGIN(oslib, NULL, 0)
LROT_FUNCENTRY( clock, os_clock )
LROT_FUNCENTRY( date, os_date )
#if !defined LUA_NUMBER_INTEGRAL
LROT_FUNCENTRY(difftime, os_difftime)
LROT_FUNCENTRY( difftime, os_difftime )
#endif
LROT_FUNCENTRY(execute, os_execute)
LROT_FUNCENTRY(exit, os_exit)
LROT_FUNCENTRY(getenv, os_getenv)
LROT_FUNCENTRY(remove, os_remove)
LROT_FUNCENTRY(rename, os_rename)
LROT_FUNCENTRY(setlocale, os_setlocale)
LROT_FUNCENTRY(time, os_time)
LROT_FUNCENTRY(tmpname, os_tmpname)
LROT_FUNCENTRY( execute, os_execute )
LROT_FUNCENTRY( exit, os_exit )
LROT_FUNCENTRY( getenv, os_getenv )
LROT_FUNCENTRY( remove, os_remove )
LROT_FUNCENTRY( rename, os_rename )
LROT_FUNCENTRY( setlocale, os_setlocale )
LROT_FUNCENTRY( time, os_time )
LROT_FUNCENTRY( tmpname, os_tmpname )
LROT_END(oslib, NULL, 0)
/* }====================================================== */
LUALIB_API int luaopen_os (lua_State *L) {
(void)L;
//LREGISTER(L, LUA_OSLIBNAME, oslib); // <------------- ???
return 0;
return 1;
}
......@@ -5,15 +5,15 @@
*/
#define LUAC_CROSS_FILE
#define luac_c
#define LUA_CORE
#include "luac_cross.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define luac_c
#define LUA_CORE
#include "lua.h"
#include "lauxlib.h"
......@@ -42,11 +42,12 @@ static const char* execute; /* executed a Lua file */
static const char* progname=PROGNAME; /* actual program name */
static DumpTargetInfo target;
void fatal(const char* message)
void luac_fatal(const char* message)
{
fprintf(stderr,"%s: %s\n",progname,message);
exit(EXIT_FAILURE);
}
#define fatal(s) luac_fatal(s)
static void cannot(const char* what)
{
......@@ -280,8 +281,8 @@ static int pmain(lua_State* L)
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);
if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
lua_pushstring(L, execute);
if (lua_pcall(L, 1, 1, 0)) fatal(lua_tostring(L,-1));
if (!lua_isfunction(L, -1))
......
......@@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <ctype.h>
#include <stdio.h>
......
......@@ -6,11 +6,9 @@
#define lapi_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
//#include <assert.h>
#include <math.h>
#include <string.h>
#include "lapi.h"
......@@ -26,7 +24,6 @@
#include "ltm.h"
#include "lundump.h"
#include "lvm.h"
#include "lrotable.h"
#if 0
const char lua_ident[] =
......@@ -155,6 +152,16 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
*/
/*
** convert an acceptable stack index into an absolute index
*/
LUA_API int lua_absindex (lua_State *L, int idx) {
return (idx > 0 || idx <= LUA_REGISTRYINDEX)
? idx
: cast_int(L->top - L->base) - 1 + idx;
}
LUA_API int lua_gettop (lua_State *L) {
return cast_int(L->top - L->base);
}
......@@ -243,6 +250,12 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
LUA_API int lua_type (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
return (o == luaO_nilobject) ? LUA_TNONE : ttnov(o);
}
LUA_API int lua_fulltype (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
}
......@@ -250,7 +263,7 @@ LUA_API int lua_type (lua_State *L, int idx) {
LUA_API const char *lua_typename (lua_State *L, int t) {
UNUSED(L);
return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
return (t == LUA_TNONE || t >= LUA_NUMTAGS) ? "no value" : luaT_typenames[t];
}
......@@ -287,32 +300,25 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
}
LUA_API int lua_equal (lua_State *L, int index1, int index2) {
StkId o1, o2;
int i;
lua_lock(L); /* may call tag method */
o1 = index2adr(L, index1);
o2 = index2adr(L, index2);
i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
lua_unlock(L);
return i;
}
LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
StkId o1, o2;
int i;
int i = 0;
lua_lock(L); /* may call tag method */
o1 = index2adr(L, index1);
o2 = index2adr(L, index2);
i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
: luaV_lessthan(L, o1, o2);
if (o1 != luaO_nilobject && o2 != luaO_nilobject) {
switch (op) {
case LUA_OPEQ: i = luaV_equalval(L, o1, o2); break;
case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
default: api_check(L, 0);
}
}
lua_unlock(L);
return i;
}
LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
TValue n;
const TValue *o = index2adr(L, idx);
......@@ -363,11 +369,10 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
LUA_API size_t lua_objlen (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
switch (ttnov(o)) {
case LUA_TSTRING: return tsvalue(o)->len;
case LUA_TUSERDATA: return uvalue(o)->len;
case LUA_TTABLE: return luaH_getn(hvalue(o));
case LUA_TROTABLE: return luaH_getn_ro(rvalue(o));
case LUA_TNUMBER: {
size_t l;
lua_lock(L); /* `luaV_tostring' may create a new string */
......@@ -405,16 +410,14 @@ LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
LUA_API const void *lua_topointer (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
case LUA_TTABLE: return hvalue(o);
case LUA_TTABLE:
case LUA_TROTABLE:
return hvalue(o);
case LUA_TFUNCTION: return clvalue(o);
case LUA_TTHREAD: return thvalue(o);
case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA:
return lua_touserdata(L, idx);
case LUA_TROTABLE:
return rvalue(o);
case LUA_TLIGHTFUNCTION:
return fvalue(o);
case LUA_TUSERDATA: return lua_touserdata(L, idx);
case LUA_TLIGHTUSERDATA: return pvalue(o);
case LUA_TLIGHTFUNCTION: return fvalue(o);
default: return NULL;
}
}
......@@ -492,18 +495,23 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
Closure *cl;
lua_lock(L);
luaC_checkGC(L);
api_checknelems(L, n);
cl = luaF_newCclosure(L, n, getcurrenv(L));
cl->c.f = fn;
L->top -= n;
while (n--)
setobj2n(L, &cl->c.upvalue[n], L->top+n);
setclvalue(L, L->top, cl);
lua_assert(iswhite(obj2gco(cl)));
api_incr_top(L);
if (n == 0) {
setfvalue(L->top, fn);
api_incr_top(L);
} else {
Closure *cl;
luaC_checkGC(L);
api_checknelems(L, n);
cl = luaF_newCclosure(L, n, getcurrenv(L));
cl->c.f = fn;
L->top -= n;
while (n--)
setobj2n(L, &cl->c.upvalue[n], L->top+n);
setclvalue(L, L->top, cl);
lua_assert(iswhite(obj2gco(cl)));
api_incr_top(L);
}
lua_unlock(L);
}
......@@ -523,16 +531,10 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
lua_unlock(L);
}
LUA_API void lua_pushrotable (lua_State *L, void *p) {
lua_lock(L);
setrvalue(L->top, p);
api_incr_top(L);
lua_unlock(L);
}
LUA_API void lua_pushlightfunction(lua_State *L, void *p) {
LUA_API void lua_pushrotable (lua_State *L, const ROTable *t) {
lua_lock(L);
setfvalue(L->top, p);
sethvalue(L, L->top, cast(ROTable *,t));
api_incr_top(L);
lua_unlock(L);
}
......@@ -553,17 +555,17 @@ LUA_API int lua_pushthread (lua_State *L) {
*/
LUA_API void lua_gettable (lua_State *L, int idx) {
LUA_API int lua_gettable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
luaV_gettable(L, t, L->top - 1, L->top - 1);
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
StkId t;
TValue key;
lua_lock(L);
......@@ -575,29 +577,58 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
luaV_gettable(L, t, &key, L->top);
api_incr_top(L);
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API int lua_geti (lua_State *L, int idx, int n) {
StkId t;
TValue key;
lua_lock(L);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
fixedstack(L);
setnvalue(&key, n);
unfixedstack(L);
luaV_gettable(L, t, &key, L->top);
api_incr_top(L);
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API void lua_rawget (lua_State *L, int idx) {
LUA_API int lua_rawget (lua_State *L, int idx) {
StkId t;
const TValue *res;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t) || ttisrotable(t));
res = ttistable(t) ? luaH_get(hvalue(t), L->top - 1) : luaH_get_ro(rvalue(t), L->top - 1);
setobj2s(L, L->top - 1, res);
api_check(L, ttistable(t));
setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
LUA_API int lua_rawgeti (lua_State *L, int idx, int n) {
StkId o;
lua_lock(L);
o = index2adr(L, idx);
api_check(L, ttistable(o) || ttisrotable(o));
setobj2s(L, L->top, ttistable(o) ? luaH_getnum(hvalue(o), n) : luaH_getnum_ro(rvalue(o), n))
api_check(L, ttistable(o));
setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
api_incr_top(L);
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
StkId t;
TValue k;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t));
setpvalue(&k, cast(void *, p));
setobj2s(L, L->top, luaH_get(hvalue(t), &k));
api_incr_top(L);
lua_unlock(L);
return ttnov(L->top - 1);
}
......@@ -616,27 +647,21 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
int res;
lua_lock(L);
obj = index2adr(L, objindex);
switch (ttype(obj)) {
switch (ttnov(obj)) {
case LUA_TTABLE:
mt = hvalue(obj)->metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(obj)->metatable;
break;
case LUA_TROTABLE:
mt = (Table*)luaR_getmeta(rvalue(obj));
break;
default:
mt = G(L)->mt[ttype(obj)];
mt = G(L)->mt[ttnov(obj)];
break;
}
if (mt == NULL)
res = 0;
else {
if(luaR_isrotable(mt))
setrvalue(L->top, mt)
else
sethvalue(L, L->top, mt)
sethvalue(L, L->top, mt)
api_incr_top(L);
res = 1;
}
......@@ -730,40 +755,54 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
}
LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
StkId o;
TValue k;
lua_lock(L);
api_checknelems(L, 1);
o = index2adr(L, idx);
api_check(L, ttistable(o));
fixedstack(L);
setpvalue(&k, cast(void *, p))
setobj2t(L, luaH_set(L, hvalue(o), &k), L->top-1);
unfixedstack(L);
luaC_barriert(L, hvalue(o), L->top-1);
L->top--;
lua_unlock(L);
}
LUA_API int lua_setmetatable (lua_State *L, int objindex) {
TValue *obj;
Table *mt;
int isrometa = 0;
lua_lock(L);
api_checknelems(L, 1);
obj = index2adr(L, objindex);
api_checkvalidindex(L, obj);
if (ttisnil(L->top - 1))
if (ttisnil(L->top - 1)) {
mt = NULL;
else {
api_check(L, ttistable(L->top - 1) || ttisrotable(L->top - 1));
if (ttistable(L->top - 1))
mt = hvalue(L->top - 1);
else {
mt = (Table*)rvalue(L->top - 1);
isrometa = 1;
}
} else {
api_check(L, ttistable(L->top - 1));
mt = hvalue(L->top - 1);
}
switch (ttype(obj)) {
switch (ttype(obj)) { /* use basetype to retain subtypes*/
case LUA_TTABLE: {
hvalue(obj)->metatable = mt;
if (mt && !isrometa)
if (mt && !isrotable(mt))
luaC_objbarriert(L, hvalue(obj), mt);
break;
}
case LUA_TUSERDATA: {
uvalue(obj)->metatable = mt;
if (mt && !isrometa)
if (mt && !isrotable(mt))
luaC_objbarrier(L, rawuvalue(obj), mt);
break;
}
case LUA_TISROTABLE: { /* Ignore any changes to a ROTable MT */
break;
}
default: {
G(L)->mt[ttype(obj)] = mt;
G(L)->mt[ttnov(obj)] = mt;
break;
}
}
......@@ -813,7 +852,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
#define checkresults(L,na,nr) \
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
StkId func;
......@@ -914,14 +953,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
}
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int stripping) {
int status;
TValue *o;
lua_lock(L);
api_checknelems(L, 1);
o = L->top - 1;
if (isLfunction(o))
status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
status = luaU_dump(L, clvalue(o)->l.p, writer, data, stripping);
else
status = 1;
lua_unlock(L);
......@@ -929,6 +968,30 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
}
LUA_API int lua_stripdebug (lua_State *L, int stripping){
TValue *o = L->top - 1;
Proto *p = NULL;
int res = -1;
lua_lock(L);
api_checknelems(L, 1);
if (isLfunction(o)) {
p = clvalue(o)->l.p;
if (p && !isLFSobject(p) && (unsigned) stripping < 3 ) {
// found a valid proto to strip
res = luaG_stripdebug(L, p, stripping, 1);
}
} else if (ttisnil(L->top - 1)) {
// get or set the default strip level
if ((unsigned) stripping < 3)
G(L)->stripdefault = stripping;
res = G(L)->stripdefault;
}
L->top--;
lua_unlock(L);
return res;
}
LUA_API int lua_status (lua_State *L) {
return L->status;
}
......@@ -1039,8 +1102,8 @@ LUA_API int lua_next (lua_State *L, int idx) {
int more;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t) || ttisrotable(t));
more = ttistable(t) ? luaH_next(L, hvalue(t), L->top - 1) : luaH_next_ro(L, rvalue(t), L->top - 1);
api_check(L, ttistable(t));
more = luaH_next(L, hvalue(t), L->top - 1);
if (more) {
api_incr_top(L);
}
......@@ -1149,3 +1212,15 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
return name;
}
LUA_API void lua_setegcmode ( lua_State *L, int mode, int limit) {
G(L)->egcmode = mode;
G(L)->memlimit = limit;
}
LUA_API void lua_getegcinfo (lua_State *L, int *totals) {
if (totals) {
totals[0] = G(L)->totalbytes;
totals[1] = G(L)->estimate;
}
}
......@@ -4,20 +4,16 @@
** See Copyright Notice in lua.h
*/
#define LUAC_CROSS_FILE
#include "lua.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#ifndef LUA_CROSS_COMPILER
#include "esp_system.h"
#include "vfs.h"
/* defined in esp_system_internal.h */
void esp_reset_reason_set_hint(esp_reset_reason_t hint);
#else
#endif
/* This file uses only the official API of Lua.
......@@ -27,14 +23,14 @@ void esp_reset_reason_set_hint(esp_reset_reason_t hint);
#define lauxlib_c
#define LUA_LIB
#include "lrotable.h"
#include "lnodemcu.h"
#include "lauxlib.h"
#include "lgc.h"
#include "ldo.h"
#include "lobject.h"
#include "lstate.h"
#include "legc.h"
#include "lpanic.h"
#define FREELIST_REF 0 /* free list of references */
......@@ -277,7 +273,7 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
return 1;
}
LUALIB_API int luaL_rometatable (lua_State *L, const char* tname, void *p) {
LUALIB_API int luaL_rometatable (lua_State *L, const char* tname, const ROTable *p) {
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
......@@ -288,21 +284,25 @@ LUALIB_API int luaL_rometatable (lua_State *L, const char* tname, void *p) {
return 1;
}
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
lua_pop(L, 2); /* remove both metatables */
return p;
}
if (!lua_rawequal(L, -1, -2)) /* not the same? */
p = NULL; /* value is a userdata with wrong metatable */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
luaL_typerror(L, ud, tname); /* else error */
return NULL; /* to avoid warnings */
return NULL; /* value is not a userdata with a metatable */
}
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
void *p = luaL_testudata(L, ud, tname);
if (p == NULL) luaL_typerror(L, ud, tname);
return p;
}
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
if (!lua_checkstack(L, space))
......@@ -315,22 +315,6 @@ LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
tag_error(L, narg, t);
}
LUALIB_API void luaL_checkanyfunction (lua_State *L, int narg) {
if (lua_type(L, narg) != LUA_TFUNCTION && lua_type(L, narg) != LUA_TLIGHTFUNCTION) {
const char *msg = lua_pushfstring(L, "function or lightfunction expected, got %s",
luaL_typename(L, narg));
luaL_argerror(L, narg, msg);
}
}
LUALIB_API void luaL_checkanytable (lua_State *L, int narg) {
if (lua_type(L, narg) != LUA_TTABLE && lua_type(L, narg) != LUA_TROTABLE) {
const char *msg = lua_pushfstring(L, "table or rotable expected, got %s",
luaL_typename(L, narg));
luaL_argerror(L, narg, msg);
}
}
LUALIB_API void luaL_checkany (lua_State *L, int narg) {
if (lua_type(L, narg) == LUA_TNONE)
......@@ -449,7 +433,7 @@ LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
for (i=0; i<nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup);
if (ftype == LUA_USELIGHTFUNCTIONS)
lua_pushlightfunction(L, l->func);
lua_pushcfunction(L, l->func);
else
lua_pushcclosure(L, l->func, nup);
lua_setfield(L, -(nup+2), l->name);
......@@ -561,7 +545,7 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */
}
else if (!lua_istable(L, -1) && !lua_isrotable(L, -1)) { /* field has a non-table value? */
else if (!lua_istable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */
}
......@@ -703,6 +687,26 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
}
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref) {
int reft;
/*
* If the ref is positive and the entry in table t exists then
* overwrite the value otherwise fall through to luaL_ref()
*/
if (ref) {
if (*ref >= 0) {
t = abs_index(L, t);
lua_rawgeti(L, t, *ref);
reft = lua_type(L, -1);
lua_pop(L, 1);
if (reft != LUA_TNIL) {
lua_rawseti(L, t, *ref);
return;
}
}
*ref = luaL_ref(L, t);
}
}
/*
** {======================================================
......@@ -710,14 +714,33 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
** =======================================================
*/
#ifdef LUA_CROSS_COMPILER
typedef struct LoadF {
int extraline;
#ifdef LUA_CROSS_COMPILER
FILE *f;
#else
int f;
#endif
char buff[LUAL_BUFFERSIZE];
} LoadF;
#ifdef LUA_CROSS_COMPILER
# define freopen_bin(f,fn) freopen(f,"rb",fn)
# define read_buff(b,f) fread(b, 1, sizeof (b), f)
#else
# define strerror(n) ""
#undef feof
# define feof(f) vfs_eof(f)
#undef fopen
# define fopen(f, m) vfs_open(f, m)
# define freopen_bin(fn,f) ((void) vfs_close(f), vfs_open(fn, "r"))
#undef getc
# define getc(f) vfs_getc(f)
#undef ungetc
# define ungetc(c,f) vfs_ungetc(c, f)
# define read_buff(b,f) vfs_read(f, b, sizeof (b))
#endif
static const char *getF (lua_State *L, void *ud, size_t *size) {
LoadF *lf = (LoadF *)ud;
......@@ -728,7 +751,7 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
return "\n";
}
if (feof(lf->f)) return NULL;
*size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
*size = read_buff(lf->buff, lf->f);
return (*size > 0) ? lf->buff : NULL;
}
......@@ -748,14 +771,19 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
if (filename == NULL) {
#ifdef LUA_CROSS_COMPILER
lua_pushliteral(L, "=stdin");
lf.f = stdin;
#else
return luaL_error(L, "filename is NULL");
#endif
}
else {
lua_pushfstring(L, "@%s", filename);
lf.f = fopen(filename, "r");
if (lf.f == NULL) return errfile(L, "open", fnameindex);
if (!lf.f) return errfile(L, "open", fnameindex);
}
c = getc(lf.f);
if (c == '#') { /* Unix exec. file? */
......@@ -764,8 +792,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
if (c == '\n') c = getc(lf.f);
}
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
lf.f = freopen_bin(filename, lf.f); /* reopen in binary mode */
if (!lf.f) return errfile(L, "reopen", fnameindex);
/* skip eventual `#!...' */
while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) {}
......@@ -773,95 +801,21 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
}
ungetc(c, lf.f);
status = lua_load(L, getF, &lf, lua_tostring(L, -1));
#ifdef LUA_CROSS_COMPILER
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, "read", fnameindex);
}
lua_remove(L, fnameindex);
return status;
}
#else
#include <fcntl.h>
typedef struct LoadFSF {
int extraline;
int f;
char buff[LUAL_BUFFERSIZE];
} LoadFSF;
static const char *getFSF (lua_State *L, void *ud, size_t *size) {
LoadFSF *lf = (LoadFSF *)ud;
(void)L;
if (L == NULL && size == NULL) // Direct mode check
return NULL;
if (lf->extraline) {
lf->extraline = 0;
*size = 1;
return "\n";
}
if (vfs_eof(lf->f)) return NULL;
*size = vfs_read(lf->f, lf->buff, sizeof(lf->buff));
return (*size > 0) ? lf->buff : NULL;
}
static int errfsfile (lua_State *L, const char *what, int fnameindex) {
const char *filename = lua_tostring(L, fnameindex) + 1;
lua_pushfstring(L, "cannot %s %s", what, filename);
lua_remove(L, fnameindex);
return LUA_ERRFILE;
}
LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) {
LoadFSF lf;
int status;
int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
if (filename == NULL) {
return luaL_error(L, "filename is NULL");
}
else {
lua_pushfstring(L, "@%s", filename);
lf.f = vfs_open(filename, "r");
if (!lf.f) return errfsfile(L, "open", fnameindex);
}
// 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)) != VFS_EOF && c != '\n') ; /* skip first line */
if (c == '\n') c = vfs_getc(lf.f);
}
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
vfs_close(lf.f);
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)) != VFS_EOF && c != LUA_SIGNATURE[0])
;
lf.extraline = 0;
}
vfs_ungetc(c, lf.f);
status = lua_load(L, getFSF, &lf, lua_tostring(L, -1));
if (filename) vfs_close(lf.f); /* close file (even in case of errors) */
(void) readstatus;
if (filename) vfs_close(lf.f); /* close file (even in case of errors) */
#endif
lua_remove(L, fnameindex);
return status;
}
#endif
typedef struct LoadS {
const char *s;
......@@ -959,51 +913,6 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
#endif
}
#ifndef LUA_CROSS_COMPILER
/*
* upper 28 bit have magic value 0xD1EC0DE0
* if paniclevel is valid (i.e. matches magic value)
* lower 4 bits have paniclevel:
* 0 = no panic occurred
* 1..15 = one..fifteen subsequent panic(s) occurred
*/
static __NOINIT_ATTR uint32_t l_rtc_panic_val;
int panic_get_nvval() {
if ((l_rtc_panic_val & 0xfffffff0) == 0xD1EC0DE0) {
return (l_rtc_panic_val & 0xf);
}
panic_clear_nvval();
return 0;
}
void panic_clear_nvval() {
l_rtc_panic_val = 0xD1EC0DE0;
}
#endif
static int panic (lua_State *L) {
(void)L; /* to avoid warnings */
#ifndef LUA_CROSS_COMPILER
uint8_t paniclevel = panic_get_nvval();
if (paniclevel < 15) paniclevel++;
l_rtc_panic_val = 0xD1EC0DE0 | paniclevel;
#endif
#if defined(LUA_USE_STDIO)
fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
#else
luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
#endif
#ifndef LUA_CROSS_COMPILER
/* call abort() directly - we don't want another reset cause to intervene */
esp_reset_reason_set_hint(ESP_RST_PANIC);
abort();
#endif
while (1) {}
return 0;
}
LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL);
......
......@@ -8,12 +8,13 @@
#ifndef lauxlib_h
#define lauxlib_h
#include "lua.h"
#ifdef LUA_LIB
#include "lnodemcu.h"
#endif
#include <stdio.h>
#if defined(LUA_COMPAT_GETN)
LUALIB_API int (luaL_getn) (lua_State *L, int t);
LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
......@@ -43,7 +44,7 @@ LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l);
LUALIB_API void (luaL_register_light) (lua_State *L, const char *libname,
const luaL_Reg *l);
const luaL_Reg *l);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
......@@ -62,11 +63,10 @@ LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
LUALIB_API void (luaL_checkanyfunction) (lua_State *L, int narg);
LUALIB_API void (luaL_checkanytable) (lua_State *L, int narg);
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API int (luaL_rometatable) (lua_State *L, const char* tname, void *p);
LUALIB_API int (luaL_rometatable) (lua_State *L, const char* tname, const ROTable *p);
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
......@@ -77,12 +77,11 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
#define luaL_unref2(l,t,r) do {luaL_unref(L, (t), (r)); r = LUA_NOREF;} while (0)
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref);
#ifdef LUA_CROSS_COMPILER
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
#else
LUALIB_API int (luaL_loadfsfile) (lua_State *L, const char *filename);
#endif
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
......@@ -112,7 +111,12 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
#define luaL_optunsigned(L,a,d) ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
#define luaL_checktable(L,n) luaL_checktype(L, (n), LUA_TTABLE);
#define luaL_checkfunction(L,n) luaL_checktype(L, (n), LUA_TFUNCTION);
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
......@@ -121,7 +125,7 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#else
#define luaL_dofile(L, fn) \
(luaL_loadfsfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#endif
#define luaL_dostring(L, s) \
......@@ -165,6 +169,18 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
/* }====================================================== */
LUALIB_API int (luaL_pushlfsmodules) (lua_State *L);
LUALIB_API int (luaL_pushlfsmodule) (lua_State *L);
LUALIB_API int (luaL_pushlfsdts) (lua_State *L);
LUALIB_API void (luaL_lfsreload) (lua_State *L);
LUALIB_API int (luaL_pcallx) (lua_State *L, int narg, int nres);
LUALIB_API int (luaL_posttask) ( lua_State* L, int prio );
#define LUA_TASK_LOW 0
#define LUA_TASK_MEDIUM 1
#define LUA_TASK_HIGH 2
/* }====================================================== */
/* compatibility with ref system */
......@@ -184,7 +200,3 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
#endif
#ifndef LUA_CROSS_COMPILER
int panic_get_nvval();
void panic_clear_nvval();
#endif
......@@ -8,17 +8,14 @@
#define lbaselib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
/*
......@@ -27,6 +24,10 @@
** model but changing `fputs' to put the strings at a proper place
** (a console window or a log file, for instance).
*/
#ifdef LUA_CROSS_COMPILER
#undef puts
#define puts(s) printf("%s",s)
#endif
static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
......@@ -40,20 +41,11 @@ static int luaB_print (lua_State *L) {
if (s == NULL)
return luaL_error(L, LUA_QL("tostring") " must return a string to "
LUA_QL("print"));
#if defined(LUA_USE_STDIO)
if (i>1) fputs("\t", stdout);
fputs(s, stdout);
#else
if (i>1) luai_writestring("\t", 1);
luai_writestring(s, strlen(s));
#endif
if (i>1) puts("\t");
puts(s);
lua_pop(L, 1); /* pop result */
}
#if defined(LUA_USE_STDIO)
fputs("\n", stdout);
#else
luai_writeline();
#endif
puts("\n");
return 0;
}
......@@ -112,7 +104,7 @@ static int luaB_getmetatable (lua_State *L) {
static int luaB_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE || t == LUA_TROTABLE, 2,
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
if (luaL_getmetafield(L, 1, "__metatable"))
luaL_error(L, "cannot change a protected metatable");
......@@ -175,7 +167,7 @@ static int luaB_rawequal (lua_State *L) {
static int luaB_rawget (lua_State *L) {
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_rawget(L, 1);
......@@ -183,7 +175,7 @@ static int luaB_rawget (lua_State *L) {
}
static int luaB_rawset (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checktable(L, 1);
luaL_checkany(L, 2);
luaL_checkany(L, 3);
lua_settop(L, 3);
......@@ -233,7 +225,7 @@ static int luaB_type (lua_State *L) {
static int luaB_next (lua_State *L) {
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
if (lua_next(L, 1))
return 2;
......@@ -245,7 +237,7 @@ static int luaB_next (lua_State *L) {
static int luaB_pairs (lua_State *L) {
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushnil(L); /* and initial value */
......@@ -255,7 +247,7 @@ static int luaB_pairs (lua_State *L) {
static int ipairsaux (lua_State *L) {
int i = luaL_checkint(L, 2);
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
i++; /* next value */
lua_pushinteger(L, i);
lua_rawgeti(L, 1, i);
......@@ -264,7 +256,7 @@ static int ipairsaux (lua_State *L) {
static int luaB_ipairs (lua_State *L) {
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushinteger(L, 0); /* and initial value */
......@@ -296,7 +288,7 @@ static int luaB_loadfile (lua_State *L) {
#ifdef LUA_CROSS_COMPILER
return load_aux(L, luaL_loadfile(L, fname));
#else
return load_aux(L, luaL_loadfsfile(L, fname));
return load_aux(L, luaL_loadfile(L, fname));
#endif
}
......@@ -343,7 +335,7 @@ static int luaB_dofile (lua_State *L) {
#ifdef LUA_CROSS_COMPILER
if (luaL_loadfile(L, fname) != 0) lua_error(L);
#else
if (luaL_loadfsfile(L, fname) != 0) lua_error(L);
if (luaL_loadfile(L, fname) != 0) lua_error(L);
#endif
lua_call(L, 0, LUA_MULTRET);
return lua_gettop(L) - n;
......@@ -462,29 +454,24 @@ static int luaB_newproxy (lua_State *L) {
return 1;
}
#include "lrotable.h"
LROT_EXTERN(lua_rotable_base);
/*
* 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)
** ESP builds use specific linker directives to marshal all the ROTable entries
** for the library modules including the base library into an entry vector in
** the PSECT ".lua_rotable" including the base library entries; this is bound
** into a ROTable in linit.c which then hooked into the __index metaentry for
** _G so that base library and ROM tables are directly resolved through _G.
**
** The host-based luac.cross builds which must use a standard GNU link or
** MSVC so this linker-specfic assembly approach can't be used. In this case
** luaopen_base returns a base_func ROTable so a two cascade resolution. See
** description in init.c for further details.
*/
#ifdef LUA_CROSS_COMPILER
LROT_BEGIN(base_func, NULL, 0)
#else
LROT_ENTRIES_IN_SECTION(base_func, rotable)
#endif
LROT_FUNCENTRY(assert, luaB_assert)
LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage)
LROT_FUNCENTRY(dofile, luaB_dofile)
......@@ -509,13 +496,11 @@ LROT_PUBLIC_BEGIN(base_func)
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)
#ifdef LUA_CROSS_COMPILER
LROT_END(base_func, NULL, 0)
#else
LROT_BREAK(base_func)
#endif
/*
** {======================================================
......@@ -645,14 +630,14 @@ static int luaB_corunning (lua_State *L) {
return 1;
}
LROT_PUBLIC_BEGIN(co_funcs)
LROT_BEGIN(co_funcs, NULL, 0)
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)
LROT_END(co_funcs, NULL, 0)
/* }====================================================== */
......@@ -661,19 +646,13 @@ static void auxopen (lua_State *L, const char *name,
lua_CFunction f, lua_CFunction u) {
lua_pushcfunction(L, u);
lua_pushcclosure(L, f, 1);
lua_setfield(L, -2, name);
lua_setglobal(L, name);
}
static void base_open (lua_State *L) {
/* set global _G */
extern LROT_TABLE(rotables);
LUALIB_API int luaopen_base (lua_State *L) {
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G");
/* open lib into global table */
luaL_register_light(L, "_G", &((luaL_Reg) {0}));
lua_pushrotable(L, LROT_TABLEREF(G_meta));
lua_setmetatable(L, LUA_GLOBALSINDEX);
lua_settable(L, LUA_GLOBALSINDEX); /* set global _G */
lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
......@@ -681,16 +660,15 @@ static void base_open (lua_State *L) {
auxopen(L, "pairs", luaB_pairs, luaB_next);
/* `newproxy' needs a weaktable as upvalue */
lua_createtable(L, 0, 1); /* new table `w' */
lua_pushvalue(L, -1); /* `w' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushliteral(L, "kv");
lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
lua_pushcclosure(L, luaB_newproxy, 1);
lua_pushvalue(L, -1); /* `w' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushcclosure(L, luaB_newproxy, 1); /* Upval is table w */
lua_setglobal(L, "newproxy"); /* set global `newproxy' */
}
LUALIB_API int luaopen_base (lua_State *L) {
base_open(L);
return 1;
lua_pushrotable(L, LROT_TABLEREF(rotables));
lua_setglobal(L, "__index");
lua_pushvalue(L, LUA_GLOBALSINDEX); /* _G is its own metatable */
lua_setmetatable(L, LUA_GLOBALSINDEX);
return 0;
}
......@@ -7,7 +7,6 @@
#define lcode_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdlib.h>
......@@ -781,8 +780,6 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
}
#ifdef LUA_OPTIMIZE_DEBUG
/*
* Attempted to write to last (null terminator) byte of lineinfo, so need
* to grow the lineinfo vector and extend the fill bytes
......@@ -829,10 +826,8 @@ static void generateInfoDeltaLine(FuncState *fs, int line) {
fs->lastlineOffset = p - fs->f->packedlineinfo - 1;
#undef addDLbyte
}
#endif
void luaK_fixline (FuncState *fs, int line) {
#ifdef LUA_OPTIMIZE_DEBUG
/* The fixup line can be the same as existing one and in this case there's nothing to do */
if (line != fs->lastline) {
/* first remove the current line reference */
......@@ -863,9 +858,6 @@ void luaK_fixline (FuncState *fs, int line) {
/* Then add the new line reference */
generateInfoDeltaLine(fs, line);
}
#else
fs->f->lineinfo[fs->pc - 1] = line;
#endif
}
......@@ -877,7 +869,6 @@ static int luaK_code (FuncState *fs, Instruction i, int line) {
MAX_INT, "code size overflow");
f->code[fs->pc] = i;
/* save corresponding line information */
#ifdef LUA_OPTIMIZE_DEBUG
/* note that frst time fs->lastline==0 through, so the else branch is taken */
if (fs->pc == fs->lineinfoLastPC+1) {
if (line == fs->lastline && f->packedlineinfo[fs->lastlineOffset] < INFO_MAX_LINECNT) {
......@@ -891,11 +882,6 @@ static int luaK_code (FuncState *fs, Instruction i, int line) {
luaK_fixline(fs,line);
}
fs->lineinfoLastPC = fs->pc;
#else
luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
MAX_INT, "code size overflow");
f->lineinfo[fs->pc] = line;
#endif
return fs->pc++;
}
......
......@@ -7,7 +7,6 @@
#define ldblib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
......@@ -18,8 +17,6 @@
#include "lualib.h"
#include "lstring.h"
#include "lflash.h"
#include "lrotable.h"
#include "sdkconfig.h"
static int db_getregistry (lua_State *L) {
......@@ -28,34 +25,16 @@ static int db_getregistry (lua_State *L) {
}
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 */
static const char *const opts[] = {"RAM","ROM",NULL};
int opt = luaL_checkoption(L, 1, "RAM", opts);
if (lua_pushstringsarray(L, opt)) {
if(lua_getglobal(L, "table") == LUA_TTABLE) {
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) */
}
}
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;
}
......@@ -144,7 +123,7 @@ static int db_getinfo (lua_State *L) {
return 1;
}
}
else if (lua_isfunction(L, arg+1) || lua_islightfunction(L, arg+1)) {
else if (lua_isfunction(L, arg+1)) {
lua_pushfstring(L, ">%s", options);
options = lua_tostring(L, -1);
lua_pushvalue(L, arg+1);
......@@ -302,7 +281,7 @@ static int db_sethook (lua_State *L) {
}
else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checkanyfunction(L, arg+1);
luaL_checkfunction(L, arg+1);
count = luaL_optint(L, arg+3, 0);
func = hookf; mask = makemask(smask, count);
}
......@@ -367,7 +346,7 @@ static int db_debug (lua_State *L) {
#define LEVELS1 12 /* size of the first part of the stack */
#define LEVELS2 10 /* size of the second part of the stack */
static int db_errorfb (lua_State *L) {
static int debug_errorfb (lua_State *L) {
int level;
int firstpart = 1; /* still before eventual `...' */
int arg;
......@@ -419,7 +398,7 @@ static int db_errorfb (lua_State *L) {
return 1;
}
LROT_PUBLIC_BEGIN(dblib)
LROT_BEGIN(dblib, NULL, 0)
#ifndef CONFIG_LUA_BUILTIN_DEBUG_MINIMAL
#if defined(LUA_CROSS_COMPILER)
LROT_FUNCENTRY( debug, db_debug )
......@@ -440,7 +419,7 @@ LROT_PUBLIC_BEGIN(dblib)
LROT_FUNCENTRY( setmetatable, db_setmetatable )
LROT_FUNCENTRY( setupvalue, db_setupvalue )
#endif
LROT_FUNCENTRY( traceback, db_errorfb )
LROT_FUNCENTRY( traceback, debug_errorfb )
LROT_END(dblib, NULL, 0)
LUALIB_API int luaopen_debug (lua_State *L) {
......
......@@ -7,7 +7,6 @@
#define ldebug_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
......@@ -183,8 +182,7 @@ static void info_tailcall (lua_Debug *ar) {
# define INFO_DELTA_7BITS 0x7F
# define INFO_MAX_LINECNT 126
Table *t = luaH_new(L, 0, 0);
#ifdef LUA_OPTIMIZE_DEBUG
Table *t = luaH_new(L, 0, 0);
int line = 0;
unsigned char *p = f->l.p->packedlineinfo;
if (p) {
......@@ -204,18 +202,11 @@ static void info_tailcall (lua_Debug *ar) {
setbvalue(luaH_setnum(L, t, line), 1);
}
}
#else
int *lineinfo = f->l.p->lineinfo;
int i;
for (i=0; i<f->l.p->sizelineinfo; i++)
setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
#endif
sethvalue(L, L->top, t);
sethvalue(L, L->top, t);
}
incr_top(L);
}
#ifdef LUA_OPTIMIZE_DEBUG
/*
* This may seem expensive but this is only accessed frequently in traceexec
* and the while loop will be executed roughly half the number of non-blank
......@@ -250,19 +241,18 @@ int luaG_getline (const Proto *f, int pc) {
static int stripdebug (lua_State *L, Proto *f, int level) {
int len = 0, sizepackedlineinfo;
TString* dummy;
switch (level) {
case 3:
sizepackedlineinfo = strlen(cast(char *, f->packedlineinfo))+1;
f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, sizepackedlineinfo, unsigned char);
len += sizepackedlineinfo;
// fall-through
case 2:
len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *));
if (f->packedlineinfo) {
sizepackedlineinfo = strlen(cast(char *, f->packedlineinfo))+1;
f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, sizepackedlineinfo, unsigned char);
len += sizepackedlineinfo;
}
// fall-through
case 1:
f->locvars = luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
f->upvalues = luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)) +
f->sizeupvalues * (sizeof(dummy->tsv) + sizeof(TString *));
len += f->sizelocvars*sizeof(struct LocVar) + f->sizeupvalues*sizeof(TString *);
f->sizelocvars = 0;
f->sizeupvalues = 0;
}
......@@ -278,7 +268,6 @@ LUA_API int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv){
len += stripdebug (L, f, level);
return len;
}
#endif
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
......@@ -328,21 +317,21 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
lua_lock(L);
if (*what == '>') {
StkId func = L->top - 1;
luai_apicheck(L, ttisfunction(func) || ttislightfunction(func));
luai_apicheck(L, ttisfunction(func));
what++; /* skip the '>' */
if (ttisfunction(func))
f = clvalue(func);
else
if (ttislightfunction(func))
plight = fvalue(func);
else
f = clvalue(func);
L->top--; /* pop function */
}
else if (ar->i_ci != 0) { /* no tail call? */
ci = L->base_ci + ar->i_ci;
lua_assert(ttisfunction(ci->func) || ttislightfunction(ci->func));
if (ttisfunction(ci->func))
f = clvalue(ci->func);
else
lua_assert(ttisfunction(ci->func));
if (ttislightfunction(ci->func))
plight = fvalue(ci->func);
else
f = clvalue(ci->func);
}
status = auxgetinfo(L, what, ar, f, plight, ci);
if (strchr(what, 'f')) {
......@@ -381,9 +370,6 @@ static int precheck (const Proto *pt) {
check(!(pt->is_vararg & VARARG_NEEDSARG) ||
(pt->is_vararg & VARARG_HASARG));
check(pt->sizeupvalues <= pt->nups);
#ifndef LUA_OPTIMIZE_DEBUG
check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
#endif
check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
return 1;
}
......@@ -670,7 +656,7 @@ static int isinstack (CallInfo *ci, const TValue *o) {
void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
const char *name = NULL;
const char *t = luaT_typenames[ttype(o)];
const char *t = luaT_typenames[ttnov(o)];
const char *kind = (isinstack(L->ci, o)) ?
getobjname(L, L->ci, cast_int(o - L->base), &name) :
NULL;
......@@ -698,8 +684,8 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = luaT_typenames[ttype(p1)];
const char *t2 = luaT_typenames[ttype(p2)];
const char *t1 = luaT_typenames[ttnov(p1)];
const char *t2 = luaT_typenames[ttnov(p2)];
if (t1[2] == t2[2])
luaG_runerror(L, "attempt to compare two %s values", t1);
else
......@@ -722,7 +708,7 @@ static void addinfo (lua_State *L, const char *msg) {
void luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
if (!ttisfunction(errfunc) && !ttislightfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
setobjs2s(L, L->top, L->top - 1); /* move argument */
setobjs2s(L, L->top - 1, errfunc); /* push function */
incr_top(L);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment