issue #111 Lua 5.3.3 bug fixes

gccjit-ravi534
Dibyendu Majumdar 8 years ago
parent 47b24ad33a
commit 46a2282f3f

@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 2.116 2015/11/03 18:33:10 roberto Exp $
** $Id: lobject.h,v 2.116 2015/11/03 18:33:10 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@ -470,7 +470,7 @@ typedef struct RaviJITProto {
typedef struct Proto {
CommonHeader;
lu_byte numparams; /* number of fixed parameters */
lu_byte is_vararg; /* 2: declared vararg; 1: uses vararg */
lu_byte is_vararg;
lu_byte maxstacksize; /* number of registers needed by this function */
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of 'k' */

@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.148 2014/10/25 11:50:46 roberto Exp $
** $Id: lopcodes.h,v 1.148 2014/10/25 11:50:46 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -139,7 +139,9 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */
/* gets the index of the constant */
#define INDEXK(r) ((int)(r) & ~BITRK)
#if !defined(MAXINDEXRK) /* (for debugging only) */
#define MAXINDEXRK (BITRK - 1)
#endif
/* code a constant index as a RK value */
#define RKASK(x) ((x) | BITRK)

@ -1,5 +1,5 @@
/*
** $Id: ltests.h,v 2.49 2015/09/22 14:18:24 roberto Exp $
** $Id: ltests.h,v 2.49 2015/09/22 14:18:24 roberto Exp roberto $
** Internal Header for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@ -30,7 +30,6 @@
/* turn on assertions */
#undef NDEBUG
#include <assert.h>
#define lua_assert(c) assert(c)
#if !defined(RAVI_OPTION_STRING1)
@ -106,7 +105,9 @@ LUA_API Memcontrol* luaB_getmemcontrol(void);
#if defined(lua_c)
#define luaL_newstate() lua_newstate(debug_realloc, luaB_getmemcontrol())
#define luaL_openlibs(L) \
{ (luaL_openlibs)(L); luaL_requiref(L, "T", luaB_opentests, 1); }
{ (luaL_openlibs)(L); \
luaL_requiref(L, "T", luaB_opentests, 1); \
lua_pop(L, 1); }
#endif
@ -116,6 +117,7 @@ LUA_API Memcontrol* luaB_getmemcontrol(void);
#undef LUAL_BUFFERSIZE
#define LUAL_BUFFERSIZE 23
#define MINSTRTABSIZE 2
//#define MAXINDEXRK 1
/* make stack-overflow tests run faster */

@ -1,5 +1,5 @@
/*
** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $
** $Id: luaconf.h,v 1.256 2016/07/18 17:55:59 roberto Exp roberto $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@ -158,6 +158,18 @@
** ===================================================================
*/
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
*/
#define LUA_PATH_SEP ";"
#define LUA_PATH_MARK "?"
#define LUA_EXEC_DIR "!"
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
** Lua libraries.
@ -728,11 +740,11 @@
/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
** CHANGE it if it uses too much C-stack space. (For long double,
** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
** 'string.format("%.99f", -1e4932)' needs 5034 bytes, so a
** smaller buffer would force a memory allocation for each call to
** 'string.format'.)
*/
#if defined(LUA_FLOAT_LONGDOUBLE)
#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
#define LUAL_BUFFERSIZE 8192
#else
#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))

@ -43,7 +43,7 @@ function check (f, ...)
local arg = {...}
local c = T.listcode(f)
for i=1, #arg do
-- print(arg[i], c[i])
--print(arg[i], c[i])
assert(string.find(c[i], '- '..arg[i]..' *%d'))
end
assert(c[#arg+2] == nil)

@ -1,5 +1,5 @@
/*
** $Id: lbaselib.c,v 1.313 2016/04/11 19:18:40 roberto Exp $
** $Id: lbaselib.c,v 1.313 2016/04/11 19:18:40 roberto Exp roberto $
** Basic library
** See Copyright Notice in lua.h
*/
@ -213,8 +213,8 @@ static int luaB_ravitype(lua_State *L) {
static int pairsmeta (lua_State *L, const char *method, int iszero,
lua_CFunction iter) {
luaL_checkany(L, 1);
if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */
luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */
lua_pushcfunction(L, iter); /* will return generator, */
lua_pushvalue(L, 1); /* state, */
if (iszero) lua_pushinteger(L, 0); /* and initial value */
@ -256,9 +256,8 @@ static int ipairsaux (lua_State *L) {
/*
** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
** traverse a table, depending on whether the table has metamethods
** that can affect the traversal.
** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
** (The given "table" may not be a table.)
*/
static int luaB_ipairs (lua_State *L) {
#if defined(LUA_COMPAT_IPAIRS)

@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 2.109 2016/05/13 19:09:21 roberto Exp $
** $Id: lcode.c,v 2.110 2016/06/20 19:12:46 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@ -13,6 +13,7 @@
#include "lprefix.h"
#include <math.h>
#include <stdlib.h>
@ -44,7 +45,7 @@
** If expression is a numeric constant, fills 'v' with its value
** and returns 1. Otherwise, returns 0.
*/
static int tonumeral(expdesc *e, TValue *v) {
static int tonumeral(const expdesc *e, TValue *v) {
if (hasjumps(e))
return 0; /* not a numeral */
switch (e->k) {
@ -397,7 +398,6 @@ void luaK_reserveregs (FuncState *fs, int n) {
static void freereg (FuncState *fs, int reg) {
if (!ISK(reg) && reg >= fs->nactvar) {
fs->freereg--;
/* if (reg != fs->freereg) luaX_syntaxerror(fs->ls, "unexpected error"); DEBUG Lua 5.3.3 merge issue math.lua 551 */
lua_assert(reg == fs->freereg);
}
}
@ -537,6 +537,7 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
DEBUG_CODEGEN(raviY_printf(fs, "[%d]* %o ; set A to %d\n", e->u.info, *pc, fs->freereg));
luaK_reserveregs(fs, 1);
}
else lua_assert(nresults == LUA_MULTRET);
}
@ -979,6 +980,9 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
}
/*
** Emit SELF instruction (convert expression 'e' into 'e:key(e,').
*/
void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
int ereg;
/* Ravi extension:
@ -1197,6 +1201,7 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
return 1;
}
/*
** Emit code for unary expressions that "produce values"
** (everything but 'not').
@ -1219,11 +1224,15 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
** (everything but logical operators 'and'/'or' and comparison
** operators).
** Expression to produce final result will be encoded in 'e1'.
** Because 'luaK_exp2RK' can free registers, its calls must be
** in "stack order" (that is, first on 'e2', which may have more
** recent registers to be released).
*/
static void codebinexpval (FuncState *fs, OpCode op,
expdesc *e1, expdesc *e2, int line) {
int rk2 = luaK_exp2RK(fs, e2);
int rk1 = luaK_exp2RK(fs, e1); /* both operands are "RK" */
/* Note that the order below is important - see Lua 5.3.3 bug list*/
int rk2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
int rk1 = luaK_exp2RK(fs, e1);
freeexps(fs, e1, e2);
if (op == OP_ADD && e1->ravi_type == RAVI_TNUMFLT && e2->ravi_type == RAVI_TNUMFLT) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_ADDFF, 0, rk1, rk2);
@ -1456,6 +1465,9 @@ static void code_type_assertion(FuncState *fs, UnOpr op, expdesc *e) {
luaX_syntaxerror(fs->ls, "invalid type assertion");
}
/*
** Apply prefix operation 'op' to expression 'e'.
*/
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
expdesc ef = {.ravi_type = RAVI_TANY,
.pc = -1,
@ -1566,7 +1578,7 @@ void luaK_posfix (FuncState *fs, BinOpr op,
codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line);
break;
}
case OPR_EQ: case OPR_LT: case OPR_LE:
case OPR_EQ: case OPR_LT: case OPR_LE:
case OPR_NE: case OPR_GT: case OPR_GE: {
codecomp(fs, op, e1, e2);
break;

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 2.151 2015/12/16 16:40:07 roberto Exp $
** $Id: ldo.c,v 2.155 2016/09/08 16:36:26 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -211,9 +211,9 @@ static int stackinuse (lua_State *L) {
CallInfo *ci;
StkId lim = L->top;
for (ci = L->ci; ci != NULL; ci = ci->previous) {
lua_assert(ci->top <= L->stack_last);
if (lim < ci->top) lim = ci->top;
}
lua_assert(lim <= L->stack_last);
return cast_int(lim - L->stack) + 1; /* part of stack in use */
}
@ -221,16 +221,19 @@ static int stackinuse (lua_State *L) {
void luaD_shrinkstack (lua_State *L) {
int inuse = stackinuse(L);
int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
if (L->stacksize > LUAI_MAXSTACK) /* was handling stack overflow? */
if (goodsize > LUAI_MAXSTACK)
goodsize = LUAI_MAXSTACK; /* respect stack limit */
if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */
luaE_freeCI(L); /* free all CIs (list grew because of an error) */
else
luaE_shrinkCI(L); /* shrink list */
if (inuse <= LUAI_MAXSTACK && /* not handling stack overflow? */
goodsize < L->stacksize) /* trying to shrink? */
luaD_reallocstack(L, goodsize); /* shrink it */
else
condmovestack(L,,); /* don't change stack (change only for debugging) */
/* if thread is currently not handling a stack overflow and its
good size is smaller than current size, shrink its stack */
if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
goodsize < L->stacksize)
luaD_reallocstack(L, goodsize);
else /* don't change stack */
condmovestack(L,{},{}); /* (change only for debugging) */
}
@ -376,13 +379,13 @@ int luaD_precall (lua_State *L, StkId func, int nresults, int op_call) {
int n = cast_int(L->top - func) - 1; /* number of real arguments */
int fsize = p->maxstacksize; /* frame size */
checkstackp(L, fsize, func);
if (p->is_vararg != 1) { /* do not use vararg? */
if (p->is_vararg)
base = adjust_varargs(L, p, n);
else { /* non vararg function */
for (; n < p->numparams; n++)
setnilvalue(L->top++); /* complete missing arguments */
base = func + 1;
}
else
base = adjust_varargs(L, p, n);
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
@ -566,19 +569,17 @@ static void finishCcall (lua_State *L, int status) {
/* error status can only happen in a protected call */
lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */
L->errfunc = ci->u.c.old_errfunc;
ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */
L->errfunc = ci->u.c.old_errfunc; /* with the same error function */
}
/* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
handled */
adjustresults(L, ci->nresults);
/* call continuation function */
lua_unlock(L);
n = (*ci->u.c.k)(L, status, ci->u.c.ctx);
n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
lua_lock(L);
api_checknelems(L, n);
/* finish 'luaD_precall' */
luaD_poscall(L, ci, L->top - n, n);
luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */
}
@ -641,15 +642,16 @@ static int recover (lua_State *L, int status) {
/*
** signal an error in the call to 'resume', not in the execution of the
** coroutine itself. (Such errors should not be handled by any coroutine
** error handler and should not kill the coroutine.)
** Signal an error in the call to 'lua_resume', not in the execution
** of the coroutine itself. (Such errors should not be handled by any
** coroutine error handler and should not kill the coroutine.)
*/
static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
L->top = firstArg; /* remove args from the stack */
static int resume_error (lua_State *L, const char *msg, int narg) {
L->top -= narg; /* remove args from the stack */
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
api_incr_top(L);
luaD_throw(L, -1); /* jump back to 'lua_resume' */
lua_unlock(L);
return LUA_ERRRUN;
}
@ -661,22 +663,15 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
** coroutine.
*/
static void resume (lua_State *L, void *ud) {
int nCcalls = L->nCcalls;
int n = *(cast(int*, ud)); /* number of arguments */
StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci;
if (nCcalls >= LUAI_MAXCCALLS)
resume_error(L, "C stack overflow", firstArg);
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (ci != &L->base_ci) /* not in base level? */
resume_error(L, "cannot resume non-suspended coroutine", firstArg);
/* coroutine is in base level; start running it */
if (L->status == LUA_OK) { /* starting a coroutine? */
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET, 0)) /* Lua function? */
luaV_execute(L); /* call it */
}
else if (L->status != LUA_YIELD)
resume_error(L, "cannot resume dead coroutine", firstArg);
else { /* resuming from previous yield */
lua_assert(L->status == LUA_YIELD);
L->status = LUA_OK; /* mark that it is running (again) */
ci->func = restorestack(L, ci->extra);
if (isLua(ci)) /* yielded inside a hook? */
@ -693,7 +688,6 @@ static void resume (lua_State *L, void *ud) {
}
unroll(L, NULL); /* run continuation */
}
lua_assert(nCcalls == L->nCcalls);
}
@ -701,8 +695,16 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
int status;
unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */
lua_lock(L);
luai_userstateresume(L, nargs);
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (L->ci != &L->base_ci) /* not in base level? */
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
}
else if (L->status != LUA_YIELD)
return resume_error(L, "cannot resume dead coroutine", nargs);
L->nCcalls = (from) ? from->nCcalls + 1 : 1;
if (L->nCcalls >= LUAI_MAXCCALLS)
return resume_error(L, "C stack overflow", nargs);
luai_userstateresume(L, nargs);
L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
status = luaD_rawrunprotected(L, resume, &nargs);

@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 2.149 2016/05/02 14:03:19 roberto Exp $
** $Id: liolib.c,v 2.149 2016/05/02 14:03:19 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@ -37,10 +37,11 @@
#endif
/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
#define l_checkmode(mode) \
(*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \
(*mode != '+' || (++mode, 1)) && /* skip if char is '+' */ \
(strspn(mode, L_MODEEXT) == strlen(mode)))
static int l_checkmode (const char *mode) {
return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
(*mode != '+' || (++mode, 1)) && /* skip if char is '+' */
(strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */
}
#endif

@ -1,5 +1,5 @@
/*
** $Id: loadlib.c,v 1.127 2015/11/23 11:30:45 roberto Exp $
** $Id: loadlib.c,v 1.127 2015/11/23 11:30:45 roberto Exp roberto $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@ -25,40 +25,9 @@
/*
** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
** variables that Lua check to set its paths.
*/
#if !defined(LUA_PATH_VAR)
#define LUA_PATH_VAR "LUA_PATH"
#endif
#if !defined(LUA_CPATH_VAR)
#define LUA_CPATH_VAR "LUA_CPATH"
#endif
#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
#define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX
#define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
** LUA_IGMARK is a mark to ignore all before it when building the
** luaopen_ function name.
*/
#if !defined (LUA_PATH_SEP)
#define LUA_PATH_SEP ";"
#endif
#if !defined (LUA_PATH_MARK)
#define LUA_PATH_MARK "?"
#endif
#if !defined (LUA_EXEC_DIR)
#define LUA_EXEC_DIR "!"
#endif
#if !defined (LUA_IGMARK)
#define LUA_IGMARK "-"
#endif
@ -94,8 +63,6 @@ static const int CLIBS = 0;
#define LIB_FAIL "open"
#define setprogdir(L) ((void)0)
/*
** system-dependent functions
@ -179,7 +146,6 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#include <windows.h>
#undef setprogdir
/*
** optional flags for LoadLibraryEx
@ -189,21 +155,6 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#endif
static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize);
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else {
*lb = '\0';
luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
static void pusherror (lua_State *L) {
int error = GetLastError();
char buffer[128];
@ -666,41 +617,6 @@ static int ll_seeall (lua_State *L) {
/* auxiliary mark (for internal use) */
#define AUXMARK "\1"
/*
** return registry.LUA_NOENV as a boolean
*/
static int noenv (lua_State *L) {
int b;
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
b = lua_toboolean(L, -1);
lua_pop(L, 1); /* remove value */
return b;
}
static void setpath (lua_State *L, const char *fieldname, const char *envname1,
const char *envname2, const char *def) {
const char *path = getenv(envname1);
if (path == NULL) /* no environment variable? */
path = getenv(envname2); /* try alternative name */
if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2);
}
setprogdir(L);
lua_setfield(L, -2, fieldname);
}
static const luaL_Reg pk_funcs[] = {
{"loadlib", ll_loadlib},
{"searchpath", ll_searchpath},
@ -764,10 +680,10 @@ LUAMOD_API int luaopen_package (lua_State *L) {
createclibstable(L);
luaL_newlib(L, pk_funcs); /* create 'package' table */
createsearcherstable(L);
/* set field 'path' */
setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
/* set field 'cpath' */
setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
lua_pushstring(L, LUA_PATH_DEFAULT);
lua_setfield(L, -2, "path"); /* package.path = default path */
lua_pushstring(L, LUA_CPATH_DEFAULT);
lua_setfield(L, -2, "cpath"); /* package.cpath = default cpath */
/* store config information */
lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
LUA_EXEC_DIR "\n" LUA_IGMARK "\n");

@ -1,5 +1,5 @@
/*
** $Id: lobject.c,v 2.111 2016/05/20 14:07:48 roberto Exp $
** $Id: lobject.c,v 2.111 2016/05/20 14:07:48 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@ -280,7 +280,7 @@ static const char *l_str2d (const char *s, lua_Number *result) {
endptr = l_str2dloc(s, result, mode); /* try to convert */
if (endptr == NULL) { /* failed? may be a different locale */
char buff[L_MAXLENNUM + 1];
char *pdot = strchr(s, '.');
const char *pdot = strchr(s, '.');
if (strlen(s) > L_MAXLENNUM || pdot == NULL)
return NULL; /* string too long or no dot; fail */
strcpy(buff, s); /* copy string to buffer */

@ -30,16 +30,16 @@
*/
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
/* options for ANSI C 89 */
/* 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"
"||" "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"
"||" "#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
@ -257,12 +257,13 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
}
static const char *checkoption (lua_State *L, const char *conv, char *buff) {
const char *option;
int oplen = 1;
for (option = LUA_STRFTIMEOPTIONS; *option != '\0'; option += oplen) {
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++; /* next length */
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';
@ -280,8 +281,10 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) {
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
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);
@ -300,13 +303,14 @@ static int os_date (lua_State *L) {
luaL_Buffer b;
cc[0] = '%';
luaL_buffinit(L, &b);
while (*s) {
while (s < se) {
if (*s != '%') /* not a conversion specifier? */
luaL_addchar(&b, *s++);
else {
size_t reslen;
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
s = checkoption(L, s + 1, cc + 1); /* copy specifier to 'cc' */
s++; /* skip '%' */
s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */
reslen = strftime(buff, SIZETIMEFMT, cc, stm);
luaL_addsize(&b, reslen);
}

@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 2.153 2016/05/13 19:10:16 roberto Exp $
** $Id: lparser.c,v 2.154 2016/06/22 15:48:25 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
@ -735,6 +735,8 @@ static void localvar_adjust_assign(LexState *ls, int nvars, int nexps, expdesc *
ravi_setzero(fs, reg, extra);
}
}
if (nexps > nvars)
ls->fs->freereg -= nexps - nvars; /* remove extra values */
}
static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
@ -756,6 +758,8 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
luaK_nil(fs, reg, extra);
}
}
if (nexps > nvars)
ls->fs->freereg -= nexps - nvars; /* remove extra values */
}
@ -1246,7 +1250,7 @@ static void parlist (LexState *ls) {
}
case TK_DOTS: { /* param -> '...' */
luaX_next(ls);
f->is_vararg = 2; /* declared vararg */
f->is_vararg = 1; /* declared vararg */
break;
}
default: luaX_syntaxerror(ls, "<name> or '...' expected");
@ -1565,7 +1569,6 @@ static void simpleexp (LexState *ls, expdesc *v) {
FuncState *fs = ls->fs;
check_condition(ls, fs->f->is_vararg,
"cannot use '...' outside a vararg function");
fs->f->is_vararg = 1; /* function actually uses vararg */
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0), RAVI_TANY);
break;
}
@ -1796,8 +1799,6 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
DEBUG_EXPR(raviY_printf(ls->fs, "assignment -> = explist %e\n", &e));
if (nexps != nvars) {
adjust_assign(ls, nvars, nexps, &e);
if (nexps > nvars)
ls->fs->freereg -= nexps - nvars; /* remove extra values */
}
else {
luaK_setoneret(ls->fs, &e); /* close last expression */
@ -2343,7 +2344,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {
BlockCnt bl;
expdesc v = {.ravi_type = RAVI_TANY, .pc = -1};
open_func(ls, fs, &bl);
fs->f->is_vararg = 2; /* main function is always declared vararg */
fs->f->is_vararg = 1; /* main function is always declared vararg */
init_exp(&v, VLOCAL, 0, RAVI_TANY); /* create and... - RAVI TODO var arg is unknown type */
newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
luaX_next(ls); /* read first token */

@ -1,5 +1,5 @@
/*
** $Id: lstrlib.c,v 1.251 2016/05/20 14:13:21 roberto Exp $
** $Id: lstrlib.c,v 1.251 2016/05/20 14:13:21 roberto Exp roberto $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@ -933,7 +933,7 @@ static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
static void checkdp (char *buff, int nb) {
if (memchr(buff, '.', nb) == NULL) { /* no dot? */
char point = lua_getlocaledecpoint(); /* try locale point */
char *ppoint = memchr(buff, point, nb);
char *ppoint = (char *)memchr(buff, point, nb);
if (ppoint) *ppoint = '.'; /* change it to a dot */
}
}

@ -1,5 +1,5 @@
/*
** $Id: ltests.c,v 2.209 2015/10/12 16:38:19 roberto Exp $
** $Id: ltests.c,v 2.208 2015/09/08 16:55:43 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/

@ -1,5 +1,5 @@
/*
** $Id: lua.c,v 1.226 2015/08/14 19:11:20 roberto Exp $
** $Id: lua.c,v 1.226 2015/08/14 19:11:20 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@ -19,6 +19,7 @@
#include "lauxlib.h"
#include "lualib.h"
#if !defined(LUA_PROMPT)
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
@ -63,6 +64,8 @@
#elif defined(LUA_USE_WINDOWS) /* }{ */
#include <io.h>
#include <windows.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else /* }{ */
@ -538,6 +541,91 @@ static int runargs (lua_State *L, char **argv, int n) {
}
/*
** {==================================================================
** Set Paths
** ===================================================================
*/
/*
** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
** variables that Lua check to set its paths.
*/
#if !defined(LUA_PATH_VAR)
#define LUA_PATH_VAR "LUA_PATH"
#endif
#if !defined(LUA_CPATH_VAR)
#define LUA_CPATH_VAR "LUA_CPATH"
#endif
#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
#define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX
#define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX
#define AUXMARK "\1" /* auxiliary mark */
#if defined(LUA_USE_WINDOWS)
/*
** Replace in the path (on the top of the stack) any occurrence
** of LUA_EXEC_DIR with the executable's path.
*/
static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else {
*lb = '\0'; /* cut name on the last '\\' to get the path */
luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
#else
#define setprogdir(L) ((void)0)
#endif
/*
** Change a path according to corresponding environment variables
*/
static void chgpath (lua_State *L, const char *fieldname,
const char *envname1,
const char *envname2,
int noenv) {
const char *path = getenv(envname1);
lua_getglobal(L, LUA_LOADLIBNAME); /* get 'package' table */
lua_getfield(L, -1, fieldname); /* get original path */
if (path == NULL) /* no environment variable? */
path = getenv(envname2); /* try alternative name */
if (path == NULL || noenv) /* no environment variable? */
lua_pushvalue(L, -1); /* use original value */
else {
const char *def = lua_tostring(L, -1); /* default path */
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2); /* remove result from 1st 'gsub' */
}
setprogdir(L);
lua_setfield(L, -3, fieldname); /* set path value */
lua_pop(L, 2); /* pop 'package' table and original path */
}
/* }================================================================== */
static int handle_luainit (lua_State *L) {
const char *name = "=" LUA_INITVARVERSION;
const char *init = getenv(name + 1);
@ -570,11 +658,10 @@ static int pmain (lua_State *L) {
}
if (args & has_v) /* option '-v'? */
print_version(L);
if (args & has_E) { /* option '-E'? */
lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
}
luaL_openlibs(L); /* open standard libraries */
/* change paths according to env variables */
chgpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, (args & has_E));
chgpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, (args & has_E));
createargtable(L, argv, argc, script); /* create table 'arg' */
if (!(args & has_E)) { /* no option '-E'? */
if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */

Loading…
Cancel
Save