Commit dba57fa0 authored by Johny Mattsson's avatar Johny Mattsson
Browse files

Merge branch 'dev-esp32-idf4-lua53' into dev-esp32-idf4

parents 3a6961cc 8e5ce49d
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#define _NODEMCU_LNODEAUX_H_ #define _NODEMCU_LNODEAUX_H_
#include "lua.h" #include "lua.h"
#include <stdbool.h>
// lua_ref_t represents a reference to a lua object in the registry // lua_ref_t represents a reference to a lua object in the registry
typedef int lua_ref_t; typedef int lua_ref_t;
......
#include "lpanic.h"
#include "lauxlib.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef LUA_CROSS_COMPILER
#include "esp_system.h"
/* defined in esp_system_internal.h */
void esp_reset_reason_set_hint(esp_reset_reason_t hint);
#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;
void panic_clear_nvval() {
l_rtc_panic_val = 0xD1EC0DE0;
}
int panic_get_nvval() {
if ((l_rtc_panic_val & 0xfffffff0) == 0xD1EC0DE0) {
return (l_rtc_panic_val & 0xf);
}
panic_clear_nvval();
return 0;
}
#endif
int lpanic (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
lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
#ifndef LUA_CROSS_COMPILER
fflush(stdout);
/* call abort() directly - we don't want another reset cause to intervene */
esp_reset_reason_set_hint(ESP_RST_PANIC);
#endif
abort();
while (1) {}
return 0;
}
#ifndef _LUA_PANIC_H_
#define _LUA_PANIC_H_
#include "lua.h"
void panic_clear_nvval (void);
int panic_get_nvval (void);
int lpanic (lua_State *L);
#endif
// Lua EGC (Emergeny Garbage Collector) interface
#include "legc.h"
#include "lstate.h"
void legc_set_mode(lua_State *L, int mode, int limit) {
global_State *g = G(L);
g->egcmode = mode;
g->memlimit = limit;
}
// 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 ...@@ -2,72 +2,54 @@ all: build
HOSTCC?=$(PYTHON) -m ziglang cc 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,) ifeq ($V,)
Q:=@ Q:=@
endif 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_OBJ_DIR:=$(LUAC_BUILD_DIR)/$(notdir $(LUA_PATH))
LUAC_LDFLAGS:= -ldl -lm
LUAC_DEFINES += -DLUA_CROSS_COMPILER -DLUA_USE_STDIO LUAC_CFLAGS:= \
ifneq ($(CONFIG_LUA_OPTIMIZE_DEBUG),) -I$(LUAC_BUILD_DIR) \
LUAC_DEFINES += -DLUA_OPTIMIZE_DEBUG=$(CONFIG_LUA_OPTIMIZE_DEBUG) -I$(LUA_PATH) \
endif -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_DEFINES += \
luac.c lflashimg.c loslib.c print.c liolib.c -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 \ 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 \ lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c lparser.c \
lrotable.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c \ lnodemcu.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c \
ltm.c lundump.c lvm.c lzio.c \ ltm.c lundump.c lvm.c lzio.c \
) linit.c lpanic.c \
LUAC_UZSRC:= $(addprefix $(COMPONENT_PATH)/../uzlib/, \
uzlib_deflate.c crc32.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_CROSS:=$(LUAC_BUILD_DIR)/luac.cross
$(LUAC_BUILD_DIR): $(LUAC_OBJ_DIR):
@mkdir -p "$@" @mkdir -p "$@"
$(LUAC_BUILD_DIR)/%.o: %.c | $(LUAC_BUILD_DIR) $(LUAC_OBJ_DIR)/%.o: %.c | $(LUAC_OBJ_DIR)
@echo '[hostcc] $(notdir $@)' @echo '[hostcc] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) "$<" -c -o "$@" $Q$(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) "$<" -c -o "$@"
$(LUAC_BUILD_DIR)/%.d: SHELL=/bin/bash $(LUAC_OBJ_DIR)/%.d: SHELL=/bin/bash
$(LUAC_BUILD_DIR)/%.d: %.c | $(LUAC_BUILD_DIR) $(LUAC_OBJ_DIR)/%.d: %.c | $(LUAC_OBJ_DIR)
@echo '[ dep] $<' @echo '[ dep] $<'
@rm -f "$@" @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) build: $(LUAC_DEPS) $(LUAC_CROSS)
...@@ -75,6 +57,12 @@ $(LUAC_CROSS): $(LUAC_OBJS) ...@@ -75,6 +57,12 @@ $(LUAC_CROSS): $(LUAC_OBJS)
@echo '[ link] $(notdir $@)' @echo '[ link] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_CFLAGS) $^ $(LUAC_LDFLAGS) -o "$@" $Q$(HOSTCC) $(LUAC_CFLAGS) $^ $(LUAC_LDFLAGS) -o "$@"
ifneq ($(MAKECMDGOALS),clean) # zig cc (0.8.0 at least) seems to get itself all confused with its cache
-include $(LUAC_DEPS) # 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 endif
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -109,10 +108,11 @@ static uint *flashAddrTag = flashImage + LUA_MAX_FLASH_SIZE; ...@@ -109,10 +108,11 @@ static uint *flashAddrTag = flashImage + LUA_MAX_FLASH_SIZE;
#define setFlashAddrTag(v) flashAddrTag[_TW(v)] |= _TB(v) #define setFlashAddrTag(v) flashAddrTag[_TW(v)] |= _TB(v)
#define getFlashAddrTag(v) ((flashAddrTag[_TW(v)]&_TB(v)) != 0) #define getFlashAddrTag(v) ((flashAddrTag[_TW(v)]&_TB(v)) != 0)
#define fatal luac_fatal
#ifdef _MSC_VER #ifdef _MSC_VER
extern void __declspec( noreturn ) fatal( const char* message ); extern void __declspec( noreturn ) luac_fatal( const char* message );
#else #else
extern void __attribute__((noreturn)) fatal(const char* message); extern void __attribute__((noreturn)) luac_fatal(const char* message);
#endif #endif
#ifdef LOCAL_DEBUG #ifdef LOCAL_DEBUG
...@@ -188,10 +188,8 @@ static void scanProtoStrings(lua_State *L, const Proto* f) { ...@@ -188,10 +188,8 @@ static void scanProtoStrings(lua_State *L, const Proto* f) {
if (f->source) if (f->source)
addTS(L, f->source); addTS(L, f->source);
#ifdef LUA_OPTIMIZE_DEBUG
if (f->packedlineinfo) if (f->packedlineinfo)
addTS(L, luaS_new(L, cast(const char *, f->packedlineinfo))); addTS(L, luaS_new(L, cast(const char *, f->packedlineinfo)));
#endif
for (i = 0; i < f->sizek; i++) { for (i = 0; i < f->sizek; i++) {
if (ttisstring(f->k + i)) if (ttisstring(f->k + i))
...@@ -357,11 +355,7 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) { ...@@ -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 */ /* The debug optimised version has a different Proto layout */
#ifdef LUA_OPTIMIZE_DEBUG
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIAI" #define PROTO_COPY_MASK "AHAAAAAASIIIIIIIAI"
#else
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIIAI"
#endif
/* /*
* Do the actual prototype copy. * Do the actual prototype copy.
...@@ -385,14 +379,10 @@ static void *functionToFlash(lua_State* L, const Proto* orig) { ...@@ -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.k = cast(TValue *, flashCopy(L, f.sizek, "V", f.k));
f.code = cast(Instruction *, flashCopy(L, f.sizecode, "I", f.code)); f.code = cast(Instruction *, flashCopy(L, f.sizecode, "I", f.code));
#ifdef LUA_OPTIMIZE_DEBUG
if (f.packedlineinfo) { if (f.packedlineinfo) {
TString *ts=luaS_new(L, cast(const char *,f.packedlineinfo)); TString *ts=luaS_new(L, cast(const char *,f.packedlineinfo));
f.packedlineinfo = cast(unsigned char *, resolveTString(L, ts)) + sizeof (FlashTS); 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.locvars = cast(struct LocVar *, flashCopy(L, f.sizelocvars, "SII", f.locvars));
f.upvalues = cast(TString **, flashCopy(L, f.sizeupvalues, "S", f.upvalues)); f.upvalues = cast(TString **, flashCopy(L, f.sizeupvalues, "S", f.upvalues));
return cast(void *, flashCopy(L, 1, PROTO_COPY_MASK, &f)); return cast(void *, flashCopy(L, 1, PROTO_COPY_MASK, &f));
...@@ -401,10 +391,10 @@ static void *functionToFlash(lua_State* L, const Proto* orig) { ...@@ -401,10 +391,10 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w, uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
void* data, int strip, void* data, int strip,
lu_int32 address, lu_int32 maxSize) { lu_int32 address, lu_int32 maxSize) {
(void)strip;
// parameter strip is ignored for now // parameter strip is ignored for now
(void)strip;
FlashHeader *fh = cast(FlashHeader *, flashAlloc(L, sizeof(FlashHeader))); FlashHeader *fh = cast(FlashHeader *, flashAlloc(L, sizeof(FlashHeader)));
int status; int i, status;
lua_newtable(L); lua_newtable(L);
scanProtoStrings(L, main); scanProtoStrings(L, main);
createROstrt(L, fh); createROstrt(L, fh);
...@@ -416,7 +406,7 @@ uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w, ...@@ -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"); fatal ("The image is too large for specfied LFS size");
} }
if (address) { /* in absolute mode convert addresses to mapped address */ 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)) if (getFlashAddrTag(i))
flashImage[i] = 4*flashImage[i] + address; flashImage[i] = 4*flashImage[i] + address;
lua_unlock(L); lua_unlock(L);
...@@ -434,7 +424,7 @@ uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w, ...@@ -434,7 +424,7 @@ uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
status = uzlib_compress (&oBuf, &oLen, status = uzlib_compress (&oBuf, &oLen,
(const uint8_t *)flashImage, bmLen+fh->flash_size); (const uint8_t *)flashImage, bmLen+fh->flash_size);
if (status != UZLIB_OK) { if (status != UZLIB_OK) {
fatal("Out of memory during image compression"); luac_fatal("Out of memory during image compression");
} }
lua_unlock(L); lua_unlock(L);
#if 0 #if 0
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h" #include "lnodemcu.h"
#define IO_INPUT 1 #define IO_INPUT 1
#define IO_OUTPUT 2 #define IO_OUTPUT 2
...@@ -439,7 +439,10 @@ static int f_flush (lua_State *L) { ...@@ -439,7 +439,10 @@ static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL); 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( close, io_close )
LROT_FUNCENTRY( flush, io_flush ) LROT_FUNCENTRY( flush, io_flush )
LROT_FUNCENTRY( input, io_input ) LROT_FUNCENTRY( input, io_input )
...@@ -449,10 +452,14 @@ LROT_PUBLIC_BEGIN(iolib) ...@@ -449,10 +452,14 @@ LROT_PUBLIC_BEGIN(iolib)
LROT_FUNCENTRY( read, io_read ) LROT_FUNCENTRY( read, io_read )
LROT_FUNCENTRY( type, io_type ) LROT_FUNCENTRY( type, io_type )
LROT_FUNCENTRY( write, io_write ) LROT_FUNCENTRY( write, io_write )
LROT_TABENTRY( __index, iolib ) LROT_END(iolib, NULL, LROT_MASK_GC_INDEX)
LROT_END(iolib, NULL, 0)
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( close, io_close )
LROT_FUNCENTRY( flush, f_flush ) LROT_FUNCENTRY( flush, f_flush )
LROT_FUNCENTRY( lines, f_lines ) LROT_FUNCENTRY( lines, f_lines )
...@@ -460,9 +467,6 @@ LROT_BEGIN(flib) ...@@ -460,9 +467,6 @@ LROT_BEGIN(flib)
LROT_FUNCENTRY( seek, f_seek ) LROT_FUNCENTRY( seek, f_seek )
LROT_FUNCENTRY( setvbuf, f_setvbuf ) LROT_FUNCENTRY( setvbuf, f_setvbuf )
LROT_FUNCENTRY( write, f_write ) 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) LROT_END(flib, NULL, LROT_MASK_GC_INDEX)
static const luaL_Reg io_base[] = {{NULL, NULL}}; static const luaL_Reg io_base[] = {{NULL, NULL}};
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <errno.h> #include <errno.h>
#include <locale.h> #include <locale.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -20,8 +19,7 @@ ...@@ -20,8 +19,7 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h" #include "lnodemcu.h"
static int os_pushresult (lua_State *L, int i, const char *filename) { static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */ int en = errno; /* calls to Lua API may change this value */
...@@ -221,32 +219,26 @@ static int os_exit (lua_State *L) { ...@@ -221,32 +219,26 @@ static int os_exit (lua_State *L) {
exit(luaL_optint(L, 1, EXIT_SUCCESS)); exit(luaL_optint(L, 1, EXIT_SUCCESS));
} }
#undef MIN_OPT_LEVEL LROT_BEGIN(oslib, NULL, 0)
#define MIN_OPT_LEVEL 1 LROT_FUNCENTRY( clock, os_clock )
#include "lrotable.h" LROT_FUNCENTRY( date, os_date )
LROT_PUBLIC_BEGIN(oslib)
LROT_FUNCENTRY(clock, os_clock)
LROT_FUNCENTRY(date, os_date)
#if !defined LUA_NUMBER_INTEGRAL #if !defined LUA_NUMBER_INTEGRAL
LROT_FUNCENTRY(difftime, os_difftime) LROT_FUNCENTRY( difftime, os_difftime )
#endif #endif
LROT_FUNCENTRY(execute, os_execute) LROT_FUNCENTRY( execute, os_execute )
LROT_FUNCENTRY(exit, os_exit) LROT_FUNCENTRY( exit, os_exit )
LROT_FUNCENTRY(getenv, os_getenv) LROT_FUNCENTRY( getenv, os_getenv )
LROT_FUNCENTRY(remove, os_remove) LROT_FUNCENTRY( remove, os_remove )
LROT_FUNCENTRY(rename, os_rename) LROT_FUNCENTRY( rename, os_rename )
LROT_FUNCENTRY(setlocale, os_setlocale) LROT_FUNCENTRY( setlocale, os_setlocale )
LROT_FUNCENTRY(time, os_time) LROT_FUNCENTRY( time, os_time )
LROT_FUNCENTRY(tmpname, os_tmpname) LROT_FUNCENTRY( tmpname, os_tmpname )
LROT_END(oslib, NULL, 0) LROT_END(oslib, NULL, 0)
/* }====================================================== */ /* }====================================================== */
LUALIB_API int luaopen_os (lua_State *L) { LUALIB_API int luaopen_os (lua_State *L) {
(void)L; (void)L;
//LREGISTER(L, LUA_OSLIBNAME, oslib); // <------------- ??? return 1;
return 0;
} }
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
*/ */
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#define luac_c
#define LUA_CORE
#include "luac_cross.h"
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#define luac_c
#define LUA_CORE
#include "lua.h" #include "lua.h"
#include "lauxlib.h" #include "lauxlib.h"
...@@ -42,11 +42,12 @@ static const char* execute; /* executed a Lua file */ ...@@ -42,11 +42,12 @@ static const char* execute; /* executed a Lua file */
static const char* progname=PROGNAME; /* actual program name */ static const char* progname=PROGNAME; /* actual program name */
static DumpTargetInfo target; static DumpTargetInfo target;
void fatal(const char* message) void luac_fatal(const char* message)
{ {
fprintf(stderr,"%s: %s\n",progname,message); fprintf(stderr,"%s: %s\n",progname,message);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#define fatal(s) luac_fatal(s)
static void cannot(const char* what) static void cannot(const char* what)
{ {
...@@ -280,8 +281,8 @@ static int pmain(lua_State* L) ...@@ -280,8 +281,8 @@ static int pmain(lua_State* L)
if (!lua_checkstack(L,argc)) fatal("too many input files"); if (!lua_checkstack(L,argc)) fatal("too many input files");
if (execute) if (execute)
{ {
if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
luaL_openlibs(L); luaL_openlibs(L);
if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
lua_pushstring(L, execute); lua_pushstring(L, execute);
if (lua_pcall(L, 1, 1, 0)) fatal(lua_tostring(L,-1)); if (lua_pcall(L, 1, 1, 0)) fatal(lua_tostring(L,-1));
if (!lua_isfunction(L, -1)) if (!lua_isfunction(L, -1))
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE #define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
......
...@@ -6,11 +6,9 @@ ...@@ -6,11 +6,9 @@
#define lapi_c #define lapi_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
//#include <assert.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include "lapi.h" #include "lapi.h"
...@@ -26,7 +24,6 @@ ...@@ -26,7 +24,6 @@
#include "ltm.h" #include "ltm.h"
#include "lundump.h" #include "lundump.h"
#include "lvm.h" #include "lvm.h"
#include "lrotable.h"
#if 0 #if 0
const char lua_ident[] = const char lua_ident[] =
...@@ -155,6 +152,16 @@ LUA_API lua_State *lua_newthread (lua_State *L) { ...@@ -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) { LUA_API int lua_gettop (lua_State *L) {
return cast_int(L->top - L->base); return cast_int(L->top - L->base);
} }
...@@ -243,6 +250,12 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) { ...@@ -243,6 +250,12 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
LUA_API int lua_type (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); StkId o = index2adr(L, idx);
return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
} }
...@@ -250,7 +263,7 @@ LUA_API int lua_type (lua_State *L, int idx) { ...@@ -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) { LUA_API const char *lua_typename (lua_State *L, int t) {
UNUSED(L); 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) { ...@@ -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) { LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
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) {
StkId o1, o2; StkId o1, o2;
int i; int i = 0;
lua_lock(L); /* may call tag method */ lua_lock(L); /* may call tag method */
o1 = index2adr(L, index1); o1 = index2adr(L, index1);
o2 = index2adr(L, index2); o2 = index2adr(L, index2);
i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 if (o1 != luaO_nilobject && o2 != luaO_nilobject) {
: luaV_lessthan(L, o1, o2); 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); lua_unlock(L);
return i; return i;
} }
LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
TValue n; TValue n;
const TValue *o = index2adr(L, idx); const TValue *o = index2adr(L, idx);
...@@ -363,11 +369,10 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { ...@@ -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) { LUA_API size_t lua_objlen (lua_State *L, int idx) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
switch (ttype(o)) { switch (ttnov(o)) {
case LUA_TSTRING: return tsvalue(o)->len; case LUA_TSTRING: return tsvalue(o)->len;
case LUA_TUSERDATA: return uvalue(o)->len; case LUA_TUSERDATA: return uvalue(o)->len;
case LUA_TTABLE: return luaH_getn(hvalue(o)); case LUA_TTABLE: return luaH_getn(hvalue(o));
case LUA_TROTABLE: return luaH_getn_ro(rvalue(o));
case LUA_TNUMBER: { case LUA_TNUMBER: {
size_t l; size_t l;
lua_lock(L); /* `luaV_tostring' may create a new string */ 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) { ...@@ -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) { LUA_API const void *lua_topointer (lua_State *L, int idx) {
StkId o = index2adr(L, idx); StkId o = index2adr(L, idx);
switch (ttype(o)) { 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_TFUNCTION: return clvalue(o);
case LUA_TTHREAD: return thvalue(o); case LUA_TTHREAD: return thvalue(o);
case LUA_TUSERDATA: case LUA_TUSERDATA: return lua_touserdata(L, idx);
case LUA_TLIGHTUSERDATA: case LUA_TLIGHTUSERDATA: return pvalue(o);
return lua_touserdata(L, idx); case LUA_TLIGHTFUNCTION: return fvalue(o);
case LUA_TROTABLE:
return rvalue(o);
case LUA_TLIGHTFUNCTION:
return fvalue(o);
default: return NULL; default: return NULL;
} }
} }
...@@ -492,18 +495,23 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { ...@@ -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) { LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
Closure *cl;
lua_lock(L); lua_lock(L);
luaC_checkGC(L); if (n == 0) {
api_checknelems(L, n); setfvalue(L->top, fn);
cl = luaF_newCclosure(L, n, getcurrenv(L)); api_incr_top(L);
cl->c.f = fn; } else {
L->top -= n; Closure *cl;
while (n--) luaC_checkGC(L);
setobj2n(L, &cl->c.upvalue[n], L->top+n); api_checknelems(L, n);
setclvalue(L, L->top, cl); cl = luaF_newCclosure(L, n, getcurrenv(L));
lua_assert(iswhite(obj2gco(cl))); cl->c.f = fn;
api_incr_top(L); 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); lua_unlock(L);
} }
...@@ -523,16 +531,10 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { ...@@ -523,16 +531,10 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
lua_unlock(L); 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); lua_lock(L);
setfvalue(L->top, p); sethvalue(L, L->top, cast(ROTable *,t));
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
...@@ -553,17 +555,17 @@ LUA_API int lua_pushthread (lua_State *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; StkId t;
lua_lock(L); lua_lock(L);
t = index2adr(L, idx); t = index2adr(L, idx);
api_checkvalidindex(L, t); api_checkvalidindex(L, t);
luaV_gettable(L, t, L->top - 1, L->top - 1); luaV_gettable(L, t, L->top - 1, L->top - 1);
lua_unlock(L); lua_unlock(L);
return ttnov(L->top - 1);
} }
LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
StkId t; StkId t;
TValue key; TValue key;
lua_lock(L); lua_lock(L);
...@@ -575,29 +577,58 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { ...@@ -575,29 +577,58 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
luaV_gettable(L, t, &key, L->top); luaV_gettable(L, t, &key, L->top);
api_incr_top(L); api_incr_top(L);
lua_unlock(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; StkId t;
const TValue *res;
lua_lock(L); lua_lock(L);
t = index2adr(L, idx); t = index2adr(L, idx);
api_check(L, ttistable(t) || ttisrotable(t)); api_check(L, ttistable(t));
res = ttistable(t) ? luaH_get(hvalue(t), L->top - 1) : luaH_get_ro(rvalue(t), L->top - 1); setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
setobj2s(L, L->top - 1, res);
lua_unlock(L); 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; StkId o;
lua_lock(L); lua_lock(L);
o = index2adr(L, idx); o = index2adr(L, idx);
api_check(L, ttistable(o) || ttisrotable(o)); api_check(L, ttistable(o));
setobj2s(L, L->top, ttistable(o) ? luaH_getnum(hvalue(o), n) : luaH_getnum_ro(rvalue(o), n)) 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); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
return ttnov(L->top - 1);
} }
...@@ -616,27 +647,21 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { ...@@ -616,27 +647,21 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
int res; int res;
lua_lock(L); lua_lock(L);
obj = index2adr(L, objindex); obj = index2adr(L, objindex);
switch (ttype(obj)) { switch (ttnov(obj)) {
case LUA_TTABLE: case LUA_TTABLE:
mt = hvalue(obj)->metatable; mt = hvalue(obj)->metatable;
break; break;
case LUA_TUSERDATA: case LUA_TUSERDATA:
mt = uvalue(obj)->metatable; mt = uvalue(obj)->metatable;
break; break;
case LUA_TROTABLE:
mt = (Table*)luaR_getmeta(rvalue(obj));
break;
default: default:
mt = G(L)->mt[ttype(obj)]; mt = G(L)->mt[ttnov(obj)];
break; break;
} }
if (mt == NULL) if (mt == NULL)
res = 0; res = 0;
else { else {
if(luaR_isrotable(mt)) sethvalue(L, L->top, mt)
setrvalue(L->top, mt)
else
sethvalue(L, L->top, mt)
api_incr_top(L); api_incr_top(L);
res = 1; res = 1;
} }
...@@ -730,40 +755,54 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) { ...@@ -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) { LUA_API int lua_setmetatable (lua_State *L, int objindex) {
TValue *obj; TValue *obj;
Table *mt; Table *mt;
int isrometa = 0;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
obj = index2adr(L, objindex); obj = index2adr(L, objindex);
api_checkvalidindex(L, obj); api_checkvalidindex(L, obj);
if (ttisnil(L->top - 1)) if (ttisnil(L->top - 1)) {
mt = NULL; mt = NULL;
else { } else {
api_check(L, ttistable(L->top - 1) || ttisrotable(L->top - 1)); api_check(L, ttistable(L->top - 1));
if (ttistable(L->top - 1)) mt = hvalue(L->top - 1);
mt = hvalue(L->top - 1);
else {
mt = (Table*)rvalue(L->top - 1);
isrometa = 1;
}
} }
switch (ttype(obj)) { switch (ttype(obj)) { /* use basetype to retain subtypes*/
case LUA_TTABLE: { case LUA_TTABLE: {
hvalue(obj)->metatable = mt; hvalue(obj)->metatable = mt;
if (mt && !isrometa) if (mt && !isrotable(mt))
luaC_objbarriert(L, hvalue(obj), mt); luaC_objbarriert(L, hvalue(obj), mt);
break; break;
} }
case LUA_TUSERDATA: { case LUA_TUSERDATA: {
uvalue(obj)->metatable = mt; uvalue(obj)->metatable = mt;
if (mt && !isrometa) if (mt && !isrotable(mt))
luaC_objbarrier(L, rawuvalue(obj), mt); luaC_objbarrier(L, rawuvalue(obj), mt);
break; break;
} }
case LUA_TISROTABLE: { /* Ignore any changes to a ROTable MT */
break;
}
default: { default: {
G(L)->mt[ttype(obj)] = mt; G(L)->mt[ttnov(obj)] = mt;
break; break;
} }
} }
...@@ -813,7 +852,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { ...@@ -813,7 +852,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
#define checkresults(L,na,nr) \ #define checkresults(L,na,nr) \
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) 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) { LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
StkId func; StkId func;
...@@ -914,14 +953,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, ...@@ -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; int status;
TValue *o; TValue *o;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
o = L->top - 1; o = L->top - 1;
if (isLfunction(o)) 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 else
status = 1; status = 1;
lua_unlock(L); lua_unlock(L);
...@@ -929,6 +968,30 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { ...@@ -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) { LUA_API int lua_status (lua_State *L) {
return L->status; return L->status;
} }
...@@ -1039,8 +1102,8 @@ LUA_API int lua_next (lua_State *L, int idx) { ...@@ -1039,8 +1102,8 @@ LUA_API int lua_next (lua_State *L, int idx) {
int more; int more;
lua_lock(L); lua_lock(L);
t = index2adr(L, idx); t = index2adr(L, idx);
api_check(L, ttistable(t) || ttisrotable(t)); api_check(L, ttistable(t));
more = ttistable(t) ? luaH_next(L, hvalue(t), L->top - 1) : luaH_next_ro(L, rvalue(t), L->top - 1); more = luaH_next(L, hvalue(t), L->top - 1);
if (more) { if (more) {
api_incr_top(L); api_incr_top(L);
} }
...@@ -1149,3 +1212,15 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { ...@@ -1149,3 +1212,15 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
return name; 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 @@ ...@@ -4,20 +4,16 @@
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <fcntl.h>
#ifndef LUA_CROSS_COMPILER #ifndef LUA_CROSS_COMPILER
#include "esp_system.h" #include "esp_system.h"
#include "vfs.h" #include "vfs.h"
/* defined in esp_system_internal.h */
void esp_reset_reason_set_hint(esp_reset_reason_t hint);
#else
#endif #endif
/* This file uses only the official API of Lua. /* This file uses only the official API of Lua.
...@@ -27,14 +23,14 @@ void esp_reset_reason_set_hint(esp_reset_reason_t hint); ...@@ -27,14 +23,14 @@ void esp_reset_reason_set_hint(esp_reset_reason_t hint);
#define lauxlib_c #define lauxlib_c
#define LUA_LIB #define LUA_LIB
#include "lrotable.h" #include "lnodemcu.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lgc.h" #include "lgc.h"
#include "ldo.h" #include "ldo.h"
#include "lobject.h" #include "lobject.h"
#include "lstate.h" #include "lstate.h"
#include "legc.h" #include "lpanic.h"
#define FREELIST_REF 0 /* free list of references */ #define FREELIST_REF 0 /* free list of references */
...@@ -277,7 +273,7 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { ...@@ -277,7 +273,7 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
return 1; 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 */ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
if (!lua_isnil(L, -1)) /* name already in use? */ if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */ 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) { ...@@ -288,21 +284,25 @@ LUALIB_API int luaL_rometatable (lua_State *L, const char* tname, void *p) {
return 1; 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); void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */ if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ if (!lua_rawequal(L, -1, -2)) /* not the same? */
lua_pop(L, 2); /* remove both metatables */ p = NULL; /* value is a userdata with wrong metatable */
return p; lua_pop(L, 2); /* remove both metatables */
} return p;
} }
} }
luaL_typerror(L, ud, tname); /* else error */ return NULL; /* value is not a userdata with a metatable */
return NULL; /* to avoid warnings */
} }
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) { LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
if (!lua_checkstack(L, space)) if (!lua_checkstack(L, space))
...@@ -315,22 +315,6 @@ LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { ...@@ -315,22 +315,6 @@ LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
tag_error(L, narg, 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) { LUALIB_API void luaL_checkany (lua_State *L, int narg) {
if (lua_type(L, narg) == LUA_TNONE) if (lua_type(L, narg) == LUA_TNONE)
...@@ -449,7 +433,7 @@ LUALIB_API void luaI_openlib (lua_State *L, const char *libname, ...@@ -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 */ for (i=0; i<nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup); lua_pushvalue(L, -nup);
if (ftype == LUA_USELIGHTFUNCTIONS) if (ftype == LUA_USELIGHTFUNCTIONS)
lua_pushlightfunction(L, l->func); lua_pushcfunction(L, l->func);
else else
lua_pushcclosure(L, l->func, nup); lua_pushcclosure(L, l->func, nup);
lua_setfield(L, -(nup+2), l->name); lua_setfield(L, -(nup+2), l->name);
...@@ -561,7 +545,7 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx, ...@@ -561,7 +545,7 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */ 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 */ lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */ return fname; /* return problematic part of the name */
} }
...@@ -703,6 +687,26 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { ...@@ -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) { ...@@ -710,14 +714,33 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
** ======================================================= ** =======================================================
*/ */
#ifdef LUA_CROSS_COMPILER
typedef struct LoadF { typedef struct LoadF {
int extraline; int extraline;
#ifdef LUA_CROSS_COMPILER
FILE *f; FILE *f;
#else
int f;
#endif
char buff[LUAL_BUFFERSIZE]; char buff[LUAL_BUFFERSIZE];
} LoadF; } 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) { static const char *getF (lua_State *L, void *ud, size_t *size) {
LoadF *lf = (LoadF *)ud; LoadF *lf = (LoadF *)ud;
...@@ -728,7 +751,7 @@ static const char *getF (lua_State *L, void *ud, size_t *size) { ...@@ -728,7 +751,7 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
return "\n"; return "\n";
} }
if (feof(lf->f)) return NULL; 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; return (*size > 0) ? lf->buff : NULL;
} }
...@@ -748,14 +771,19 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { ...@@ -748,14 +771,19 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
int c; int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0; lf.extraline = 0;
if (filename == NULL) { if (filename == NULL) {
#ifdef LUA_CROSS_COMPILER
lua_pushliteral(L, "=stdin"); lua_pushliteral(L, "=stdin");
lf.f = stdin; lf.f = stdin;
#else
return luaL_error(L, "filename is NULL");
#endif
} }
else { else {
lua_pushfstring(L, "@%s", filename); lua_pushfstring(L, "@%s", filename);
lf.f = fopen(filename, "r"); 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); c = getc(lf.f);
if (c == '#') { /* Unix exec. file? */ if (c == '#') { /* Unix exec. file? */
...@@ -764,8 +792,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { ...@@ -764,8 +792,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
if (c == '\n') c = getc(lf.f); if (c == '\n') c = getc(lf.f);
} }
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ lf.f = freopen_bin(filename, lf.f); /* reopen in binary mode */
if (lf.f == NULL) return errfile(L, "reopen", fnameindex); if (!lf.f) return errfile(L, "reopen", fnameindex);
/* skip eventual `#!...' */ /* skip eventual `#!...' */
while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) {} 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) { ...@@ -773,95 +801,21 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
} }
ungetc(c, lf.f); ungetc(c, lf.f);
status = lua_load(L, getF, &lf, lua_tostring(L, -1)); status = lua_load(L, getF, &lf, lua_tostring(L, -1));
#ifdef LUA_CROSS_COMPILER
readstatus = ferror(lf.f); readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */ if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) { if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */ lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, "read", fnameindex); return errfile(L, "read", fnameindex);
} }
lua_remove(L, fnameindex);
return status;
}
#else #else
(void) readstatus;
#include <fcntl.h> if (filename) vfs_close(lf.f); /* close file (even in case of errors) */
#endif
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) */
lua_remove(L, fnameindex); lua_remove(L, fnameindex);
return status; return status;
} }
#endif
typedef struct LoadS { typedef struct LoadS {
const char *s; const char *s;
...@@ -959,56 +913,11 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message) ...@@ -959,56 +913,11 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
#endif #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) { LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL); lua_State *L = lua_newstate(l_alloc, NULL);
lua_setallocf(L, l_alloc, L); /* allocator need lua_State. */ lua_setallocf(L, l_alloc, L); /* allocator need lua_State. */
if (L) lua_atpanic(L, &panic); if (L) lua_atpanic(L, lpanic);
return L; return L;
} }
...@@ -8,12 +8,13 @@ ...@@ -8,12 +8,13 @@
#ifndef lauxlib_h #ifndef lauxlib_h
#define lauxlib_h #define lauxlib_h
#include "lua.h" #include "lua.h"
#ifdef LUA_LIB
#include "lnodemcu.h"
#endif
#include <stdio.h> #include <stdio.h>
#if defined(LUA_COMPAT_GETN) #if defined(LUA_COMPAT_GETN)
LUALIB_API int (luaL_getn) (lua_State *L, int t); LUALIB_API int (luaL_getn) (lua_State *L, int t);
LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); 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, ...@@ -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, LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l); const luaL_Reg *l);
LUALIB_API void (luaL_register_light) (lua_State *L, const char *libname, 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_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_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); 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, ...@@ -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_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_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 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_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_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_where) (lua_State *L, int lvl); 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, ...@@ -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 int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 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); 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, LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name); const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 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) ...@@ -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_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) #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_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))) #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) ...@@ -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)) (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#else #else
#define luaL_dofile(L, fn) \ #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 #endif
#define luaL_dostring(L, s) \ #define luaL_dostring(L, s) \
...@@ -165,6 +169,18 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); ...@@ -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 */ /* compatibility with ref system */
...@@ -184,7 +200,3 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); ...@@ -184,7 +200,3 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
#endif #endif
#ifndef LUA_CROSS_COMPILER
int panic_get_nvval();
void panic_clear_nvval();
#endif
...@@ -8,17 +8,14 @@ ...@@ -8,17 +8,14 @@
#define lbaselib_c #define lbaselib_c
#define LUA_LIB #define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h"
/* /*
...@@ -27,6 +24,10 @@ ...@@ -27,6 +24,10 @@
** model but changing `fputs' to put the strings at a proper place ** model but changing `fputs' to put the strings at a proper place
** (a console window or a log file, for instance). ** (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) { static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */ int n = lua_gettop(L); /* number of arguments */
int i; int i;
...@@ -40,20 +41,11 @@ static int luaB_print (lua_State *L) { ...@@ -40,20 +41,11 @@ static int luaB_print (lua_State *L) {
if (s == NULL) if (s == NULL)
return luaL_error(L, LUA_QL("tostring") " must return a string to " return luaL_error(L, LUA_QL("tostring") " must return a string to "
LUA_QL("print")); LUA_QL("print"));
#if defined(LUA_USE_STDIO) if (i>1) puts("\t");
if (i>1) fputs("\t", stdout); puts(s);
fputs(s, stdout);
#else
if (i>1) luai_writestring("\t", 1);
luai_writestring(s, strlen(s));
#endif
lua_pop(L, 1); /* pop result */ lua_pop(L, 1); /* pop result */
} }
#if defined(LUA_USE_STDIO) puts("\n");
fputs("\n", stdout);
#else
luai_writeline();
#endif
return 0; return 0;
} }
...@@ -112,7 +104,7 @@ static int luaB_getmetatable (lua_State *L) { ...@@ -112,7 +104,7 @@ static int luaB_getmetatable (lua_State *L) {
static int luaB_setmetatable (lua_State *L) { static int luaB_setmetatable (lua_State *L) {
int t = lua_type(L, 2); int t = lua_type(L, 2);
luaL_checktype(L, 1, LUA_TTABLE); 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"); "nil or table expected");
if (luaL_getmetafield(L, 1, "__metatable")) if (luaL_getmetafield(L, 1, "__metatable"))
luaL_error(L, "cannot change a protected metatable"); luaL_error(L, "cannot change a protected metatable");
...@@ -175,7 +167,7 @@ static int luaB_rawequal (lua_State *L) { ...@@ -175,7 +167,7 @@ static int luaB_rawequal (lua_State *L) {
static int luaB_rawget (lua_State *L) { static int luaB_rawget (lua_State *L) {
luaL_checkanytable(L, 1); luaL_checktable(L, 1);
luaL_checkany(L, 2); luaL_checkany(L, 2);
lua_settop(L, 2); lua_settop(L, 2);
lua_rawget(L, 1); lua_rawget(L, 1);
...@@ -183,7 +175,7 @@ static int luaB_rawget (lua_State *L) { ...@@ -183,7 +175,7 @@ static int luaB_rawget (lua_State *L) {
} }
static int luaB_rawset (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, 2);
luaL_checkany(L, 3); luaL_checkany(L, 3);
lua_settop(L, 3); lua_settop(L, 3);
...@@ -233,7 +225,7 @@ static int luaB_type (lua_State *L) { ...@@ -233,7 +225,7 @@ static int luaB_type (lua_State *L) {
static int luaB_next (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 */ lua_settop(L, 2); /* create a 2nd argument if there isn't one */
if (lua_next(L, 1)) if (lua_next(L, 1))
return 2; return 2;
...@@ -245,7 +237,7 @@ static int luaB_next (lua_State *L) { ...@@ -245,7 +237,7 @@ static int luaB_next (lua_State *L) {
static int luaB_pairs (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, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */ lua_pushvalue(L, 1); /* state, */
lua_pushnil(L); /* and initial value */ lua_pushnil(L); /* and initial value */
...@@ -255,7 +247,7 @@ static int luaB_pairs (lua_State *L) { ...@@ -255,7 +247,7 @@ static int luaB_pairs (lua_State *L) {
static int ipairsaux (lua_State *L) { static int ipairsaux (lua_State *L) {
int i = luaL_checkint(L, 2); int i = luaL_checkint(L, 2);
luaL_checkanytable(L, 1); luaL_checktable(L, 1);
i++; /* next value */ i++; /* next value */
lua_pushinteger(L, i); lua_pushinteger(L, i);
lua_rawgeti(L, 1, i); lua_rawgeti(L, 1, i);
...@@ -264,7 +256,7 @@ static int ipairsaux (lua_State *L) { ...@@ -264,7 +256,7 @@ static int ipairsaux (lua_State *L) {
static int luaB_ipairs (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, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */ lua_pushvalue(L, 1); /* state, */
lua_pushinteger(L, 0); /* and initial value */ lua_pushinteger(L, 0); /* and initial value */
...@@ -296,7 +288,7 @@ static int luaB_loadfile (lua_State *L) { ...@@ -296,7 +288,7 @@ static int luaB_loadfile (lua_State *L) {
#ifdef LUA_CROSS_COMPILER #ifdef LUA_CROSS_COMPILER
return load_aux(L, luaL_loadfile(L, fname)); return load_aux(L, luaL_loadfile(L, fname));
#else #else
return load_aux(L, luaL_loadfsfile(L, fname)); return load_aux(L, luaL_loadfile(L, fname));
#endif #endif
} }
...@@ -343,7 +335,7 @@ static int luaB_dofile (lua_State *L) { ...@@ -343,7 +335,7 @@ static int luaB_dofile (lua_State *L) {
#ifdef LUA_CROSS_COMPILER #ifdef LUA_CROSS_COMPILER
if (luaL_loadfile(L, fname) != 0) lua_error(L); if (luaL_loadfile(L, fname) != 0) lua_error(L);
#else #else
if (luaL_loadfsfile(L, fname) != 0) lua_error(L); if (luaL_loadfile(L, fname) != 0) lua_error(L);
#endif #endif
lua_call(L, 0, LUA_MULTRET); lua_call(L, 0, LUA_MULTRET);
return lua_gettop(L) - n; return lua_gettop(L) - n;
...@@ -462,29 +454,24 @@ static int luaB_newproxy (lua_State *L) { ...@@ -462,29 +454,24 @@ static int luaB_newproxy (lua_State *L) {
return 1; return 1;
} }
#include "lrotable.h"
LROT_EXTERN(lua_rotable_base);
/* /*
* Separate ROTables are used for the base functions and library ROTables, with ** ESP builds use specific linker directives to marshal all the ROTable entries
* the base functions ROTable declared below. The library ROTable is chained ** for the library modules including the base library into an entry vector in
* from this using its __index meta-method. ** 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
* ESP builds use specific linker directives to marshal all the ROTable entries ** _G so that base library and ROM tables are directly resolved through _G.
* 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 ** The host-based luac.cross builds which must use a standard GNU link or
* equivalent ROTable for the core libraries defined in linit.c for the cross- ** MSVC so this linker-specfic assembly approach can't be used. In this case
* compiler build. ** luaopen_base returns a base_func ROTable so a two cascade resolution. See
*/ ** description in init.c for further details.
*/
LROT_EXTERN(lua_rotables); #ifdef LUA_CROSS_COMPILER
LROT_BEGIN(base_func, NULL, 0)
LROT_PUBLIC_BEGIN(base_func_meta) #else
LROT_TABENTRY( __index, lua_rotables ) LROT_ENTRIES_IN_SECTION(base_func, rotable)
LROT_END(base_func, base_func_meta, LROT_MASK_INDEX) #endif
LROT_PUBLIC_BEGIN(base_func)
LROT_FUNCENTRY(assert, luaB_assert) LROT_FUNCENTRY(assert, luaB_assert)
LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage) LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage)
LROT_FUNCENTRY(dofile, luaB_dofile) LROT_FUNCENTRY(dofile, luaB_dofile)
...@@ -509,13 +496,11 @@ LROT_PUBLIC_BEGIN(base_func) ...@@ -509,13 +496,11 @@ LROT_PUBLIC_BEGIN(base_func)
LROT_FUNCENTRY(type, luaB_type) LROT_FUNCENTRY(type, luaB_type)
LROT_FUNCENTRY(unpack, luaB_unpack) LROT_FUNCENTRY(unpack, luaB_unpack)
LROT_FUNCENTRY(xpcall, luaB_xpcall) LROT_FUNCENTRY(xpcall, luaB_xpcall)
LROT_TABENTRY(__metatable, base_func_meta) #ifdef LUA_CROSS_COMPILER
LROT_END(base_func, base_func_meta, LROT_MASK_INDEX) LROT_END(base_func, NULL, 0)
#else
LROT_BEGIN(G_meta) LROT_BREAK(base_func)
LROT_TABENTRY( __index, base_func ) #endif
LROT_END(G_meta, NULL, 0)
/* /*
** {====================================================== ** {======================================================
...@@ -645,14 +630,14 @@ static int luaB_corunning (lua_State *L) { ...@@ -645,14 +630,14 @@ static int luaB_corunning (lua_State *L) {
return 1; return 1;
} }
LROT_PUBLIC_BEGIN(co_funcs) LROT_BEGIN(co_funcs, NULL, 0)
LROT_FUNCENTRY( create, luaB_cocreate ) LROT_FUNCENTRY( create, luaB_cocreate )
LROT_FUNCENTRY( resume, luaB_coresume ) LROT_FUNCENTRY( resume, luaB_coresume )
LROT_FUNCENTRY( running, luaB_corunning ) LROT_FUNCENTRY( running, luaB_corunning )
LROT_FUNCENTRY( status, luaB_costatus ) LROT_FUNCENTRY( status, luaB_costatus )
LROT_FUNCENTRY( wrap, luaB_cowrap ) LROT_FUNCENTRY( wrap, luaB_cowrap )
LROT_FUNCENTRY( yield, luaB_yield ) 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, ...@@ -661,19 +646,13 @@ static void auxopen (lua_State *L, const char *name,
lua_CFunction f, lua_CFunction u) { lua_CFunction f, lua_CFunction u) {
lua_pushcfunction(L, u); lua_pushcfunction(L, u);
lua_pushcclosure(L, f, 1); lua_pushcclosure(L, f, 1);
lua_setfield(L, -2, name); lua_setglobal(L, name);
} }
static void base_open (lua_State *L) { extern LROT_TABLE(rotables);
/* set global _G */ LUALIB_API int luaopen_base (lua_State *L) {
lua_pushvalue(L, LUA_GLOBALSINDEX); lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G"); lua_settable(L, LUA_GLOBALSINDEX); /* set global _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_pushliteral(L, LUA_VERSION); lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */ lua_setglobal(L, "_VERSION"); /* set global _VERSION */
/* `ipairs' and `pairs' need auxliliary functions as upvalues */ /* `ipairs' and `pairs' need auxliliary functions as upvalues */
...@@ -681,16 +660,15 @@ static void base_open (lua_State *L) { ...@@ -681,16 +660,15 @@ static void base_open (lua_State *L) {
auxopen(L, "pairs", luaB_pairs, luaB_next); auxopen(L, "pairs", luaB_pairs, luaB_next);
/* `newproxy' needs a weaktable as upvalue */ /* `newproxy' needs a weaktable as upvalue */
lua_createtable(L, 0, 1); /* new table `w' */ 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_pushliteral(L, "kv");
lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "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' */ lua_setglobal(L, "newproxy"); /* set global `newproxy' */
} lua_pushrotable(L, LROT_TABLEREF(rotables));
lua_setglobal(L, "__index");
lua_pushvalue(L, LUA_GLOBALSINDEX); /* _G is its own metatable */
LUALIB_API int luaopen_base (lua_State *L) { lua_setmetatable(L, LUA_GLOBALSINDEX);
base_open(L); return 0;
return 1;
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment