Commit bbeb09b6 authored by Terry Ellison's avatar Terry Ellison Committed by Marcel Stör
Browse files

Squashed updates do get Lua51 and Lua53 working (#3075)

-  Lots of minor but nasty bugfixes to get all tests to run clean
-  core lua and test suite fixes to allow luac -F to run cleanly against test suite
-  next tranch to get LFS working
-  luac.cross -a options plus fixes from feedback
-  UART fixes and lua.c merge
-  commit of wip prior to rebaselining against current dev
-  more tweaks
parent 99aba344
...@@ -13,6 +13,13 @@ ...@@ -13,6 +13,13 @@
#include <stdbool.h> #include <stdbool.h>
#include "user_config.h" #include "user_config.h"
#ifdef __XTENSA__
# define LUA_USE_ESP
#else
# define LUA_USE_HOST
#endif
/* /*
** ================================================================== ** ==================================================================
** Search for "@@" to find all configurable definitions. ** Search for "@@" to find all configurable definitions.
...@@ -266,16 +273,6 @@ ...@@ -266,16 +273,6 @@
#endif #endif
/*
@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
** CHANGE them if you want different prompts. (You can also change the
** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
*/
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
/* /*
@@ LUA_PROGNAME is the default name for the stand-alone Lua program. @@ LUA_PROGNAME is the default name for the stand-alone Lua program.
** CHANGE it if your stand-alone interpreter has a different name and ** CHANGE it if your stand-alone interpreter has a different name and
...@@ -300,25 +297,6 @@ ...@@ -300,25 +297,6 @@
** CHANGE them if you want to improve this functionality (e.g., by using ** CHANGE them if you want to improve this functionality (e.g., by using
** GNU readline and history facilities). ** GNU readline and history facilities).
*/ */
#if defined(LUA_USE_STDIO)
#if defined(LUA_CROSS_COMPILER) && defined(LUA_USE_READLINE)
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
#define lua_saveline(L,idx) \
if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
add_history(lua_tostring(L, idx)); /* add it to history */
#define lua_freeline(L,b) ((void)L, free(b))
#else // #if defined(LUA_CROSS_COMPILER) && defined(LUA_USE_READLINE)
#define lua_readline(L,b,p) \
((void)L, fputs(p, c_stdout), fflush(c_stdout), /* show prompt */ \
fgets(b, LUA_MAXINPUT, c_stdin) != NULL) /* get line */
#define lua_saveline(L,idx) { (void)L; (void)idx; }
#define lua_freeline(L,b) { (void)L; (void)b; }
#endif // #if defined(LUA_USE_READLINE)
#else // #if defined(LUA_USE_STDIO)
#define lua_readline(L,b,p) (readline4lua(p, b, LUA_MAXINPUT)) #define lua_readline(L,b,p) (readline4lua(p, b, LUA_MAXINPUT))
#define lua_saveline(L,idx) { (void)L; (void)idx; } #define lua_saveline(L,idx) { (void)L; (void)idx; }
...@@ -326,48 +304,29 @@ ...@@ -326,48 +304,29 @@
extern int readline4lua(const char *prompt, char *buffer, int length); extern int readline4lua(const char *prompt, char *buffer, int length);
#endif // #if defined(LUA_USE_STDIO)
/* /*
@@ luai_writestring/luai_writeline define how 'print' prints its results. @@ lua_writestring/luai_writeline define how 'print' prints its results.
** They are only used in libraries and the stand-alone program. (The #if ** They are only used in libraries and the stand-alone program. (The #if
** avoids including 'stdio.h' everywhere.) ** avoids including 'stdio.h' everywhere.)
*/ */
#if !defined(LUA_USE_STDIO) #ifdef LUA_USE_ESP
#define luai_writestring(s, l) puts(s) #define lua_writestring(s,l) output_redirect((s),(l))
#define luai_writeline() puts("\n") #else
#endif // defined(LUA_USE_STDIO) #define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#endif
#define luai_writeline() lua_writestring("\n",1)
/* /*
@@ luai_writestringerror defines how to print error messages. @@ lua_writestringerror defines how to print error messages.
** (A format string with one argument is enough for Lua...) ** (A format string with one argument is enough for Lua...)
*/ */
#if !defined(LUA_USE_STDIO) #ifdef LUA_USE_ESP
#define luai_writestringerror(s,p) dbg_printf((s), (p)) #define lua_writestringerror(s,p) dbg_printf((s), (p))
#endif // defined(LUA_USE_STDIO) #else
#define lua_writestringerror(s,p) fprintf(stderr, (s), (p))
#endif
/* }================================================================== */
/*
@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
@* as a percentage.
** CHANGE it if you want the GC to run faster or slower (higher values
** mean larger pauses which mean slower collection.) You can also change
** this value dynamically.
*/
#define LUAI_GCPAUSE 110 /* 110% (wait memory to grow 10% before next gc) */
/* #define LUAI_GCPAUSE 110 /* 110% (wait memory to grow 10% before next gc) */
@@ LUAI_GCMUL defines the default speed of garbage collection relative to
@* memory allocation as a percentage.
** CHANGE it if you want to change the granularity of the garbage
** collection. (Higher values mean coarser collections. 0 represents
** infinity, where each step performs a full collection.) You can also
** change this value dynamically.
*/
#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
...@@ -898,4 +857,6 @@ union luai_Cast { double l_d; long l_l; }; ...@@ -898,4 +857,6 @@ union luai_Cast { double l_d; long l_l; };
#error "Pipes not supported NodeMCU firmware" #error "Pipes not supported NodeMCU firmware"
#endif #endif
#define LUA_DEBUG_HOOK lua_debugbreak
#endif #endif
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define lundump_c #define lundump_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <string.h> #include <string.h>
...@@ -164,16 +163,9 @@ static TString* LoadString(LoadState* S) ...@@ -164,16 +163,9 @@ static TString* LoadString(LoadState* S)
return NULL; return NULL;
else else
{ {
char* s; char* s = luaZ_openspace(S->L,S->b,size);
if (!luaZ_direct_mode(S->Z)) { LoadBlock(S,s,size);
s = luaZ_openspace(S->L,S->b,size); return luaS_newlstr(S->L,s,size-1); /* remove trailing zero */
LoadBlock(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing zero */
} else {
s = (char*)luaZ_get_crt_address(S->Z);
LoadBlock(S,NULL,size);
return luaS_newlstr(S->L,s,size-1);
}
} }
} }
...@@ -181,13 +173,8 @@ static void LoadCode(LoadState* S, Proto* f) ...@@ -181,13 +173,8 @@ static void LoadCode(LoadState* S, Proto* f)
{ {
int n=LoadInt(S); int n=LoadInt(S);
Align4(S); Align4(S);
if (!luaZ_direct_mode(S->Z)) { f->code=luaM_newvector(S->L,n,Instruction);
f->code=luaM_newvector(S->L,n,Instruction); LoadVector(S,f->code,n,sizeof(Instruction));
LoadVector(S,f->code,n,sizeof(Instruction));
} else {
f->code=(Instruction*)luaZ_get_crt_address(S->Z);
LoadVector(S,NULL,n,sizeof(Instruction));
}
f->sizecode=n; f->sizecode=n;
} }
...@@ -238,24 +225,14 @@ static void LoadDebug(LoadState* S, Proto* f) ...@@ -238,24 +225,14 @@ static void LoadDebug(LoadState* S, Proto* f)
#ifdef LUA_OPTIMIZE_DEBUG #ifdef LUA_OPTIMIZE_DEBUG
if(n) { if(n) {
if (!luaZ_direct_mode(S->Z)) { f->packedlineinfo=luaM_newvector(S->L,n,unsigned char);
f->packedlineinfo=luaM_newvector(S->L,n,unsigned char); LoadBlock(S,f->packedlineinfo,n);
LoadBlock(S,f->packedlineinfo,n);
} else {
f->packedlineinfo=(unsigned char*)luaZ_get_crt_address(S->Z);
LoadBlock(S,NULL,n);
}
} else { } else {
f->packedlineinfo=NULL; f->packedlineinfo=NULL;
} }
#else #else
if (!luaZ_direct_mode(S->Z)) { f->lineinfo=luaM_newvector(S->L,n,int);
f->lineinfo=luaM_newvector(S->L,n,int); LoadVector(S,f->lineinfo,n,sizeof(int));
LoadVector(S,f->lineinfo,n,sizeof(int));
} else {
f->lineinfo=(int*)luaZ_get_crt_address(S->Z);
LoadVector(S,NULL,n,sizeof(int));
}
f->sizelineinfo=n; f->sizelineinfo=n;
#endif #endif
n=LoadInt(S); n=LoadInt(S);
...@@ -280,7 +257,6 @@ static Proto* LoadFunction(LoadState* S, TString* p) ...@@ -280,7 +257,6 @@ static Proto* LoadFunction(LoadState* S, TString* p)
Proto* f; Proto* f;
if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
f=luaF_newproto(S->L); f=luaF_newproto(S->L);
if (luaZ_direct_mode(S->Z)) l_setbit((f)->marked, READONLYBIT);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
f->source=LoadString(S); if (f->source==NULL) f->source=p; f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->linedefined=LoadInt(S); f->linedefined=LoadInt(S);
......
...@@ -50,11 +50,4 @@ LUAI_FUNC void luaU_print (const Proto* f, int full); ...@@ -50,11 +50,4 @@ LUAI_FUNC void luaU_print (const Proto* f, int full);
/* size of header of binary files */ /* size of header of binary files */
#define LUAC_HEADERSIZE 12 #define LUAC_HEADERSIZE 12
/* error codes from cross-compiler */
/* target integer is too small to hold a value */
#define LUA_ERR_CC_INTOVERFLOW 101
/* target lua_Number is integral but a constant is non-integer */
#define LUA_ERR_CC_NOTINTEGER 102
#endif #endif
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#define lvm_c #define lvm_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <stdio.h> #include <stdio.h>
...@@ -25,7 +24,6 @@ ...@@ -25,7 +24,6 @@
#include "ltable.h" #include "ltable.h"
#include "ltm.h" #include "ltm.h"
#include "lvm.h" #include "lvm.h"
#include "lrotable.h"
/* limit for table tag-method chains (to avoid loops) */ /* limit for table tag-method chains (to avoid loops) */
...@@ -134,26 +132,17 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { ...@@ -134,26 +132,17 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
if (ttistable(t)) { /* `t' is a table? */ if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t); Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */ const TValue *res = luaH_get(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */ if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res); setobj2s(L, val, res);
return; return;
} }
/* else will try the tag method */ /* else will try the tag method */
} else if (ttisrotable(t)) { /* `t' is a table? */
void *h = rvalue(t);
const TValue *res = luaH_get_ro(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, (Table*)luaR_getmeta(h), TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
}
/* else will try the tag method */
} }
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
luaG_typeerror(L, t, "index"); luaG_typeerror(L, t, "index");
if (ttisfunction(tm) || ttislightfunction(tm)) { if (ttisfunction(tm)) {
callTMres(L, val, tm, t, key); callTMres(L, val, tm, t, key);
return; return;
} }
...@@ -193,7 +182,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { ...@@ -193,7 +182,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
luaG_typeerror(L, t, "index"); luaG_typeerror(L, t, "index");
if (ttisfunction(tm) || ttislightfunction(tm)) { if (ttisfunction(tm)) {
L->top--; L->top--;
unfixedstack(L); unfixedstack(L);
callTM(L, tm, t, key, val); callTM(L, tm, t, key, val);
...@@ -305,8 +294,6 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { ...@@ -305,8 +294,6 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
case LUA_TNIL: return 1; case LUA_TNIL: return 1;
case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TROTABLE:
return rvalue(t1) == rvalue(t2);
case LUA_TLIGHTUSERDATA: case LUA_TLIGHTUSERDATA:
case LUA_TLIGHTFUNCTION: case LUA_TLIGHTFUNCTION:
return pvalue(t1) == pvalue(t2); return pvalue(t1) == pvalue(t2);
...@@ -316,6 +303,8 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { ...@@ -316,6 +303,8 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
TM_EQ); TM_EQ);
break; /* will try TM */ break; /* will try TM */
} }
case LUA_TROTABLE:
return hvalue(t1) == hvalue(t2);
case LUA_TTABLE: { case LUA_TTABLE: {
if (hvalue(t1) == hvalue(t2)) return 1; if (hvalue(t1) == hvalue(t2)) return 1;
tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
...@@ -440,7 +429,6 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, ...@@ -440,7 +429,6 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
} }
void luaV_execute (lua_State *L, int nexeccalls) { void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl; LClosure *cl;
StkId base; StkId base;
...@@ -582,10 +570,9 @@ void luaV_execute (lua_State *L, int nexeccalls) { ...@@ -582,10 +570,9 @@ void luaV_execute (lua_State *L, int nexeccalls) {
} }
case OP_LEN: { case OP_LEN: {
const TValue *rb = RB(i); const TValue *rb = RB(i);
switch (ttype(rb)) { switch (basettype(rb)) {
case LUA_TTABLE: case LUA_TTABLE: {
case LUA_TROTABLE: { setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
setnvalue(ra, ttistable(rb) ? cast_num(luaH_getn(hvalue(rb))) : cast_num(luaH_getn_ro(rvalue(rb))));
break; break;
} }
case LUA_TSTRING: { case LUA_TSTRING: {
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#define lzio_c #define lzio_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <string.h> #include <string.h>
...@@ -49,7 +48,7 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { ...@@ -49,7 +48,7 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
z->L = L; z->L = L;
z->reader = reader; z->reader = reader;
z->data = data; z->data = data;
z->n = z->i = 0; z->n = 0;
z->p = NULL; z->p = NULL;
} }
...@@ -64,7 +63,6 @@ size_t luaZ_read (ZIO *z, void *b, size_t n) { ...@@ -64,7 +63,6 @@ size_t luaZ_read (ZIO *z, void *b, size_t n) {
if (b) if (b)
memcpy(b, z->p, m); memcpy(b, z->p, m);
z->n -= m; z->n -= m;
z->i += m;
z->p += m; z->p += m;
if (b) if (b)
b = (char *)b + m; b = (char *)b + m;
......
...@@ -43,9 +43,6 @@ typedef struct Mbuffer { ...@@ -43,9 +43,6 @@ typedef struct Mbuffer {
#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
#define luaZ_get_base_address(zio) ((const char *)((zio)->reader(NULL, (zio)->data, NULL)))
#define luaZ_direct_mode(zio) (luaZ_get_base_address(zio) != NULL)
#define luaZ_get_crt_address(zio) (luaZ_get_base_address(zio) + (zio)->i)
LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
...@@ -59,7 +56,6 @@ LUAI_FUNC int luaZ_lookahead (ZIO *z); ...@@ -59,7 +56,6 @@ LUAI_FUNC int luaZ_lookahead (ZIO *z);
struct Zio { struct Zio {
size_t n; /* bytes still unread */ size_t n; /* bytes still unread */
size_t i; /* buffer offset */
const char *p; /* current position in buffer */ const char *p; /* current position in buffer */
lua_Reader reader; lua_Reader reader;
void* data; /* additional data */ void* data; /* additional data */
......
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
SUBDIRS = host
GEN_LIBS = liblua.a
endif
STD_CFLAGS=-std=gnu11 -Wimplicit -Wall
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
#
#DEFINES += -DDEVELOPMENT_TOOLS -DDEVELOPMENT_USE_GDB -DDEVELOPMENT_BREAK_ON_STARTUP_PIN=1
#EXTRA_CCFLAGS += -ggdb -O0
#############################################################
# Recursion Magic - Don't touch this!!
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../spiffs
INCLUDES += -I ../libc
INCLUDES += -I ../modules
INCLUDES += -I ../platform
INCLUDES += -I ../uzlib
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
#
# This Makefile is called from the core Makefile hierarchy which is a hierarchical
# make which uses parent callbacks to implement inheritance. However if luac_cross
# build stands outside this, it uses the host toolchain to implement a separate
# host build of the luac.cross image.
#
.NOTPARALLEL:
CCFLAGS:= -I. -I.. -I../../include -I../../uzlib
LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm -ldl -Wl,-Map=mapfile
CCFLAGS += -Wall
TARGET = host
VERBOSE ?=
V ?= $(VERBOSE)
ifeq ("$(V)","1")
export summary := @true
else
export summary := @echo
# disable echoing of commands, directory names
# MAKEFLAGS += --silent -w
endif # $(V)==1
DEBUG ?=
ifeq ("$(DEBUG)","1")
FLAVOR = debug
CCFLAGS += -O0 -ggdb
TARGET_LDFLAGS += -O0 -ggdb
DEFINES += -DLUA_DEBUG_BUILD -DDEVELOPMENT_TOOLS -DDEVELOPMENT_USE_GDB
else
FLAVOR = release
CCFLAGS += -O2
TARGET_LDFLAGS += -O2
endif # DEBUG
LUACSRC := luac.c liolib.c loslib.c
LUASRC := lapi.c lauxlib.c lbaselib.c lcode.c lcorolib.c lctype.c \
ldblib.c ldebug.c ldo.c ldump.c lfunc.c lgc.c \
linit.c llex.c lmathlib.c lmem.c loadlib.c lnodemcu.c \
lobject.c lopcodes.c lparser.c lstate.c lstring.c lstrlib.c \
ltable.c ltablib.c ltm.c lundump.c lutf8lib.c lvm.c \
lzio.c
UZSRC := uzlib_deflate.c crc32.c
TEST ?=
ifeq ("$(TEST)","1")
DEFINES += -DLUA_ENABLE_TEST
LUACSRC += ltests.c
endif # $(TEST)==1
#
# This relies on the files being unique on the vpath
#
SRC := $(LUACSRC) $(LUASRC) $(UZSRC)
vpath %.c .:..:../../libc:../../uzlib
ODIR := .output/$(TARGET)/$(FLAVOR)/obj
OBJS := $(SRC:%.c=$(ODIR)/%.o)
DEPS := $(SRC:%.c=$(ODIR)/%.d)
CFLAGS = $(CCFLAGS) $(DEFINES) $(EXTRA_CCFLAGS) $(STD_CFLAGS) $(INCLUDES)
DFLAGS = $(CCFLAGS) $(DDEFINES) $(EXTRA_CCFLAGS) $(STD_CFLAGS) $(INCLUDES)
CC := $(WRAPCC) gcc
ECHO := echo
BUILD_TYPE := $(shell $(CC) $(EXTRA_CCFLAGS) -E -dM - <../../include/user_config.h | grep LUA_NUMBER_INTEGRAL | wc -l)
ifeq ($(BUILD_TYPE),0)
IMAGE := ../../../luac.cross
else
IMAGE := ../../../luac.cross.int
endif
.PHONY: test clean all
all: $(DEPS) $(IMAGE)
$(IMAGE) : $(OBJS)
$(summary) HOSTLD $@
$(CC) $(OBJS) -o $@ $(LDFLAGS)
test :
@echo CC: $(CC)
@echo SRC: $(SRC)
@echo OBJS: $(OBJS)
@echo DEPS: $(DEPS)
@echo IMAGE: $(IMAGE)
clean :
$(RM) -r $(ODIR)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
$(ODIR)/%.o: %.c
@mkdir -p $(ODIR);
$(summary) HOSTCC $(CURDIR)/$<
$(CC) $(if $(findstring $<,$(DSRCS)),$(DFLAGS),$(CFLAGS)) $(COPTS_$(*F)) -o $@ -c $<
$(ODIR)/%.d: %.c
@mkdir -p $(ODIR);
$(summary) DEPEND: HOSTCC $(CURDIR)/$<
@set -e; rm -f $@; \
$(CC) -M $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\.o\)[ :]*,$(ODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
This diff is collapsed.
/*
** $Id: loslib.c,v 1.65.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
#define loslib_c
#define LUA_LIB
#include "lprefix.h"
#include <errno.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** {==================================================================
** List of valid conversion specifiers for the 'strftime' function;
** options are grouped by length; group of length 2 start with '||'.
** ===================================================================
*/
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
/* options for ANSI C 89 (only 1-char options) */
#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
/* options for ISO C 99 and POSIX */
#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
"||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
/* options for Windows */
#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
"||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
#if defined(LUA_USE_WINDOWS)
#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
#elif defined(LUA_USE_C89)
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
#else /* C99 specification */
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
#endif
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for time-related stuff
** ===================================================================
*/
#if !defined(l_time_t) /* { */
/*
** type to represent time_t in Lua
*/
#define l_timet lua_Integer
#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t))
static time_t l_checktime (lua_State *L, int arg) {
lua_Integer t = luaL_checkinteger(L, arg);
luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds");
return (time_t)t;
}
#endif /* } */
#if !defined(l_gmtime) /* { */
/*
** By default, Lua uses gmtime/localtime, except when POSIX is available,
** where it uses gmtime_r/localtime_r
*/
#if defined(LUA_USE_POSIX) /* { */
#define l_gmtime(t,r) gmtime_r(t,r)
#define l_localtime(t,r) localtime_r(t,r)
#else /* }{ */
/* ISO C definitions */
#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t))
#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t))
#endif /* } */
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for 'tmpnam':
** By default, Lua uses tmpnam except when POSIX is available, where
** it uses mkstemp.
** ===================================================================
*/
#if !defined(lua_tmpnam) /* { */
#if defined(__GNUC__) /* { */
#include <unistd.h>
#define LUA_TMPNAMBUFSIZE 32
#if !defined(LUA_TMPNAMTEMPLATE)
#define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX"
#endif
#define lua_tmpnam(b,e) { \
strcpy(b, LUA_TMPNAMTEMPLATE); \
e = mkstemp(b); \
if (e != -1) close(e); \
e = (e == -1); }
#else /* }{ */
/* ISO C definitions */
#define LUA_TMPNAMBUFSIZE L_tmpnam
#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
#endif /* } */
#endif /* } */
/* }================================================================== */
static int os_execute (lua_State *L) {
const char *cmd = luaL_optstring(L, 1, NULL);
int stat = system(cmd);
if (cmd != NULL)
return luaL_execresult(L, stat);
else {
lua_pushboolean(L, stat); /* true if there is a shell */
return 1;
}
}
static int os_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
return luaL_fileresult(L, remove(filename) == 0, filename);
}
static int os_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
}
static int os_tmpname (lua_State *L) {
char buff[LUA_TMPNAMBUFSIZE];
int err;
lua_tmpnam(buff, err);
if (err)
return luaL_error(L, "unable to generate a unique filename");
lua_pushstring(L, buff);
return 1;
}
static int os_getenv (lua_State *L) {
lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
return 1;
}
static int os_clock (lua_State *L) {
lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
return 1;
}
/*
** {======================================================
** Time/Date operations
** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
** wday=%w+1, yday=%j, isdst=? }
** =======================================================
*/
static void setfield (lua_State *L, const char *key, int value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
}
static void setboolfield (lua_State *L, const char *key, int value) {
if (value < 0) /* undefined? */
return; /* does not set field */
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}
/*
** Set all fields from structure 'tm' in the table on top of the stack
*/
static void setallfields (lua_State *L, struct tm *stm) {
setfield(L, "sec", stm->tm_sec);
setfield(L, "min", stm->tm_min);
setfield(L, "hour", stm->tm_hour);
setfield(L, "day", stm->tm_mday);
setfield(L, "month", stm->tm_mon + 1);
setfield(L, "year", stm->tm_year + 1900);
setfield(L, "wday", stm->tm_wday + 1);
setfield(L, "yday", stm->tm_yday + 1);
setboolfield(L, "isdst", stm->tm_isdst);
}
static int getboolfield (lua_State *L, const char *key) {
int res;
res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
/* maximum value for date fields (to avoid arithmetic overflows with 'int') */
#if !defined(L_MAXDATEFIELD)
#define L_MAXDATEFIELD (INT_MAX / 2)
#endif
static int getfield (lua_State *L, const char *key, int d, int delta) {
int isnum;
int t = lua_getfield(L, -1, key); /* get field and its type */
lua_Integer res = lua_tointegerx(L, -1, &isnum);
if (!isnum) { /* field is not an integer? */
if (t != LUA_TNIL) /* some other value? */
return luaL_error(L, "field '%s' is not an integer", key);
else if (d < 0) /* absent field; no default? */
return luaL_error(L, "field '%s' missing in date table", key);
res = d;
}
else {
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
return luaL_error(L, "field '%s' is out-of-bound", key);
res -= delta;
}
lua_pop(L, 1);
return (int)res;
}
static const char *checkoption (lua_State *L, const char *conv,
ptrdiff_t convlen, char *buff) {
const char *option = LUA_STRFTIMEOPTIONS;
int oplen = 1; /* length of options being checked */
for (; *option != '\0' && oplen <= convlen; option += oplen) {
if (*option == '|') /* next block? */
oplen++; /* will check options with next length (+1) */
else if (memcmp(conv, option, oplen) == 0) { /* match? */
memcpy(buff, conv, oplen); /* copy valid option to buffer */
buff[oplen] = '\0';
return conv + oplen; /* return next item */
}
}
luaL_argerror(L, 1,
lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
return conv; /* to avoid warnings */
}
/* maximum size for an individual 'strftime' item */
#define SIZETIMEFMT 250
static int os_date (lua_State *L) {
size_t slen;
const char *s = luaL_optlstring(L, 1, "%c", &slen);
time_t t = luaL_opt(L, l_checktime, 2, time(NULL));
const char *se = s + slen; /* 's' end */
struct tm tmr, *stm;
if (*s == '!') { /* UTC? */
stm = l_gmtime(&t, &tmr);
s++; /* skip '!' */
}
else
stm = l_localtime(&t, &tmr);
if (stm == NULL) /* invalid date? */
return luaL_error(L,
"time result cannot be represented in this installation");
if (strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
setallfields(L, stm);
}
else {
char cc[4]; /* buffer for individual conversion specifiers */
luaL_Buffer b;
cc[0] = '%';
luaL_buffinit(L, &b);
while (s < se) {
if (*s != '%') /* not a conversion specifier? */
luaL_addchar(&b, *s++);
else {
size_t reslen;
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
s++; /* skip '%' */
s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */
reslen = strftime(buff, SIZETIMEFMT, cc, stm);
luaL_addsize(&b, reslen);
}
}
luaL_pushresult(&b);
}
return 1;
}
static int os_time (lua_State *L) {
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL); /* get current time */
else {
struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); /* make sure table is at the top */
ts.tm_sec = getfield(L, "sec", 0, 0);
ts.tm_min = getfield(L, "min", 0, 0);
ts.tm_hour = getfield(L, "hour", 12, 0);
ts.tm_mday = getfield(L, "day", -1, 0);
ts.tm_mon = getfield(L, "month", -1, 1);
ts.tm_year = getfield(L, "year", -1, 1900);
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
setallfields(L, &ts); /* update fields with normalized values */
}
if (t != (time_t)(l_timet)t || t == (time_t)(-1))
return luaL_error(L,
"time result cannot be represented in this installation");
l_pushtime(L, t);
return 1;
}
static int os_difftime (lua_State *L) {
time_t t1 = l_checktime(L, 1);
time_t t2 = l_checktime(L, 2);
lua_pushnumber(L, (lua_Number)difftime(t1, t2));
return 1;
}
/* }====================================================== */
static int os_setlocale (lua_State *L) {
static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
LC_NUMERIC, LC_TIME};
static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
"numeric", "time", NULL};
const char *l = luaL_optstring(L, 1, NULL);
int op = luaL_checkoption(L, 2, "all", catnames);
lua_pushstring(L, setlocale(cat[op], l));
return 1;
}
static int os_exit (lua_State *L) {
int status;
if (lua_isboolean(L, 1))
status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
else
status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS);
if (lua_toboolean(L, 2))
lua_close(L);
if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
return 0;
}
static const luaL_Reg syslib[] = {
{"clock", os_clock},
{"date", os_date},
{"difftime", os_difftime},
{"execute", os_execute},
{"exit", os_exit},
{"getenv", os_getenv},
{"remove", os_remove},
{"rename", os_rename},
{"setlocale", os_setlocale},
{"time", os_time},
{"tmpname", os_tmpname},
{NULL, NULL}
};
/* }====================================================== */
LUAMOD_API int luaopen_os (lua_State *L) {
luaL_newlib(L, syslib);
return 1;
}
This diff is collapsed.
/*
** $Id: ltests.h,v 2.50 2016/07/19 17:13:00 roberto Exp $
** Internal Header for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
#ifndef ltests_h
#define ltests_h
#include <stdlib.h>
#if 0 /* test Lua with compatibility code */
#undef LUA_COMPAT_MATHLIB
#undef LUA_COMPAT_IPAIRS
#undef LUA_COMPAT_BITLIB
#undef LUA_COMPAT_APIINTCASTS
#undef LUA_COMPAT_FLOATSTRING
#undef LUA_COMPAT_UNPACK
#undef LUA_COMPAT_LOADERS
#undef LUA_COMPAT_LOG10
#undef LUA_COMPAT_LOADSTRING
#undef LUA_COMPAT_MAXN
#undef LUA_COMPAT_MODULE
#endif
#define LUA_DEBUG
/* turn on assertions */
#undef NDEBUG
#include <assert.h>
#ifndef lua_assert
#define lua_assert(c) assert(c)
#endif
/* to avoid warnings, and to make sure value is really unused */
#define UNUSED(x) (x=0, (void)(x))
/* test for sizes in 'l_sprintf' (make sure whole buffer is available) */
#undef l_sprintf
#if !defined(LUA_USE_C89)
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), snprintf(s,sz,f,i))
#else
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), sprintf(s,f,i))
#endif
/* memory-allocator control variables */
typedef struct Memcontrol {
unsigned long numblocks;
unsigned long total;
unsigned long maxmem;
unsigned long memlimit;
unsigned long objcount[LUA_NUMTAGS];
} Memcontrol;
LUA_API Memcontrol l_memcontrol;
/*
** generic variable for debug tricks
*/
extern void *l_Trick;
/*
** Function to traverse and check all memory used by Lua
*/
int lua_checkmemory (lua_State *L);
/* test for lock/unlock */
struct L_EXTRA { int lock; int *plock; };
#undef LUA_EXTRASPACE
#define LUA_EXTRASPACE sizeof(struct L_EXTRA)
#define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l))
#define luai_userstateopen(l) \
(getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
#define luai_userstateclose(l) \
lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock))
#define luai_userstatethread(l,l1) \
lua_assert(getlock(l1)->plock == getlock(l)->plock)
#define luai_userstatefree(l,l1) \
lua_assert(getlock(l)->plock == getlock(l1)->plock)
#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0)
#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0)
LUA_API int luaB_opentests (lua_State *L);
LUA_API void *debug_realloc (void *ud, void *block,
size_t osize, size_t nsize);
#if defined(luac_c)
#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol)
#define luaL_openlibs(L) \
{ (luaL_openlibs)(L); \
luaL_requiref(L, "T", luaB_opentests, 1); \
lua_pop(L, 1); }
#endif
/* change some sizes to give some bugs a chance */
#undef LUAL_BUFFERSIZE
#define LUAL_BUFFERSIZE 23
#define MINSTRTABSIZE 2
#define MAXINDEXRK 1
/* make stack-overflow tests run faster */
#undef LUAI_MAXSTACK
#define LUAI_MAXSTACK 50000
#undef LUAI_USER_ALIGNMENT_T
#define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; }
#define STRCACHE_N 16
#define STRCACHE_M 5
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
-- $Id: big.lua,v 1.32 2016/11/07 13:11:28 roberto Exp $
-- See Copyright Notice in file all.lua
if _soft then
return 'a'
end
print "testing large tables"
local debug = require"debug"
-- NodeMCU: limit big size to IoT scales
local lim = 50000
local prog = { "local y = {0" }
for i = 1, lim do prog[#prog + 1] = i end
prog[#prog + 1] = "}\n"
prog[#prog + 1] = "X = y\n"
prog[#prog + 1] = ("assert(X[%d] == %d)"):format(lim - 1, lim - 2)
prog[#prog + 1] = "return 0"
prog = table.concat(prog, ";")
local env = {string = string, assert = assert}
local f = assert(load(prog, nil, nil, env))
f()
assert(env.X[lim] == lim - 1 and env.X[lim + 1] == lim)
for k in pairs(env) do env[k] = nil end
-- yields during accesses larger than K (in RK)
setmetatable(env, {
__index = function (t, n) coroutine.yield('g'); return _G[n] end,
__newindex = function (t, n, v) coroutine.yield('s'); _G[n] = v end,
})
X = nil
co = coroutine.wrap(f)
assert(co() == 's')
assert(co() == 'g')
assert(co() == 'g')
assert(co() == 0)
assert(X[lim] == lim - 1 and X[lim + 1] == lim)
-- errors in accesses larger than K (in RK)
getmetatable(env).__index = function () end
getmetatable(env).__newindex = function () end
local e, m = pcall(f)
assert(not e and m:find("global 'X'"))
-- errors in metamethods
getmetatable(env).__newindex = function () error("hi") end
local e, m = xpcall(f, debug.traceback)
assert(not e and m:find("'__newindex'"))
f, X = nil
coroutine.yield'b'
if 2^32 == 0 then -- (small integers) {
print "testing string length overflow"
local repstrings = 192 -- number of strings to be concatenated
local ssize = math.ceil(2.0^32 / repstrings) + 1 -- size of each string
assert(repstrings * ssize > 2.0^32) -- it should be larger than maximum size
local longs = string.rep("\0", ssize) -- create one long string
-- create function to concatentate 'repstrings' copies of its argument
local rep = assert(load(
"local a = ...; return " .. string.rep("a", repstrings, "..")))
local a, b = pcall(rep, longs) -- call that function
-- it should fail without creating string (result would be too large)
assert(not a and string.find(b, "overflow"))
end -- }
print'OK'
return 'a'
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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