Merge branch 'lethosor/lua-upgrade-5.3.6' into develop

develop
lethosor 2021-10-08 19:17:32 -04:00
commit b61c88663e
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
61 changed files with 602 additions and 430 deletions

@ -1,5 +1,5 @@
This is Lua 5.3.3, released on 30 May 2016. This is Lua 5.3.6, released on 14 Sep 2020.
For installation instructions, license details, and For installation instructions, license details, and
further information about Lua, see further information about Lua, see

@ -1,5 +1,5 @@
/* /*
** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $ ** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions from Lua API ** Auxiliary functions from Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 roberto Exp $ ** $Id: lauxlib.h,v 1.131.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions for building Lua libraries ** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -16,10 +16,18 @@
/* extra error code for 'luaL_load' */ /* extra error code for 'luaL_loadfilex' */
#define LUA_ERRFILE (LUA_ERRERR+1) #define LUA_ERRFILE (LUA_ERRERR+1)
/* key, in the registry, for table of loaded modules */
#define LUA_LOADED_TABLE "_LOADED"
/* key, in the registry, for table of preloaded loaders */
#define LUA_PRELOAD_TABLE "_PRELOAD"
typedef struct luaL_Reg { typedef struct luaL_Reg {
const char *name; const char *name;
lua_CFunction func; lua_CFunction func;

@ -1,5 +1,5 @@
/* /*
** $Id: lcode.h,v 1.64 2016/01/05 16:22:37 roberto Exp $ ** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $ ** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
** 'ctype' functions for Lua ** 'ctype' functions for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $ ** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions from Debug Interface module ** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp $ ** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $ ** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures ** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lgc.h,v 2.91 2015/12/21 13:02:14 roberto Exp $ ** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: llex.h,v 1.79 2016/05/02 14:02:12 roberto Exp $ ** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $
** Lexical Analyzer ** Lexical Analyzer
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: llimits.h,v 1.141 2015/11/19 19:16:22 roberto Exp $ ** $Id: llimits.h,v 1.141.1.1 2017/04/19 17:20:42 roberto Exp $
** Limits, basic types, and some other 'installation-dependent' definitions ** Limits, basic types, and some other 'installation-dependent' definitions
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp $ ** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $
** Interface to Memory Manager ** Interface to Memory Manager
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lobject.h,v 2.116 2015/11/03 18:33:10 roberto Exp $ ** $Id: lobject.h,v 2.117.1.1 2017/04/19 17:39:34 roberto Exp $
** Type definitions for Lua objects ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -407,7 +407,7 @@ typedef struct LocVar {
typedef struct Proto { typedef struct Proto {
CommonHeader; CommonHeader;
lu_byte numparams; /* number of fixed parameters */ 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 */ lu_byte maxstacksize; /* number of registers needed by this function */
int sizeupvalues; /* size of 'upvalues' */ int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of 'k' */ 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.149.1.1 2017/04/19 17:20:42 roberto Exp $
** Opcodes for Lua virtual machine ** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h ** 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 */ /* gets the index of the constant */
#define INDEXK(r) ((int)(r) & ~BITRK) #define INDEXK(r) ((int)(r) & ~BITRK)
#if !defined(MAXINDEXRK) /* (for debugging only) */
#define MAXINDEXRK (BITRK - 1) #define MAXINDEXRK (BITRK - 1)
#endif
/* code a constant index as a RK value */ /* code a constant index as a RK value */
#define RKASK(x) ((x) | BITRK) #define RKASK(x) ((x) | BITRK)

@ -1,5 +1,5 @@
/* /*
** $Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp $ ** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $
** Lua Parser ** Lua Parser
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ ** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $
** Definitions for Lua code that must come before any other header file ** Definitions for Lua code that must come before any other header file
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lstate.h,v 2.130 2015/12/16 16:39:38 roberto Exp $ ** $Id: lstate.h,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -26,6 +26,24 @@
** 'tobefnz': all objects ready to be finalized; ** 'tobefnz': all objects ready to be finalized;
** 'fixedgc': all objects that are not to be collected (currently ** 'fixedgc': all objects that are not to be collected (currently
** only small strings, such as reserved words). ** only small strings, such as reserved words).
**
** Moreover, there is another set of lists that control gray objects.
** These lists are linked by fields 'gclist'. (All objects that
** can become gray have such a field. The field is not the same
** in all objects, but it always has this name.) Any gray object
** must belong to one of these lists, and all objects in these lists
** must be gray:
**
** 'gray': regular gray objects, still waiting to be visited.
** 'grayagain': objects that must be revisited at the atomic phase.
** That includes
** - black objects got in a write barrier;
** - all kinds of weak tables during propagation phase;
** - all threads.
** 'weak': tables with weak values to be cleared;
** 'ephemeron': ephemeron tables with white->white entries;
** 'allweak': tables with weak keys and/or weak values to be cleared.
** The last three lists are used only during the atomic phase.
*/ */
@ -88,7 +106,7 @@ typedef struct CallInfo {
} u; } u;
ptrdiff_t extra; ptrdiff_t extra;
short nresults; /* expected number of results from this function */ short nresults; /* expected number of results from this function */
lu_byte callstatus; unsigned short callstatus;
} CallInfo; } CallInfo;
@ -104,6 +122,7 @@ typedef struct CallInfo {
#define CIST_TAIL (1<<5) /* call was tail called */ #define CIST_TAIL (1<<5) /* call was tail called */
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
#define CIST_LEQ (1<<7) /* using __lt for __le */ #define CIST_LEQ (1<<7) /* using __lt for __le */
#define CIST_FIN (1<<8) /* call is running a finalizer */
#define isLua(ci) ((ci)->callstatus & CIST_LUA) #define isLua(ci) ((ci)->callstatus & CIST_LUA)

@ -1,5 +1,5 @@
/* /*
** $Id: lstring.h,v 1.61 2015/11/03 15:36:01 roberto Exp $ ** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $
** String table (keep all strings handled by Lua) ** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: ltable.h,v 2.21 2015/11/03 15:47:30 roberto Exp $ ** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $
** Lua tables (hash) ** Lua tables (hash)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -27,6 +27,14 @@
#define invalidateTMcache(t) ((t)->flags = 0) #define invalidateTMcache(t) ((t)->flags = 0)
/* true when 't' is using 'dummynode' as its hash part */
#define isdummy(t) ((t)->lastfree == NULL)
/* allocated size for hash nodes */
#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
/* returns the key, given the value of a table entry */ /* returns the key, given the value of a table entry */
#define keyfromval(v) \ #define keyfromval(v) \
(gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
@ -46,12 +54,12 @@ LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t); LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t); LUAI_FUNC lua_Unsigned luaH_getn (Table *t);
#if defined(LUA_DEBUG) #if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
LUAI_FUNC int luaH_isdummy (Node *n); LUAI_FUNC int luaH_isdummy (const Table *t);
#endif #endif

@ -1,5 +1,5 @@
/* /*
** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp $ ** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $
** Tag methods ** Tag methods
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,4 @@
/* /*
** $Id: lua.h,v 1.331 2016/05/30 15:53:28 roberto Exp $
** Lua - A Scripting Language ** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file ** See Copyright Notice at the end of this file
@ -19,11 +18,11 @@
#define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "3" #define LUA_VERSION_MINOR "3"
#define LUA_VERSION_NUM 503 #define LUA_VERSION_NUM 503
#define LUA_VERSION_RELEASE "3" #define LUA_VERSION_RELEASE "6"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2016 Lua.org, PUC-Rio" #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2020 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
@ -460,7 +459,7 @@ struct lua_Debug {
/****************************************************************************** /******************************************************************************
* Copyright (C) 1994-2016 Lua.org, PUC-Rio. * Copyright (C) 1994-2020 Lua.org, PUC-Rio.
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the

@ -1,5 +1,5 @@
/* /*
** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $ ** $Id: luaconf.h,v 1.259.1.1 2017/04/19 17:29:57 roberto Exp $
** Configuration file for Lua ** Configuration file for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -11,6 +11,7 @@
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
// !! BEGIN DFHack modifications: compatibility
#define LUA_COMPAT_APIINTCASTS #define LUA_COMPAT_APIINTCASTS
#define LUA_COMPAT_IPAIRS #define LUA_COMPAT_IPAIRS
@ -22,6 +23,7 @@
#if !defined(LLONG_MIN) && defined(__LONG_LONG_MAX__) #if !defined(LLONG_MIN) && defined(__LONG_LONG_MAX__)
#define LLONG_MIN (-__LONG_LONG_MAX__ - 1LL) #define LLONG_MIN (-__LONG_LONG_MAX__ - 1LL)
#endif #endif
// !! END DFHack modifications: compatibility
/* /*
** =================================================================== ** ===================================================================
@ -169,6 +171,19 @@
** =================================================================== ** ===================================================================
*/ */
/*
** 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 "!"
// !! BEGIN DFHack modifications: library paths
/* /*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
** Lua libraries. ** Lua libraries.
@ -202,6 +217,7 @@
#define LUA_PATH_VAR "DFHACK_LUA_PATH" #define LUA_PATH_VAR "DFHACK_LUA_PATH"
#define LUA_CPATH_VAR "DFHACK_LUA_CPATH" #define LUA_CPATH_VAR "DFHACK_LUA_CPATH"
// !! END DFHack modifications: library paths
/* /*
@@ LUA_DIRSEP is the directory separator (for submodules). @@ LUA_DIRSEP is the directory separator (for submodules).
@ -234,6 +250,7 @@
*/ */
#if defined(LUA_BUILD_AS_DLL) /* { */ #if defined(LUA_BUILD_AS_DLL) /* { */
// !! BEGIN DFHack modifications: symbol exporting
#if defined(_MSC_VER) #if defined(_MSC_VER)
#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ #if defined(LUA_CORE) || defined(LUA_LIB) /* { */
#define LUA_API __declspec(dllexport) #define LUA_API __declspec(dllexport)
@ -243,6 +260,7 @@
#else #else
#define LUA_API __attribute__ ((visibility("default"))) #define LUA_API __attribute__ ((visibility("default")))
#endif #endif
// !! END DFHack modifications: symbol exporting
#else /* }{ */ #else /* }{ */
@ -411,7 +429,7 @@
/* /*
@@ LUA_NUMBER is the floating-point type used by Lua. @@ LUA_NUMBER is the floating-point type used by Lua.
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' @@ LUAI_UACNUMBER is the result of a 'default argument promotion'
@@ over a floating number. @@ over a floating number.
@@ l_mathlim(x) corrects limit name 'x' to the proper float type @@ l_mathlim(x) corrects limit name 'x' to the proper float type
** by prefixing it with one of FLT/DBL/LDBL. ** by prefixing it with one of FLT/DBL/LDBL.
@ -428,7 +446,8 @@
#define l_floor(x) (l_mathop(floor)(x)) #define l_floor(x) (l_mathop(floor)(x))
#define lua_number2str(s,sz,n) l_sprintf((s), sz, LUA_NUMBER_FMT, (n)) #define lua_number2str(s,sz,n) \
l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n))
/* /*
@@ lua_numbertointeger converts a float number to an integer, or @@ lua_numbertointeger converts a float number to an integer, or
@ -505,7 +524,7 @@
** **
@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. @@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
** **
@@ LUAI_UACINT is the result of an 'usual argument conversion' @@ LUAI_UACINT is the result of a 'default argument promotion'
@@ over a lUA_INTEGER. @@ over a lUA_INTEGER.
@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. @@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
@@ LUA_INTEGER_FMT is the format for writing integers. @@ LUA_INTEGER_FMT is the format for writing integers.
@ -518,10 +537,12 @@
/* The following definitions are good for most cases here */ /* The following definitions are good for most cases here */
#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" #define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
#define lua_integer2str(s,sz,n) l_sprintf((s), sz, LUA_INTEGER_FMT, (n))
#define LUAI_UACINT LUA_INTEGER #define LUAI_UACINT LUA_INTEGER
#define lua_integer2str(s,sz,n) \
l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n))
/* /*
** use LUAI_UACINT here to avoid problems with promotions (which ** use LUAI_UACINT here to avoid problems with promotions (which
** can turn a comparison between unsigneds into a signed comparison) ** can turn a comparison between unsigneds into a signed comparison)
@ -612,6 +633,13 @@
#endif #endif
/*
@@ lua_pointer2str converts a pointer to a readable string in a
** non-specified way.
*/
#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p)
/* /*
@@ lua_number2strx converts a float to an hexadecimal numeric string. @@ lua_number2strx converts a float to an hexadecimal numeric string.
** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. ** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
@ -619,7 +647,8 @@
** provide its own implementation. ** provide its own implementation.
*/ */
#if !defined(LUA_USE_C89) #if !defined(LUA_USE_C89)
#define lua_number2strx(L,b,sz,f,n) ((void)L, l_sprintf(b,sz,f,n)) #define lua_number2strx(L,b,sz,f,n) \
((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n)))
#endif #endif
@ -735,11 +764,11 @@
/* /*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. @@ 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, ** 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 ** smaller buffer would force a memory allocation for each call to
** 'string.format'.) ** 'string.format'.)
*/ */
#if defined(LUA_FLOAT_LONGDOUBLE) #if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
#define LUAL_BUFFERSIZE 8192 #define LUAL_BUFFERSIZE 8192
#else #else
#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer))) #define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))

@ -1,5 +1,5 @@
/* /*
** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $ ** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
** Lua standard libraries ** Lua standard libraries
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -11,6 +11,9 @@
#include "lua.h" #include "lua.h"
/* version suffix for environment variable names */
#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
LUAMOD_API int (luaopen_base) (lua_State *L); LUAMOD_API int (luaopen_base) (lua_State *L);

@ -1,5 +1,5 @@
/* /*
** $Id: lundump.h,v 1.45 2015/09/08 15:41:05 roberto Exp $ ** $Id: lundump.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
** load precompiled Lua chunks ** load precompiled Lua chunks
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lvm.h,v 2.40 2016/01/05 16:07:21 roberto Exp $ ** $Id: lvm.h,v 2.41.1.1 2017/04/19 17:20:42 roberto Exp $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lzio.h,v 1.31 2015/09/08 15:41:05 roberto Exp $ ** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $
** Buffered streams ** Buffered streams
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lapi.c,v 2.259 2016/02/29 14:27:14 roberto Exp $ ** $Id: lapi.c,v 2.259.1.2 2017/12/06 18:35:12 roberto Exp $
** Lua API ** Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -533,6 +533,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
lua_lock(L); lua_lock(L);
if (n == 0) { if (n == 0) {
setfvalue(L->top, fn); setfvalue(L->top, fn);
api_incr_top(L);
} }
else { else {
CClosure *cl; CClosure *cl;
@ -546,9 +547,9 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
/* does not need barrier because closure is white */ /* does not need barrier because closure is white */
} }
setclCvalue(L, L->top, cl); setclCvalue(L, L->top, cl);
api_incr_top(L);
luaC_checkGC(L);
} }
api_incr_top(L);
luaC_checkGC(L);
lua_unlock(L); lua_unlock(L);
} }
@ -1253,13 +1254,12 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
} }
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { static UpVal **getupvalref (lua_State *L, int fidx, int n) {
LClosure *f; LClosure *f;
StkId fi = index2addr(L, fidx); StkId fi = index2addr(L, fidx);
api_check(L, ttisLclosure(fi), "Lua function expected"); api_check(L, ttisLclosure(fi), "Lua function expected");
f = clLvalue(fi); f = clLvalue(fi);
api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
if (pf) *pf = f;
return &f->upvals[n - 1]; /* get its upvalue pointer */ return &f->upvals[n - 1]; /* get its upvalue pointer */
} }
@ -1268,7 +1268,7 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
StkId fi = index2addr(L, fidx); StkId fi = index2addr(L, fidx);
switch (ttype(fi)) { switch (ttype(fi)) {
case LUA_TLCL: { /* lua closure */ case LUA_TLCL: { /* lua closure */
return *getupvalref(L, fidx, n, NULL); return *getupvalref(L, fidx, n);
} }
case LUA_TCCL: { /* C closure */ case LUA_TCCL: { /* C closure */
CClosure *f = clCvalue(fi); CClosure *f = clCvalue(fi);
@ -1285,9 +1285,10 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
int fidx2, int n2) { int fidx2, int n2) {
LClosure *f1; UpVal **up1 = getupvalref(L, fidx1, n1);
UpVal **up1 = getupvalref(L, fidx1, n1, &f1); UpVal **up2 = getupvalref(L, fidx2, n2);
UpVal **up2 = getupvalref(L, fidx2, n2, NULL); if (*up1 == *up2)
return;
luaC_upvdeccount(L, *up1); luaC_upvdeccount(L, *up1);
*up1 = *up2; *up1 = *up2;
(*up1)->refcount++; (*up1)->refcount++;

@ -1,5 +1,5 @@
/* /*
** $Id: lauxlib.c,v 1.286 2016/01/08 15:33:09 roberto Exp $ ** $Id: lauxlib.c,v 1.289.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions for building Lua libraries ** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -69,12 +69,11 @@ static int findfield (lua_State *L, int objidx, int level) {
/* /*
** Search for a name for a function in all loaded modules ** Search for a name for a function in all loaded modules
** (registry._LOADED).
*/ */
static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
int top = lua_gettop(L); int top = lua_gettop(L);
lua_getinfo(L, "f", ar); /* push function */ lua_getinfo(L, "f", ar); /* push function */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
if (findfield(L, top + 1, 2)) { if (findfield(L, top + 1, 2)) {
const char *name = lua_tostring(L, -1); const char *name = lua_tostring(L, -1);
if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */ if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */
@ -809,13 +808,17 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */ if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
if (!lua_isstring(L, -1))
luaL_error(L, "'__tostring' must return a string");
}
else {
switch (lua_type(L, idx)) { switch (lua_type(L, idx)) {
case LUA_TNUMBER: { case LUA_TNUMBER: {
if (lua_isinteger(L, idx)) if (lua_isinteger(L, idx))
lua_pushfstring(L, "%I", lua_tointeger(L, idx)); lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx));
else else
lua_pushfstring(L, "%f", lua_tonumber(L, idx)); lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx));
break; break;
} }
case LUA_TSTRING: case LUA_TSTRING:
@ -827,10 +830,15 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
case LUA_TNIL: case LUA_TNIL:
lua_pushliteral(L, "nil"); lua_pushliteral(L, "nil");
break; break;
default: default: {
lua_pushfstring(L, "%s: %p", luaL_typename(L, idx), int tt = luaL_getmetafield(L, idx, "__name"); /* try name */
lua_topointer(L, idx)); const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) :
luaL_typename(L, idx);
lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx));
if (tt != LUA_TNIL)
lua_remove(L, -2); /* remove '__name' */
break; break;
}
} }
} }
return lua_tolstring(L, -1, len); return lua_tolstring(L, -1, len);
@ -882,23 +890,23 @@ static int libsize (const luaL_Reg *l) {
/* /*
** Find or create a module table with a given name. The function ** Find or create a module table with a given name. The function
** first looks at the _LOADED table and, if that fails, try a ** first looks at the LOADED table and, if that fails, try a
** global variable with that name. In any case, leaves on the stack ** global variable with that name. In any case, leaves on the stack
** the module table. ** the module table.
*/ */
LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
int sizehint) { int sizehint) {
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ luaL_findtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE, 1);
if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no _LOADED[modname]? */ if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no LOADED[modname]? */
lua_pop(L, 1); /* remove previous result */ lua_pop(L, 1); /* remove previous result */
/* try global variable (and create one if it does not exist) */ /* try global variable (and create one if it does not exist) */
lua_pushglobaltable(L); lua_pushglobaltable(L);
if (luaL_findtable(L, 0, modname, sizehint) != NULL) if (luaL_findtable(L, 0, modname, sizehint) != NULL)
luaL_error(L, "name conflict for module '%s'", modname); luaL_error(L, "name conflict for module '%s'", modname);
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ lua_setfield(L, -3, modname); /* LOADED[modname] = new table */
} }
lua_remove(L, -2); /* remove _LOADED table */ lua_remove(L, -2); /* remove LOADED table */
} }
@ -962,17 +970,17 @@ LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
*/ */
LUALIB_API void luaL_requiref (lua_State *L, const char *modname, LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
lua_CFunction openf, int glb) { lua_CFunction openf, int glb) {
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_getfield(L, -1, modname); /* _LOADED[modname] */ lua_getfield(L, -1, modname); /* LOADED[modname] */
if (!lua_toboolean(L, -1)) { /* package not already loaded? */ if (!lua_toboolean(L, -1)) { /* package not already loaded? */
lua_pop(L, 1); /* remove field */ lua_pop(L, 1); /* remove field */
lua_pushcfunction(L, openf); lua_pushcfunction(L, openf);
lua_pushstring(L, modname); /* argument to open function */ lua_pushstring(L, modname); /* argument to open function */
lua_call(L, 1, 1); /* call 'openf' to open module */ lua_call(L, 1, 1); /* call 'openf' to open module */
lua_pushvalue(L, -1); /* make copy of module (call result) */ lua_pushvalue(L, -1); /* make copy of module (call result) */
lua_setfield(L, -3, modname); /* _LOADED[modname] = module */ lua_setfield(L, -3, modname); /* LOADED[modname] = module */
} }
lua_remove(L, -2); /* remove _LOADED table */ lua_remove(L, -2); /* remove LOADED table */
if (glb) { if (glb) {
lua_pushvalue(L, -1); /* copy of module */ lua_pushvalue(L, -1); /* copy of module */
lua_setglobal(L, modname); /* _G[modname] = module */ lua_setglobal(L, modname); /* _G[modname] = module */
@ -1003,8 +1011,13 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
free(ptr); free(ptr);
return NULL; return NULL;
} }
else else { /* cannot fail when shrinking a block */
return realloc(ptr, nsize); void *newptr = realloc(ptr, nsize);
if (newptr == NULL && ptr != NULL && nsize <= osize)
return ptr; /* keep the original block */
else /* no fail or not shrinking */
return newptr; /* use the new block */
}
} }
@ -1030,6 +1043,6 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
luaL_error(L, "multiple Lua VMs detected"); luaL_error(L, "multiple Lua VMs detected");
else if (*v != ver) else if (*v != ver)
luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
ver, *v); (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v);
} }

@ -1,5 +1,5 @@
/* /*
** $Id: lbaselib.c,v 1.313 2016/04/11 19:18:40 roberto Exp $ ** $Id: lbaselib.c,v 1.314.1.1 2017/04/19 17:39:34 roberto Exp $
** Basic library ** Basic library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -208,8 +208,8 @@ static int luaB_type (lua_State *L) {
static int pairsmeta (lua_State *L, const char *method, int iszero, static int pairsmeta (lua_State *L, const char *method, int iszero,
lua_CFunction iter) { lua_CFunction iter) {
luaL_checkany(L, 1);
if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */ 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_pushcfunction(L, iter); /* will return generator, */
lua_pushvalue(L, 1); /* state, */ lua_pushvalue(L, 1); /* state, */
if (iszero) lua_pushinteger(L, 0); /* and initial value */ if (iszero) lua_pushinteger(L, 0); /* and initial value */

@ -1,5 +1,5 @@
/* /*
** $Id: lbitlib.c,v 1.30 2015/11/11 19:08:09 roberto Exp $ ** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $
** Standard library for bitwise operations ** Standard library for bitwise operations
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lcode.c,v 2.109 2016/05/13 19:09:21 roberto Exp $ ** $Id: lcode.c,v 2.112.1.1 2017/04/19 17:20:42 roberto Exp $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -40,7 +40,7 @@
** If expression is a numeric constant, fills 'v' with its value ** If expression is a numeric constant, fills 'v' with its value
** and returns 1. Otherwise, returns 0. ** and returns 1. Otherwise, returns 0.
*/ */
static int tonumeral(expdesc *e, TValue *v) { static int tonumeral(const expdesc *e, TValue *v) {
if (hasjumps(e)) if (hasjumps(e))
return 0; /* not a numeral */ return 0; /* not a numeral */
switch (e->k) { switch (e->k) {
@ -975,7 +975,8 @@ static int validop (int op, TValue *v1, TValue *v2) {
** Try to "constant-fold" an operation; return 1 iff successful. ** Try to "constant-fold" an operation; return 1 iff successful.
** (In this case, 'e1' has the final result.) ** (In this case, 'e1' has the final result.)
*/ */
static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) { static int constfolding (FuncState *fs, int op, expdesc *e1,
const expdesc *e2) {
TValue v1, v2, res; TValue v1, v2, res;
if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
return 0; /* non-numeric operands or not safe to fold */ return 0; /* non-numeric operands or not safe to fold */
@ -1014,11 +1015,14 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
** (everything but logical operators 'and'/'or' and comparison ** (everything but logical operators 'and'/'or' and comparison
** operators). ** operators).
** Expression to produce final result will be encoded in 'e1'. ** 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, static void codebinexpval (FuncState *fs, OpCode op,
expdesc *e1, expdesc *e2, int line) { expdesc *e1, expdesc *e2, int line) {
int rk1 = luaK_exp2RK(fs, e1); /* both operands are "RK" */ int rk2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
int rk2 = luaK_exp2RK(fs, e2); int rk1 = luaK_exp2RK(fs, e1);
freeexps(fs, e1, e2); freeexps(fs, e1, e2);
e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */ e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */
e1->k = VRELOCABLE; /* all those operations are relocatable */ e1->k = VRELOCABLE; /* all those operations are relocatable */
@ -1057,12 +1061,12 @@ static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
/* /*
** Aplly prefix operation 'op' to expression 'e'. ** Apply prefix operation 'op' to expression 'e'.
*/ */
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
static expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; /* fake 2nd operand */ static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
switch (op) { switch (op) {
case OPR_MINUS: case OPR_BNOT: case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */
if (constfolding(fs, op + LUA_OPUNM, e, &ef)) if (constfolding(fs, op + LUA_OPUNM, e, &ef))
break; break;
/* FALLTHROUGH */ /* FALLTHROUGH */

@ -1,5 +1,5 @@
/* /*
** $Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 roberto Exp $ ** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $
** Coroutine Library ** Coroutine Library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $ ** $Id: lctype.c,v 1.12.1.1 2017/04/19 17:20:42 roberto Exp $
** 'ctype' functions for Lua ** 'ctype' functions for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: ldblib.c,v 1.151 2015/11/23 11:29:43 roberto Exp $ ** $Id: ldblib.c,v 1.151.1.1 2017/04/19 17:20:42 roberto Exp $
** Interface from Lua to its debug API ** Interface from Lua to its debug API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: ldebug.c,v 2.120 2016/03/31 19:01:21 roberto Exp $ ** $Id: ldebug.c,v 2.121.1.2 2017/07/10 17:21:50 roberto Exp $
** Debug Interface ** Debug Interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -38,7 +38,8 @@
#define ci_func(ci) (clLvalue((ci)->func)) #define ci_func(ci) (clLvalue((ci)->func))
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
const char **name);
static int currentpc (CallInfo *ci) { static int currentpc (CallInfo *ci) {
@ -132,10 +133,11 @@ static const char *upvalname (Proto *p, int uv) {
static const char *findvararg (CallInfo *ci, int n, StkId *pos) { static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams; int nparams = clLvalue(ci->func)->p->numparams;
if (n >= cast_int(ci->u.l.base - ci->func) - nparams) int nvararg = cast_int(ci->u.l.base - ci->func) - nparams;
if (n <= -nvararg)
return NULL; /* no such vararg */ return NULL; /* no such vararg */
else { else {
*pos = ci->func + nparams + n; *pos = ci->func + nparams - n;
return "(*vararg)"; /* generic name for any vararg */ return "(*vararg)"; /* generic name for any vararg */
} }
} }
@ -147,7 +149,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
StkId base; StkId base;
if (isLua(ci)) { if (isLua(ci)) {
if (n < 0) /* access to vararg values? */ if (n < 0) /* access to vararg values? */
return findvararg(ci, -n, pos); return findvararg(ci, n, pos);
else { else {
base = ci->u.l.base; base = ci->u.l.base;
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
@ -244,6 +246,20 @@ static void collectvalidlines (lua_State *L, Closure *f) {
} }
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
if (ci == NULL) /* no 'ci'? */
return NULL; /* no info */
else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
*name = "__gc";
return "metamethod"; /* report it as such */
}
/* calling function is a known Lua function? */
else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
return funcnamefromcode(L, ci->previous, name);
else return NULL; /* no way to find a name */
}
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) { Closure *f, CallInfo *ci) {
int status = 1; int status = 1;
@ -274,11 +290,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
break; break;
} }
case 'n': { case 'n': {
/* calling function is a known Lua function? */ ar->namewhat = getfuncname(L, ci, &ar->name);
if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
ar->namewhat = getfuncname(L, ci->previous, &ar->name);
else
ar->namewhat = NULL;
if (ar->namewhat == NULL) { if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */ ar->namewhat = ""; /* not found */
ar->name = NULL; ar->name = NULL;
@ -471,8 +483,15 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
} }
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { /*
TMS tm = (TMS)0; /* to avoid warnings */ ** Try to find a name for a function based on the code that called it.
** (Only works when function was called by a Lua function.)
** Returns what the name is (e.g., "for iterator", "method",
** "metamethod") and sets '*name' to point to the name.
*/
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
const char **name) {
TMS tm = (TMS)0; /* (initial value avoids warnings) */
Proto *p = ci_func(ci)->p; /* calling function */ Proto *p = ci_func(ci)->p; /* calling function */
int pc = currentpc(ci); /* calling instruction index */ int pc = currentpc(ci); /* calling instruction index */
Instruction i = p->code[pc]; /* calling instruction */ Instruction i = p->code[pc]; /* calling instruction */
@ -482,13 +501,13 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
} }
switch (GET_OPCODE(i)) { switch (GET_OPCODE(i)) {
case OP_CALL: case OP_CALL:
case OP_TAILCALL: /* get function name */ case OP_TAILCALL:
return getobjname(p, pc, GETARG_A(i), name); return getobjname(p, pc, GETARG_A(i), name); /* get function name */
case OP_TFORCALL: { /* for iterator */ case OP_TFORCALL: { /* for iterator */
*name = "for iterator"; *name = "for iterator";
return "for iterator"; return "for iterator";
} }
/* all other instructions can call only through metamethods */ /* other instructions can do calls through metamethods */
case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
tm = TM_INDEX; tm = TM_INDEX;
break; break;
@ -509,7 +528,8 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
case OP_EQ: tm = TM_EQ; break; case OP_EQ: tm = TM_EQ; break;
case OP_LT: tm = TM_LT; break; case OP_LT: tm = TM_LT; break;
case OP_LE: tm = TM_LE; break; case OP_LE: tm = TM_LE; break;
default: lua_assert(0); /* other instructions cannot call a function */ default:
return NULL; /* cannot find a reasonable name */
} }
*name = getstr(G(L)->tmname[tm]); *name = getstr(G(L)->tmname[tm]);
return "metamethod"; return "metamethod";
@ -634,6 +654,7 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
CallInfo *ci = L->ci; CallInfo *ci = L->ci;
const char *msg; const char *msg;
va_list argp; va_list argp;
luaC_checkGC(L); /* error message uses memory */
va_start(argp, fmt); va_start(argp, fmt);
msg = luaO_pushvfstring(L, fmt, argp); /* format message */ msg = luaO_pushvfstring(L, fmt, argp); /* format message */
va_end(argp); va_end(argp);

@ -1,5 +1,5 @@
/* /*
** $Id: ldo.c,v 2.151 2015/12/16 16:40:07 roberto Exp $ ** $Id: ldo.c,v 2.157.1.1 2017/04/19 17:20:42 roberto Exp $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -211,9 +211,9 @@ static int stackinuse (lua_State *L) {
CallInfo *ci; CallInfo *ci;
StkId lim = L->top; StkId lim = L->top;
for (ci = L->ci; ci != NULL; ci = ci->previous) { for (ci = L->ci; ci != NULL; ci = ci->previous) {
lua_assert(ci->top <= L->stack_last);
if (lim < ci->top) lim = ci->top; 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 */ 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) { void luaD_shrinkstack (lua_State *L) {
int inuse = stackinuse(L); int inuse = stackinuse(L);
int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; if (goodsize > LUAI_MAXSTACK)
if (L->stacksize > LUAI_MAXSTACK) /* was handling stack overflow? */ 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) */ luaE_freeCI(L); /* free all CIs (list grew because of an error) */
else else
luaE_shrinkCI(L); /* shrink list */ luaE_shrinkCI(L); /* shrink list */
if (inuse <= LUAI_MAXSTACK && /* not handling stack overflow? */ /* if thread is currently not handling a stack overflow and its
goodsize < L->stacksize) /* trying to shrink? */ good size is smaller than current size, shrink its stack */
luaD_reallocstack(L, goodsize); /* shrink it */ if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
else goodsize < L->stacksize)
condmovestack(L,,); /* don't change stack (change only for debugging) */ luaD_reallocstack(L, goodsize);
else /* don't change stack */
condmovestack(L,{},{}); /* (change only for debugging) */
} }
@ -322,6 +325,72 @@ static void tryfuncTM (lua_State *L, StkId func) {
} }
/*
** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'.
** Handle most typical cases (zero results for commands, one result for
** expressions, multiple results for tail calls/single parameters)
** separated.
*/
static int moveresults (lua_State *L, const TValue *firstResult, StkId res,
int nres, int wanted) {
switch (wanted) { /* handle typical cases separately */
case 0: break; /* nothing to move */
case 1: { /* one result needed */
if (nres == 0) /* no results? */
firstResult = luaO_nilobject; /* adjust with nil */
setobjs2s(L, res, firstResult); /* move it to proper place */
break;
}
case LUA_MULTRET: {
int i;
for (i = 0; i < nres; i++) /* move all results to correct place */
setobjs2s(L, res + i, firstResult + i);
L->top = res + nres;
return 0; /* wanted == LUA_MULTRET */
}
default: {
int i;
if (wanted <= nres) { /* enough results? */
for (i = 0; i < wanted; i++) /* move wanted results to correct place */
setobjs2s(L, res + i, firstResult + i);
}
else { /* not enough results; use all of them plus nils */
for (i = 0; i < nres; i++) /* move all results to correct place */
setobjs2s(L, res + i, firstResult + i);
for (; i < wanted; i++) /* complete wanted number of results */
setnilvalue(res + i);
}
break;
}
}
L->top = res + wanted; /* top points after the last result */
return 1;
}
/*
** Finishes a function call: calls hook if necessary, removes CallInfo,
** moves current number of results to proper place; returns 0 iff call
** wanted multiple (variable number of) results.
*/
int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
StkId res;
int wanted = ci->nresults;
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
if (L->hookmask & LUA_MASKRET) {
ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
luaD_hook(L, LUA_HOOKRET, -1);
firstResult = restorestack(L, fr);
}
L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
}
res = ci->func; /* res == final position of 1st result */
L->ci = ci->previous; /* back to caller */
/* move results to proper place */
return moveresults(L, firstResult, res, nres, wanted);
}
#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
@ -374,13 +443,13 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
int n = cast_int(L->top - func) - 1; /* number of real arguments */ int n = cast_int(L->top - func) - 1; /* number of real arguments */
int fsize = p->maxstacksize; /* frame size */ int fsize = p->maxstacksize; /* frame size */
checkstackp(L, fsize, func); 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++) for (; n < p->numparams; n++)
setnilvalue(L->top++); /* complete missing arguments */ setnilvalue(L->top++); /* complete missing arguments */
base = func + 1; base = func + 1;
} }
else
base = adjust_varargs(L, p, n);
ci = next_ci(L); /* now 'enter' new function */ ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults; ci->nresults = nresults;
ci->func = func; ci->func = func;
@ -402,72 +471,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
} }
/*
** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'.
** Handle most typical cases (zero results for commands, one result for
** expressions, multiple results for tail calls/single parameters)
** separated.
*/
static int moveresults (lua_State *L, const TValue *firstResult, StkId res,
int nres, int wanted) {
switch (wanted) { /* handle typical cases separately */
case 0: break; /* nothing to move */
case 1: { /* one result needed */
if (nres == 0) /* no results? */
firstResult = luaO_nilobject; /* adjust with nil */
setobjs2s(L, res, firstResult); /* move it to proper place */
break;
}
case LUA_MULTRET: {
int i;
for (i = 0; i < nres; i++) /* move all results to correct place */
setobjs2s(L, res + i, firstResult + i);
L->top = res + nres;
return 0; /* wanted == LUA_MULTRET */
}
default: {
int i;
if (wanted <= nres) { /* enough results? */
for (i = 0; i < wanted; i++) /* move wanted results to correct place */
setobjs2s(L, res + i, firstResult + i);
}
else { /* not enough results; use all of them plus nils */
for (i = 0; i < nres; i++) /* move all results to correct place */
setobjs2s(L, res + i, firstResult + i);
for (; i < wanted; i++) /* complete wanted number of results */
setnilvalue(res + i);
}
break;
}
}
L->top = res + wanted; /* top points after the last result */
return 1;
}
/*
** Finishes a function call: calls hook if necessary, removes CallInfo,
** moves current number of results to proper place; returns 0 iff call
** wanted multiple (variable number of) results.
*/
int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
StkId res;
int wanted = ci->nresults;
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
if (L->hookmask & LUA_MASKRET) {
ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
luaD_hook(L, LUA_HOOKRET, -1);
firstResult = restorestack(L, fr);
}
L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
}
res = ci->func; /* res == final position of 1st result */
L->ci = ci->previous; /* back to caller */
/* move results to proper place */
return moveresults(L, firstResult, res, nres, wanted);
}
/* /*
** Check appropriate error for stack overflow ("regular" overflow or ** Check appropriate error for stack overflow ("regular" overflow or
** overflow while handling stack overflow). If 'nCalls' is larger than ** overflow while handling stack overflow). If 'nCalls' is larger than
@ -520,19 +523,17 @@ static void finishCcall (lua_State *L, int status) {
/* error status can only happen in a protected call */ /* error status can only happen in a protected call */
lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */ ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */
L->errfunc = ci->u.c.old_errfunc; L->errfunc = ci->u.c.old_errfunc; /* with the same error function */
} }
/* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
handled */ handled */
adjustresults(L, ci->nresults); adjustresults(L, ci->nresults);
/* call continuation function */
lua_unlock(L); 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); lua_lock(L);
api_checknelems(L, n); api_checknelems(L, n);
/* finish 'luaD_precall' */ luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */
luaD_poscall(L, ci, L->top - n, n);
} }
@ -595,15 +596,16 @@ static int recover (lua_State *L, int status) {
/* /*
** signal an error in the call to 'resume', not in the execution of the ** Signal an error in the call to 'lua_resume', not in the execution
** coroutine itself. (Such errors should not be handled by any coroutine ** of the coroutine itself. (Such errors should not be handled by any
** error handler and should not kill the coroutine.) ** coroutine error handler and should not kill the coroutine.)
*/ */
static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) { static int resume_error (lua_State *L, const char *msg, int narg) {
L->top = firstArg; /* remove args from the stack */ L->top -= narg; /* remove args from the stack */
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
api_incr_top(L); api_incr_top(L);
luaD_throw(L, -1); /* jump back to 'lua_resume' */ lua_unlock(L);
return LUA_ERRRUN;
} }
@ -615,22 +617,15 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
** coroutine. ** coroutine.
*/ */
static void resume (lua_State *L, void *ud) { static void resume (lua_State *L, void *ud) {
int nCcalls = L->nCcalls;
int n = *(cast(int*, ud)); /* number of arguments */ int n = *(cast(int*, ud)); /* number of arguments */
StkId firstArg = L->top - n; /* first argument */ StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci; CallInfo *ci = L->ci;
if (nCcalls >= LUAI_MAXCCALLS) if (L->status == LUA_OK) { /* starting a coroutine? */
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 (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
luaV_execute(L); /* call it */ luaV_execute(L); /* call it */
} }
else if (L->status != LUA_YIELD)
resume_error(L, "cannot resume dead coroutine", firstArg);
else { /* resuming from previous yield */ else { /* resuming from previous yield */
lua_assert(L->status == LUA_YIELD);
L->status = LUA_OK; /* mark that it is running (again) */ L->status = LUA_OK; /* mark that it is running (again) */
ci->func = restorestack(L, ci->extra); ci->func = restorestack(L, ci->extra);
if (isLua(ci)) /* yielded inside a hook? */ if (isLua(ci)) /* yielded inside a hook? */
@ -647,7 +642,6 @@ static void resume (lua_State *L, void *ud) {
} }
unroll(L, NULL); /* run continuation */ unroll(L, NULL); /* run continuation */
} }
lua_assert(nCcalls == L->nCcalls);
} }
@ -655,8 +649,16 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
int status; int status;
unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */
lua_lock(L); 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; 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 */ L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
status = luaD_rawrunprotected(L, resume, &nargs); status = luaD_rawrunprotected(L, resume, &nargs);

@ -1,5 +1,5 @@
/* /*
** $Id: ldump.c,v 2.37 2015/10/08 15:53:49 roberto Exp $ ** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $
** save precompiled Lua chunks ** save precompiled Lua chunks
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp $ ** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures ** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lgc.c,v 2.212 2016/03/31 19:02:03 roberto Exp $ ** $Id: lgc.c,v 2.215.1.2 2017/08/31 16:15:27 roberto Exp $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -467,7 +467,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
else /* not weak */ else /* not weak */
traversestrongtable(g, h); traversestrongtable(g, h);
return sizeof(Table) + sizeof(TValue) * h->sizearray + return sizeof(Table) + sizeof(TValue) * h->sizearray +
sizeof(Node) * cast(size_t, sizenode(h)); sizeof(Node) * cast(size_t, allocsizenode(h));
} }
@ -643,8 +643,9 @@ static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
for (n = gnode(h, 0); n < limit; n++) { for (n = gnode(h, 0); n < limit; n++) {
if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
setnilvalue(gval(n)); /* remove value ... */ setnilvalue(gval(n)); /* remove value ... */
removeentry(n); /* and remove entry from table */
} }
if (ttisnil(gval(n))) /* is entry empty? */
removeentry(n); /* remove entry from table */
} }
} }
} }
@ -818,7 +819,9 @@ static void GCTM (lua_State *L, int propagateerrors) {
setobj2s(L, L->top, tm); /* push finalizer... */ setobj2s(L, L->top, tm); /* push finalizer... */
setobj2s(L, L->top + 1, &v); /* ... and its argument */ setobj2s(L, L->top + 1, &v); /* ... and its argument */
L->top += 2; /* and (next line) call the finalizer */ L->top += 2; /* and (next line) call the finalizer */
L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
L->allowhook = oldah; /* restore hooks */ L->allowhook = oldah; /* restore hooks */
g->gcrunning = running; /* restore state */ g->gcrunning = running; /* restore state */
if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ if (status != LUA_OK && propagateerrors) { /* error while running __gc? */

@ -1,5 +1,5 @@
/* /*
** $Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp $ ** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $
** Initialization of libraries for lua.c and other clients ** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -18,10 +18,10 @@
** open the library, which is already linked to the application. ** open the library, which is already linked to the application.
** For that, do the following code: ** For that, do the following code:
** **
** luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
** lua_pushcfunction(L, luaopen_modname); ** lua_pushcfunction(L, luaopen_modname);
** lua_setfield(L, -2, modname); ** lua_setfield(L, -2, modname);
** lua_pop(L, 1); // remove _PRELOAD table ** lua_pop(L, 1); // remove PRELOAD table
*/ */
#include "lprefix.h" #include "lprefix.h"

@ -1,5 +1,5 @@
/* /*
** $Id: liolib.c,v 2.149 2016/05/02 14:03:19 roberto Exp $ ** $Id: liolib.c,v 2.151.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard I/O (and system) library ** Standard I/O (and system) library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -37,10 +37,11 @@
#endif #endif
/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */ /* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
#define l_checkmode(mode) \ static int l_checkmode (const char *mode) {
(*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \ return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
(*mode != '+' || (++mode, 1)) && /* skip if char is '+' */ \ (*mode != '+' || (++mode, 1)) && /* skip if char is '+' */
(strspn(mode, L_MODEEXT) == strlen(mode))) (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */
}
#endif #endif
@ -205,11 +206,16 @@ static int aux_close (lua_State *L) {
} }
static int f_close (lua_State *L) {
tofile(L); /* make sure argument is an open stream */
return aux_close(L);
}
static int io_close (lua_State *L) { static int io_close (lua_State *L) {
if (lua_isnone(L, 1)) /* no argument? */ if (lua_isnone(L, 1)) /* no argument? */
lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
tofile(L); /* make sure argument is an open stream */ return f_close(L);
return aux_close(L);
} }
@ -271,6 +277,8 @@ static int io_popen (lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r"); const char *mode = luaL_optstring(L, 2, "r");
LStream *p = newprefile(L); LStream *p = newprefile(L);
luaL_argcheck(L, ((mode[0] == 'r' || mode[0] == 'w') && mode[1] == '\0'),
2, "invalid mode");
p->f = l_popen(L, filename, mode); p->f = l_popen(L, filename, mode);
p->closef = &io_pclose; p->closef = &io_pclose;
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
@ -618,8 +626,10 @@ static int g_write (lua_State *L, FILE *f, int arg) {
if (lua_type(L, arg) == LUA_TNUMBER) { if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */ /* optimization: could be done exactly as for strings */
int len = lua_isinteger(L, arg) int len = lua_isinteger(L, arg)
? fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg)) ? fprintf(f, LUA_INTEGER_FMT,
: fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)); (LUAI_UACINT)lua_tointeger(L, arg))
: fprintf(f, LUA_NUMBER_FMT,
(LUAI_UACNUMBER)lua_tonumber(L, arg));
status = status && (len > 0); status = status && (len > 0);
} }
else { else {
@ -709,7 +719,7 @@ static const luaL_Reg iolib[] = {
** methods for file handles ** methods for file handles
*/ */
static const luaL_Reg flib[] = { static const luaL_Reg flib[] = {
{"close", io_close}, {"close", f_close},
{"flush", f_flush}, {"flush", f_flush},
{"lines", f_lines}, {"lines", f_lines},
{"read", f_read}, {"read", f_read},

@ -1,5 +1,5 @@
/* /*
** $Id: llex.c,v 2.96 2016/05/02 14:02:12 roberto Exp $ ** $Id: llex.c,v 2.96.1.1 2017/04/19 17:20:42 roberto Exp $
** Lexical Analyzer ** Lexical Analyzer
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -244,12 +244,12 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
/* /*
** skip a sequence '[=*[' or ']=*]'; if sequence is well formed, return ** reads a sequence '[=*[' or ']=*]', leaving the last bracket.
** its number of '='s; otherwise, return a negative number (-1 iff there ** If sequence is well formed, return its number of '='s + 2; otherwise,
** are no '='s after initial bracket) ** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...').
*/ */
static int skip_sep (LexState *ls) { static size_t skip_sep (LexState *ls) {
int count = 0; size_t count = 0;
int s = ls->current; int s = ls->current;
lua_assert(s == '[' || s == ']'); lua_assert(s == '[' || s == ']');
save_and_next(ls); save_and_next(ls);
@ -257,11 +257,14 @@ static int skip_sep (LexState *ls) {
save_and_next(ls); save_and_next(ls);
count++; count++;
} }
return (ls->current == s) ? count : (-count) - 1; return (ls->current == s) ? count + 2
: (count == 0) ? 1
: 0;
} }
static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) {
int line = ls->linenumber; /* initial line (for error message) */ int line = ls->linenumber; /* initial line (for error message) */
save_and_next(ls); /* skip 2nd '[' */ save_and_next(ls); /* skip 2nd '[' */
if (currIsNewline(ls)) /* string starts with a newline? */ if (currIsNewline(ls)) /* string starts with a newline? */
@ -295,8 +298,8 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
} }
} endloop: } endloop:
if (seminfo) if (seminfo)
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep,
luaZ_bufflen(ls->buff) - 2*(2 + sep)); luaZ_bufflen(ls->buff) - 2 * sep);
} }
@ -444,9 +447,9 @@ static int llex (LexState *ls, SemInfo *seminfo) {
/* else is a comment */ /* else is a comment */
next(ls); next(ls);
if (ls->current == '[') { /* long comment? */ if (ls->current == '[') { /* long comment? */
int sep = skip_sep(ls); size_t sep = skip_sep(ls);
luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */ luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */
if (sep >= 0) { if (sep >= 2) {
read_long_string(ls, NULL, sep); /* skip long comment */ read_long_string(ls, NULL, sep); /* skip long comment */
luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */
break; break;
@ -458,12 +461,12 @@ static int llex (LexState *ls, SemInfo *seminfo) {
break; break;
} }
case '[': { /* long string or simply '[' */ case '[': { /* long string or simply '[' */
int sep = skip_sep(ls); size_t sep = skip_sep(ls);
if (sep >= 0) { if (sep >= 2) {
read_long_string(ls, seminfo, sep); read_long_string(ls, seminfo, sep);
return TK_STRING; return TK_STRING;
} }
else if (sep != -1) /* '[=...' missing second bracket */ else if (sep == 0) /* '[=...' missing second bracket */
lexerror(ls, "invalid long string delimiter", TK_STRING); lexerror(ls, "invalid long string delimiter", TK_STRING);
return '['; return '[';
} }

@ -1,5 +1,5 @@
/* /*
** $Id: lmathlib.c,v 1.117 2015/10/02 15:39:23 roberto Exp $ ** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $
** Standard mathematical library ** Standard mathematical library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -184,10 +184,13 @@ static int math_log (lua_State *L) {
else { else {
lua_Number base = luaL_checknumber(L, 2); lua_Number base = luaL_checknumber(L, 2);
#if !defined(LUA_USE_C89) #if !defined(LUA_USE_C89)
if (base == 2.0) res = l_mathop(log2)(x); else if (base == l_mathop(2.0))
res = l_mathop(log2)(x); else
#endif #endif
if (base == 10.0) res = l_mathop(log10)(x); if (base == l_mathop(10.0))
else res = l_mathop(log)(x)/l_mathop(log)(base); res = l_mathop(log10)(x);
else
res = l_mathop(log)(x)/l_mathop(log)(base);
} }
lua_pushnumber(L, res); lua_pushnumber(L, res);
return 1; return 1;

@ -1,5 +1,5 @@
/* /*
** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $ ** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $
** Interface to Memory Manager ** Interface to Memory Manager
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: loadlib.c,v 1.127 2015/11/23 11:30:45 roberto Exp $ ** $Id: loadlib.c,v 1.130.1.1 2017/04/19 17:20:42 roberto Exp $
** Dynamic library loader for Lua ** Dynamic library loader for Lua
** See Copyright Notice in lua.h ** 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 ** LUA_IGMARK is a mark to ignore all before it when building the
** luaopen_ function name. ** 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) #if !defined (LUA_IGMARK)
#define LUA_IGMARK "-" #define LUA_IGMARK "-"
#endif #endif
@ -94,7 +63,8 @@ static const int CLIBS = 0;
#define LIB_FAIL "open" #define LIB_FAIL "open"
#define setprogdir(L) ((void)0)
#define setprogdir(L) ((void)0)
/* /*
@ -179,7 +149,6 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#include <windows.h> #include <windows.h>
#undef setprogdir
/* /*
** optional flags for LoadLibraryEx ** optional flags for LoadLibraryEx
@ -189,21 +158,30 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#endif #endif
#undef setprogdir
/*
** 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) { static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1]; char buff[MAX_PATH + 1];
char *lb; char *lb;
DWORD nsize = sizeof(buff)/sizeof(char); DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize); DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName"); luaL_error(L, "unable to get ModuleFileName");
else { else {
*lb = '\0'; *lb = '\0'; /* cut name on the last '\\' to get the path */
luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
lua_remove(L, -2); /* remove original string */ lua_remove(L, -2); /* remove original string */
} }
} }
static void pusherror (lua_State *L) { static void pusherror (lua_State *L) {
int error = GetLastError(); int error = GetLastError();
char buffer[128]; char buffer[128];
@ -272,6 +250,67 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#endif /* } */ #endif /* } */
/*
** {==================================================================
** 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 AUXMARK "\1" /* auxiliary mark */
/*
** 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;
}
/*
** Set a path
*/
static void setpath (lua_State *L, const char *fieldname,
const char *envname,
const char *dft) {
const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX);
const char *path = getenv(nver); /* use versioned name */
if (path == NULL) /* no environment variable? */
path = getenv(envname); /* try unversioned name */
if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, dft); /* 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, dft);
lua_remove(L, -2); /* remove result from 1st 'gsub' */
}
setprogdir(L);
lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */
lua_pop(L, 1); /* pop versioned variable name */
}
/* }================================================================== */
/* /*
** return registry.CLIBS[path] ** return registry.CLIBS[path]
*/ */
@ -520,7 +559,7 @@ static int searcher_Croot (lua_State *L) {
static int searcher_preload (lua_State *L) { static int searcher_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */ if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */
lua_pushfstring(L, "\n\tno field package.preload['%s']", name); lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
return 1; return 1;
@ -557,9 +596,9 @@ static void findloader (lua_State *L, const char *name) {
static int ll_require (lua_State *L) { static int ll_require (lua_State *L) {
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
lua_settop(L, 1); /* _LOADED table will be at index 2 */ lua_settop(L, 1); /* LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_getfield(L, 2, name); /* _LOADED[name] */ lua_getfield(L, 2, name); /* LOADED[name] */
if (lua_toboolean(L, -1)) /* is it there? */ if (lua_toboolean(L, -1)) /* is it there? */
return 1; /* package is already loaded */ return 1; /* package is already loaded */
/* else must load package */ /* else must load package */
@ -569,11 +608,11 @@ static int ll_require (lua_State *L) {
lua_insert(L, -2); /* name is 1st argument (before search data) */ lua_insert(L, -2); /* name is 1st argument (before search data) */
lua_call(L, 2, 1); /* run loader to load module */ lua_call(L, 2, 1); /* run loader to load module */
if (!lua_isnil(L, -1)) /* non-nil return? */ if (!lua_isnil(L, -1)) /* non-nil return? */
lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ lua_setfield(L, 2, name); /* LOADED[name] = returned value */
if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */
lua_pushboolean(L, 1); /* use true as result */ lua_pushboolean(L, 1); /* use true as result */
lua_pushvalue(L, -1); /* extra copy to be returned */ lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* _LOADED[name] = true */ lua_setfield(L, 2, name); /* LOADED[name] = true */
} }
return 1; return 1;
} }
@ -666,41 +705,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[] = { static const luaL_Reg pk_funcs[] = {
{"loadlib", ll_loadlib}, {"loadlib", ll_loadlib},
{"searchpath", ll_searchpath}, {"searchpath", ll_searchpath},
@ -764,19 +768,18 @@ LUAMOD_API int luaopen_package (lua_State *L) {
createclibstable(L); createclibstable(L);
luaL_newlib(L, pk_funcs); /* create 'package' table */ luaL_newlib(L, pk_funcs); /* create 'package' table */
createsearcherstable(L); createsearcherstable(L);
/* set field 'path' */ /* set paths */
setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT); setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT);
/* set field 'cpath' */ setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
/* store config information */ /* store config information */
lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
lua_setfield(L, -2, "config"); lua_setfield(L, -2, "config");
/* set field 'loaded' */ /* set field 'loaded' */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_setfield(L, -2, "loaded"); lua_setfield(L, -2, "loaded");
/* set field 'preload' */ /* set field 'preload' */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
lua_setfield(L, -2, "preload"); lua_setfield(L, -2, "preload");
lua_pushglobaltable(L); lua_pushglobaltable(L);
lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */

@ -1,5 +1,5 @@
/* /*
** $Id: lobject.c,v 2.111 2016/05/20 14:07:48 roberto Exp $ ** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $
** Some generic functions over Lua objects ** Some generic functions over Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -266,7 +266,7 @@ static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
** - 'n'/'N' means 'inf' or 'nan' (which should be rejected) ** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
** - '.' just optimizes the search for the common case (nothing special) ** - '.' just optimizes the search for the common case (nothing special)
** This function accepts both the current locale or a dot as the radix ** This function accepts both the current locale or a dot as the radix
** mark. If the convertion fails, it may mean number has a dot but ** mark. If the conversion fails, it may mean number has a dot but
** locale accepts something else. In that case, the code copies 's' ** locale accepts something else. In that case, the code copies 's'
** to a buffer (because 's' is read-only), changes the dot to the ** to a buffer (because 's' is read-only), changes the dot to the
** current locale radix mark, and tries to convert again. ** current locale radix mark, and tries to convert again.
@ -280,7 +280,7 @@ static const char *l_str2d (const char *s, lua_Number *result) {
endptr = l_str2dloc(s, result, mode); /* try to convert */ endptr = l_str2dloc(s, result, mode); /* try to convert */
if (endptr == NULL) { /* failed? may be a different locale */ if (endptr == NULL) { /* failed? may be a different locale */
char buff[L_MAXLENNUM + 1]; char buff[L_MAXLENNUM + 1];
char *pdot = (char*)strchr(s, '.'); const char *pdot = strchr(s, '.');
if (strlen(s) > L_MAXLENNUM || pdot == NULL) if (strlen(s) > L_MAXLENNUM || pdot == NULL)
return NULL; /* string too long or no dot; fail */ return NULL; /* string too long or no dot; fail */
strcpy(buff, s); /* copy string to buffer */ strcpy(buff, s); /* copy string to buffer */
@ -435,7 +435,8 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
} }
case 'p': { /* a pointer */ case 'p': { /* a pointer */
char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */ char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
int l = l_sprintf(buff, sizeof(buff), "%p", va_arg(argp, void *)); void *p = va_arg(argp, void *);
int l = lua_pointer2str(buff, sizeof(buff), p);
pushstr(L, buff, l); pushstr(L, buff, l);
break; break;
} }

@ -1,5 +1,5 @@
/* /*
** $Id: lopcodes.c,v 1.55 2015/01/05 13:48:33 roberto Exp $ ** $Id: lopcodes.c,v 1.55.1.1 2017/04/19 17:20:42 roberto Exp $
** Opcodes for Lua virtual machine ** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp $ ** $Id: loslib.c,v 1.65.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard Operating System library ** Standard Operating System library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -30,16 +30,16 @@
*/ */
#if !defined(LUA_STRFTIMEOPTIONS) /* { */ #if !defined(LUA_STRFTIMEOPTIONS) /* { */
/* options for ANSI C 89 */ /* options for ANSI C 89 (only 1-char options) */
#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%" #define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
/* options for ISO C 99 and POSIX */ /* options for ISO C 99 and POSIX */
#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \ #define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
"||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
/* options for Windows */ /* options for Windows */
#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \ #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) #if defined(LUA_USE_WINDOWS)
#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN #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) { static const char *checkoption (lua_State *L, const char *conv,
const char *option; ptrdiff_t convlen, char *buff) {
int oplen = 1; const char *option = LUA_STRFTIMEOPTIONS;
for (option = LUA_STRFTIMEOPTIONS; *option != '\0'; option += oplen) { int oplen = 1; /* length of options being checked */
for (; *option != '\0' && oplen <= convlen; option += oplen) {
if (*option == '|') /* next block? */ if (*option == '|') /* next block? */
oplen++; /* next length */ oplen++; /* will check options with next length (+1) */
else if (memcmp(conv, option, oplen) == 0) { /* match? */ else if (memcmp(conv, option, oplen) == 0) { /* match? */
memcpy(buff, conv, oplen); /* copy valid option to buffer */ memcpy(buff, conv, oplen); /* copy valid option to buffer */
buff[oplen] = '\0'; 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) { 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)); time_t t = luaL_opt(L, l_checktime, 2, time(NULL));
const char *se = s + slen; /* 's' end */
struct tm tmr, *stm; struct tm tmr, *stm;
if (*s == '!') { /* UTC? */ if (*s == '!') { /* UTC? */
stm = l_gmtime(&t, &tmr); stm = l_gmtime(&t, &tmr);
@ -290,7 +293,8 @@ static int os_date (lua_State *L) {
else else
stm = l_localtime(&t, &tmr); stm = l_localtime(&t, &tmr);
if (stm == NULL) /* invalid date? */ if (stm == NULL) /* invalid date? */
luaL_error(L, "time result cannot be represented in this installation"); return luaL_error(L,
"time result cannot be represented in this installation");
if (strcmp(s, "*t") == 0) { if (strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */ lua_createtable(L, 0, 9); /* 9 = number of fields */
setallfields(L, stm); setallfields(L, stm);
@ -300,13 +304,14 @@ static int os_date (lua_State *L) {
luaL_Buffer b; luaL_Buffer b;
cc[0] = '%'; cc[0] = '%';
luaL_buffinit(L, &b); luaL_buffinit(L, &b);
while (*s) { while (s < se) {
if (*s != '%') /* not a conversion specifier? */ if (*s != '%') /* not a conversion specifier? */
luaL_addchar(&b, *s++); luaL_addchar(&b, *s++);
else { else {
size_t reslen; size_t reslen;
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); 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); reslen = strftime(buff, SIZETIMEFMT, cc, stm);
luaL_addsize(&b, reslen); luaL_addsize(&b, reslen);
} }
@ -336,7 +341,8 @@ static int os_time (lua_State *L) {
setallfields(L, &ts); /* update fields with normalized values */ setallfields(L, &ts); /* update fields with normalized values */
} }
if (t != (time_t)(l_timet)t || t == (time_t)(-1)) if (t != (time_t)(l_timet)t || t == (time_t)(-1))
luaL_error(L, "time result cannot be represented in this installation"); return luaL_error(L,
"time result cannot be represented in this installation");
l_pushtime(L, t); l_pushtime(L, t);
return 1; return 1;
} }

@ -1,5 +1,5 @@
/* /*
** $Id: lparser.c,v 2.153 2016/05/13 19:10:16 roberto Exp $ ** $Id: lparser.c,v 2.155.1.2 2017/04/29 18:11:40 roberto Exp $
** Lua Parser ** Lua Parser
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -323,6 +323,8 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
luaK_nil(fs, reg, extra); luaK_nil(fs, reg, extra);
} }
} }
if (nexps > nvars)
ls->fs->freereg -= nexps - nvars; /* remove extra values */
} }
@ -542,6 +544,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
fs->bl = NULL; fs->bl = NULL;
f = fs->f; f = fs->f;
f->source = ls->source; f->source = ls->source;
luaC_objbarrier(ls->L, f, f->source);
f->maxstacksize = 2; /* registers 0/1 are always valid */ f->maxstacksize = 2; /* registers 0/1 are always valid */
enterblock(fs, bl, 0); enterblock(fs, bl, 0);
} }
@ -764,7 +767,7 @@ static void parlist (LexState *ls) {
} }
case TK_DOTS: { /* param -> '...' */ case TK_DOTS: { /* param -> '...' */
luaX_next(ls); luaX_next(ls);
f->is_vararg = 2; /* declared vararg */ f->is_vararg = 1; /* declared vararg */
break; break;
} }
default: luaX_syntaxerror(ls, "<name> or '...' expected"); default: luaX_syntaxerror(ls, "<name> or '...' expected");
@ -960,7 +963,6 @@ static void simpleexp (LexState *ls, expdesc *v) {
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
check_condition(ls, fs->f->is_vararg, check_condition(ls, fs->f->is_vararg,
"cannot use '...' outside a vararg function"); "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)); init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
break; break;
} }
@ -1160,11 +1162,8 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
int nexps; int nexps;
checknext(ls, '='); checknext(ls, '=');
nexps = explist(ls, &e); nexps = explist(ls, &e);
if (nexps != nvars) { if (nexps != nvars)
adjust_assign(ls, nvars, nexps, &e); adjust_assign(ls, nvars, nexps, &e);
if (nexps > nvars)
ls->fs->freereg -= nexps - nvars; /* remove extra values */
}
else { else {
luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_setoneret(ls->fs, &e); /* close last expression */
luaK_storevar(ls->fs, &lh->v, &e); luaK_storevar(ls->fs, &lh->v, &e);
@ -1394,7 +1393,7 @@ static void test_then_block (LexState *ls, int *escapelist) {
luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
enterblock(fs, &bl, 0); /* must enter block before 'goto' */ enterblock(fs, &bl, 0); /* must enter block before 'goto' */
gotostat(ls, v.t); /* handle goto/break */ gotostat(ls, v.t); /* handle goto/break */
skipnoopstat(ls); /* skip other no-op statements */ while (testnext(ls, ';')) {} /* skip colons */
if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
leaveblock(fs); leaveblock(fs);
return; /* and that is it */ return; /* and that is it */
@ -1615,9 +1614,10 @@ static void mainfunc (LexState *ls, FuncState *fs) {
BlockCnt bl; BlockCnt bl;
expdesc v; expdesc v;
open_func(ls, fs, &bl); 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); /* create and... */ init_exp(&v, VLOCAL, 0); /* create and... */
newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
luaC_objbarrier(ls->L, fs->f, ls->envn);
luaX_next(ls); /* read first token */ luaX_next(ls); /* read first token */
statlist(ls); /* parse main body */ statlist(ls); /* parse main body */
check(ls, TK_EOS); check(ls, TK_EOS);
@ -1636,6 +1636,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
sethvalue(L, L->top, lexstate.h); /* anchor it */ sethvalue(L, L->top, lexstate.h); /* anchor it */
luaD_inctop(L); luaD_inctop(L);
funcstate.f = cl->p = luaF_newproto(L); funcstate.f = cl->p = luaF_newproto(L);
luaC_objbarrier(L, cl, cl->p);
funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ lua_assert(iswhite(funcstate.f)); /* do not need barrier here */
lexstate.buff = buff; lexstate.buff = buff;

@ -1,5 +1,5 @@
/* /*
** $Id: lstate.c,v 2.133 2015/11/13 12:16:51 roberto Exp $ ** $Id: lstate.c,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lstring.c,v 2.56 2015/11/23 11:32:51 roberto Exp $ ** $Id: lstring.c,v 2.56.1.1 2017/04/19 17:20:42 roberto Exp $
** String table (keeps all strings handled by Lua) ** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lstrlib.c,v 1.251 2016/05/20 14:13:21 roberto Exp $ ** $Id: lstrlib.c,v 1.254.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard library for string operations and pattern-matching ** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -839,11 +839,12 @@ static lua_Number adddigit (char *buff, int n, lua_Number x) {
static int num2straux (char *buff, int sz, lua_Number x) { static int num2straux (char *buff, int sz, lua_Number x) {
if (x != x || x == HUGE_VAL || x == -HUGE_VAL) /* inf or NaN? */ /* if 'inf' or 'NaN', format it like '%g' */
return l_sprintf(buff, sz, LUA_NUMBER_FMT, x); /* equal to '%g' */ if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL)
return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x);
else if (x == 0) { /* can be -0... */ else if (x == 0) { /* can be -0... */
/* create "0" or "-0" followed by exponent */ /* create "0" or "-0" followed by exponent */
return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", x); return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x);
} }
else { else {
int e; int e;
@ -878,7 +879,7 @@ static int lua_number2strx (lua_State *L, char *buff, int sz,
buff[i] = toupper(uchar(buff[i])); buff[i] = toupper(uchar(buff[i]));
} }
else if (fmt[SIZELENMOD] != 'a') else if (fmt[SIZELENMOD] != 'a')
luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
return n; return n;
} }
@ -933,7 +934,7 @@ static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
static void checkdp (char *buff, int nb) { static void checkdp (char *buff, int nb) {
if (memchr(buff, '.', nb) == NULL) { /* no dot? */ if (memchr(buff, '.', nb) == NULL) { /* no dot? */
char point = lua_getlocaledecpoint(); /* try locale point */ char point = lua_getlocaledecpoint(); /* try locale point */
char *ppoint = (char*)memchr(buff, point, nb); char *ppoint = (char *)memchr(buff, point, nb);
if (ppoint) *ppoint = '.'; /* change it to a dot */ if (ppoint) *ppoint = '.'; /* change it to a dot */
} }
} }
@ -960,7 +961,7 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
const char *format = (n == LUA_MININTEGER) /* corner case? */ const char *format = (n == LUA_MININTEGER) /* corner case? */
? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */ ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */
: LUA_INTEGER_FMT; /* else use default format */ : LUA_INTEGER_FMT; /* else use default format */
nb = l_sprintf(buff, MAX_ITEM, format, n); nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n);
} }
luaL_addsize(b, nb); luaL_addsize(b, nb);
break; break;
@ -1041,7 +1042,7 @@ static int str_format (lua_State *L) {
case 'o': case 'u': case 'x': case 'X': { case 'o': case 'u': case 'x': case 'X': {
lua_Integer n = luaL_checkinteger(L, arg); lua_Integer n = luaL_checkinteger(L, arg);
addlenmod(form, LUA_INTEGER_FRMLEN); addlenmod(form, LUA_INTEGER_FRMLEN);
nb = l_sprintf(buff, MAX_ITEM, form, n); nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n);
break; break;
} }
case 'a': case 'A': case 'a': case 'A':
@ -1051,8 +1052,9 @@ static int str_format (lua_State *L) {
break; break;
case 'e': case 'E': case 'f': case 'e': case 'E': case 'f':
case 'g': case 'G': { case 'g': case 'G': {
lua_Number n = luaL_checknumber(L, arg);
addlenmod(form, LUA_NUMBER_FRMLEN); addlenmod(form, LUA_NUMBER_FRMLEN);
nb = l_sprintf(buff, MAX_ITEM, form, luaL_checknumber(L, arg)); nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n);
break; break;
} }
case 'q': { case 'q': {
@ -1197,8 +1199,8 @@ static int getnum (const char **fmt, int df) {
static int getnumlimit (Header *h, const char **fmt, int df) { static int getnumlimit (Header *h, const char **fmt, int df) {
int sz = getnum(fmt, df); int sz = getnum(fmt, df);
if (sz > MAXINTSIZE || sz <= 0) if (sz > MAXINTSIZE || sz <= 0)
luaL_error(h->L, "integral size (%d) out of limits [1,%d]", return luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
sz, MAXINTSIZE); sz, MAXINTSIZE);
return sz; return sz;
} }

@ -1,5 +1,5 @@
/* /*
** $Id: ltable.c,v 2.117 2015/11/19 19:16:22 roberto Exp $ ** $Id: ltable.c,v 2.118.1.4 2018/06/08 16:22:51 roberto Exp $
** Lua tables (hash) ** Lua tables (hash)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -74,8 +74,6 @@
#define dummynode (&dummynode_) #define dummynode (&dummynode_)
#define isdummy(n) ((n) == dummynode)
static const Node dummynode_ = { static const Node dummynode_ = {
{NILCONSTANT}, /* value */ {NILCONSTANT}, /* value */
{{NILCONSTANT, 0}} /* key */ {{NILCONSTANT, 0}} /* key */
@ -225,7 +223,9 @@ static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
unsigned int na = 0; /* number of elements to go to array part */ unsigned int na = 0; /* number of elements to go to array part */
unsigned int optimal = 0; /* optimal size for array part */ unsigned int optimal = 0; /* optimal size for array part */
/* loop while keys can fill more than half of total size */ /* loop while keys can fill more than half of total size */
for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) { for (i = 0, twotoi = 1;
twotoi > 0 && *pna > twotoi / 2;
i++, twotoi *= 2) {
if (nums[i] > 0) { if (nums[i] > 0) {
a += nums[i]; a += nums[i];
if (a > twotoi/2) { /* more than half elements present? */ if (a > twotoi/2) { /* more than half elements present? */
@ -308,14 +308,14 @@ static void setarrayvector (lua_State *L, Table *t, unsigned int size) {
static void setnodevector (lua_State *L, Table *t, unsigned int size) { static void setnodevector (lua_State *L, Table *t, unsigned int size) {
int lsize;
if (size == 0) { /* no elements to hash part? */ if (size == 0) { /* no elements to hash part? */
t->node = cast(Node *, dummynode); /* use common 'dummynode' */ t->node = cast(Node *, dummynode); /* use common 'dummynode' */
lsize = 0; t->lsizenode = 0;
t->lastfree = NULL; /* signal that it is using dummy node */
} }
else { else {
int i; int i;
lsize = luaO_ceillog2(size); int lsize = luaO_ceillog2(size);
if (lsize > MAXHBITS) if (lsize > MAXHBITS)
luaG_runerror(L, "table overflow"); luaG_runerror(L, "table overflow");
size = twoto(lsize); size = twoto(lsize);
@ -326,9 +326,21 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
setnilvalue(wgkey(n)); setnilvalue(wgkey(n));
setnilvalue(gval(n)); setnilvalue(gval(n));
} }
t->lsizenode = cast_byte(lsize);
t->lastfree = gnode(t, size); /* all positions are free */
} }
t->lsizenode = cast_byte(lsize); }
t->lastfree = gnode(t, size); /* all positions are free */
typedef struct {
Table *t;
unsigned int nhsize;
} AuxsetnodeT;
static void auxsetnode (lua_State *L, void *ud) {
AuxsetnodeT *asn = cast(AuxsetnodeT *, ud);
setnodevector(L, asn->t, asn->nhsize);
} }
@ -336,13 +348,18 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
unsigned int nhsize) { unsigned int nhsize) {
unsigned int i; unsigned int i;
int j; int j;
AuxsetnodeT asn;
unsigned int oldasize = t->sizearray; unsigned int oldasize = t->sizearray;
int oldhsize = t->lsizenode; int oldhsize = allocsizenode(t);
Node *nold = t->node; /* save old hash ... */ Node *nold = t->node; /* save old hash ... */
if (nasize > oldasize) /* array part must grow? */ if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize); setarrayvector(L, t, nasize);
/* create new hash part with appropriate size */ /* create new hash part with appropriate size */
setnodevector(L, t, nhsize); asn.t = t; asn.nhsize = nhsize;
if (luaD_rawrunprotected(L, auxsetnode, &asn) != LUA_OK) { /* mem. error? */
setarrayvector(L, t, oldasize); /* array back to its original size */
luaD_throw(L, LUA_ERRMEM); /* rethrow memory error */
}
if (nasize < oldasize) { /* array part must shrink? */ if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize; t->sizearray = nasize;
/* re-insert elements from vanishing slice */ /* re-insert elements from vanishing slice */
@ -354,7 +371,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
luaM_reallocvector(L, t->array, oldasize, nasize, TValue); luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
} }
/* re-insert elements from hash part */ /* re-insert elements from hash part */
for (j = twoto(oldhsize) - 1; j >= 0; j--) { for (j = oldhsize - 1; j >= 0; j--) {
Node *old = nold + j; Node *old = nold + j;
if (!ttisnil(gval(old))) { if (!ttisnil(gval(old))) {
/* doesn't need barrier/invalidate cache, as entry was /* doesn't need barrier/invalidate cache, as entry was
@ -362,13 +379,13 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
} }
} }
if (!isdummy(nold)) if (oldhsize > 0) /* not the dummy node? */
luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */ luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */
} }
void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
int nsize = isdummy(t->node) ? 0 : sizenode(t); int nsize = allocsizenode(t);
luaH_resize(L, t, nasize, nsize); luaH_resize(L, t, nasize, nsize);
} }
@ -414,7 +431,7 @@ Table *luaH_new (lua_State *L) {
void luaH_free (lua_State *L, Table *t) { void luaH_free (lua_State *L, Table *t) {
if (!isdummy(t->node)) if (!isdummy(t))
luaM_freearray(L, t->node, cast(size_t, sizenode(t))); luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
luaM_freearray(L, t->array, t->sizearray); luaM_freearray(L, t->array, t->sizearray);
luaM_free(L, t); luaM_free(L, t);
@ -422,10 +439,12 @@ void luaH_free (lua_State *L, Table *t) {
static Node *getfreepos (Table *t) { static Node *getfreepos (Table *t) {
while (t->lastfree > t->node) { if (!isdummy(t)) {
t->lastfree--; while (t->lastfree > t->node) {
if (ttisnil(gkey(t->lastfree))) t->lastfree--;
return t->lastfree; if (ttisnil(gkey(t->lastfree)))
return t->lastfree;
}
} }
return NULL; /* could not find a free place */ return NULL; /* could not find a free place */
} }
@ -445,7 +464,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
if (ttisnil(key)) luaG_runerror(L, "table index is nil"); if (ttisnil(key)) luaG_runerror(L, "table index is nil");
else if (ttisfloat(key)) { else if (ttisfloat(key)) {
lua_Integer k; lua_Integer k;
if (luaV_tointeger(key, &k, 0)) { /* index is int? */ if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */
setivalue(&aux, k); setivalue(&aux, k);
key = &aux; /* insert it as an integer */ key = &aux; /* insert it as an integer */
} }
@ -453,7 +472,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
luaG_runerror(L, "table index is NaN"); luaG_runerror(L, "table index is NaN");
} }
mp = mainposition(t, key); mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */
Node *othern; Node *othern;
Node *f = getfreepos(t); /* get a free place */ Node *f = getfreepos(t); /* get a free place */
if (f == NULL) { /* cannot find a free place? */ if (f == NULL) { /* cannot find a free place? */
@ -461,7 +480,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
/* whatever called 'newkey' takes care of TM cache */ /* whatever called 'newkey' takes care of TM cache */
return luaH_set(L, t, key); /* insert key into grown table */ return luaH_set(L, t, key); /* insert key into grown table */
} }
lua_assert(!isdummy(f)); lua_assert(!isdummy(t));
othern = mainposition(t, gkey(mp)); othern = mainposition(t, gkey(mp));
if (othern != mp) { /* is colliding node out of its main position? */ if (othern != mp) { /* is colliding node out of its main position? */
/* yes; move colliding node into free position */ /* yes; move colliding node into free position */
@ -610,13 +629,13 @@ void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
} }
static int unbound_search (Table *t, unsigned int j) { static lua_Unsigned unbound_search (Table *t, lua_Unsigned j) {
unsigned int i = j; /* i is zero or a present index */ lua_Unsigned i = j; /* i is zero or a present index */
j++; j++;
/* find 'i' and 'j' such that i is present and j is not */ /* find 'i' and 'j' such that i is present and j is not */
while (!ttisnil(luaH_getint(t, j))) { while (!ttisnil(luaH_getint(t, j))) {
i = j; i = j;
if (j > cast(unsigned int, MAX_INT)/2) { /* overflow? */ if (j > l_castS2U(LUA_MAXINTEGER) / 2) { /* overflow? */
/* table was built with bad purposes: resort to linear search */ /* table was built with bad purposes: resort to linear search */
i = 1; i = 1;
while (!ttisnil(luaH_getint(t, i))) i++; while (!ttisnil(luaH_getint(t, i))) i++;
@ -626,7 +645,7 @@ static int unbound_search (Table *t, unsigned int j) {
} }
/* now do a binary search between them */ /* now do a binary search between them */
while (j - i > 1) { while (j - i > 1) {
unsigned int m = (i+j)/2; lua_Unsigned m = (i+j)/2;
if (ttisnil(luaH_getint(t, m))) j = m; if (ttisnil(luaH_getint(t, m))) j = m;
else i = m; else i = m;
} }
@ -638,7 +657,7 @@ static int unbound_search (Table *t, unsigned int j) {
** Try to find a boundary in table 't'. A 'boundary' is an integer index ** Try to find a boundary in table 't'. A 'boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/ */
int luaH_getn (Table *t) { lua_Unsigned luaH_getn (Table *t) {
unsigned int j = t->sizearray; unsigned int j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) { if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */ /* there is a boundary in the array part: (binary) search for it */
@ -651,7 +670,7 @@ int luaH_getn (Table *t) {
return i; return i;
} }
/* else must find a boundary in hash part */ /* else must find a boundary in hash part */
else if (isdummy(t->node)) /* hash part is empty? */ else if (isdummy(t)) /* hash part is empty? */
return j; /* that is easy... */ return j; /* that is easy... */
else return unbound_search(t, j); else return unbound_search(t, j);
} }
@ -664,6 +683,6 @@ Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key); return mainposition(t, key);
} }
int luaH_isdummy (Node *n) { return isdummy(n); } int luaH_isdummy (const Table *t) { return isdummy(t); }
#endif #endif

@ -1,5 +1,5 @@
/* /*
** $Id: ltablib.c,v 1.93 2016/02/25 19:41:54 roberto Exp $ ** $Id: ltablib.c,v 1.93.1.1 2017/04/19 17:20:42 roberto Exp $
** Library for Table Manipulation ** Library for Table Manipulation
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: ltm.c,v 2.37 2016/02/26 19:20:15 roberto Exp $ ** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $
** Tag methods ** Tag methods
** See Copyright Notice in lua.h ** 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.230.1.1 2017/04/19 17:29:57 roberto Exp $
** Lua stand-alone interpreter ** Lua stand-alone interpreter
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -20,6 +20,7 @@
#include "lualib.h" #include "lualib.h"
#if !defined(LUA_PROMPT) #if !defined(LUA_PROMPT)
#define LUA_PROMPT "> " #define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> " #define LUA_PROMPT2 ">> "
@ -37,8 +38,7 @@
#define LUA_INIT_VAR "LUA_INIT" #define LUA_INIT_VAR "LUA_INIT"
#endif #endif
#define LUA_INITVARVERSION \ #define LUA_INITVARVERSION LUA_INIT_VAR LUA_VERSUFFIX
LUA_INIT_VAR "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
/* /*
@ -55,6 +55,8 @@
#elif defined(LUA_USE_WINDOWS) /* }{ */ #elif defined(LUA_USE_WINDOWS) /* }{ */
#include <io.h> #include <io.h>
#include <windows.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin)) #define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else /* }{ */ #else /* }{ */
@ -136,7 +138,7 @@ static void print_usage (const char *badoption) {
"Available options are:\n" "Available options are:\n"
" -e stat execute string 'stat'\n" " -e stat execute string 'stat'\n"
" -i enter interactive mode after executing 'script'\n" " -i enter interactive mode after executing 'script'\n"
" -l name require library 'name'\n" " -l name require library 'name' into global 'name'\n"
" -v show version information\n" " -v show version information\n"
" -E ignore environment variables\n" " -E ignore environment variables\n"
" -- stop handling options\n" " -- stop handling options\n"
@ -529,6 +531,7 @@ static int runargs (lua_State *L, char **argv, int n) {
} }
static int handle_luainit (lua_State *L) { static int handle_luainit (lua_State *L) {
const char *name = "=" LUA_INITVARVERSION; const char *name = "=" LUA_INITVARVERSION;
const char *init = getenv(name + 1); const char *init = getenv(name + 1);

@ -1,5 +1,5 @@
/* /*
** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $ ** $Id: luac.c,v 1.76 2018/06/19 01:32:02 lhf Exp $
** Lua compiler (saves bytecodes to files; also lists bytecodes) ** Lua compiler (saves bytecodes to files; also lists bytecodes)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -206,7 +206,7 @@ int main(int argc, char* argv[])
} }
/* /*
** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $ ** $Id: luac.c,v 1.76 2018/06/19 01:32:02 lhf Exp $
** print bytecodes ** print bytecodes
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -348,6 +348,7 @@ static void PrintCode(const Proto* f)
case OP_ADD: case OP_ADD:
case OP_SUB: case OP_SUB:
case OP_MUL: case OP_MUL:
case OP_MOD:
case OP_POW: case OP_POW:
case OP_DIV: case OP_DIV:
case OP_IDIV: case OP_IDIV:

@ -1,5 +1,5 @@
/* /*
** $Id: lundump.c,v 2.44 2015/11/02 16:09:30 roberto Exp $ ** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $
** load precompiled Lua chunks ** load precompiled Lua chunks
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -85,8 +85,10 @@ static lua_Integer LoadInteger (LoadState *S) {
} }
static TString *LoadString (LoadState *S) { static TString *LoadString (LoadState *S, Proto *p) {
lua_State *L = S->L;
size_t size = LoadByte(S); size_t size = LoadByte(S);
TString *ts;
if (size == 0xFF) if (size == 0xFF)
LoadVar(S, size); LoadVar(S, size);
if (size == 0) if (size == 0)
@ -94,13 +96,17 @@ static TString *LoadString (LoadState *S) {
else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
char buff[LUAI_MAXSHORTLEN]; char buff[LUAI_MAXSHORTLEN];
LoadVector(S, buff, size); LoadVector(S, buff, size);
return luaS_newlstr(S->L, buff, size); ts = luaS_newlstr(L, buff, size);
} }
else { /* long string */ else { /* long string */
TString *ts = luaS_createlngstrobj(S->L, size); ts = luaS_createlngstrobj(L, size);
setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */
luaD_inctop(L);
LoadVector(S, getstr(ts), size); /* load directly in final place */ LoadVector(S, getstr(ts), size); /* load directly in final place */
return ts; L->top--; /* pop string */
} }
luaC_objbarrier(L, p, ts);
return ts;
} }
@ -140,7 +146,7 @@ static void LoadConstants (LoadState *S, Proto *f) {
break; break;
case LUA_TSHRSTR: case LUA_TSHRSTR:
case LUA_TLNGSTR: case LUA_TLNGSTR:
setsvalue2n(S->L, o, LoadString(S)); setsvalue2n(S->L, o, LoadString(S, f));
break; break;
default: default:
lua_assert(0); lua_assert(0);
@ -158,6 +164,7 @@ static void LoadProtos (LoadState *S, Proto *f) {
f->p[i] = NULL; f->p[i] = NULL;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
f->p[i] = luaF_newproto(S->L); f->p[i] = luaF_newproto(S->L);
luaC_objbarrier(S->L, f, f->p[i]);
LoadFunction(S, f->p[i], f->source); LoadFunction(S, f->p[i], f->source);
} }
} }
@ -189,18 +196,18 @@ static void LoadDebug (LoadState *S, Proto *f) {
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
f->locvars[i].varname = NULL; f->locvars[i].varname = NULL;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
f->locvars[i].varname = LoadString(S); f->locvars[i].varname = LoadString(S, f);
f->locvars[i].startpc = LoadInt(S); f->locvars[i].startpc = LoadInt(S);
f->locvars[i].endpc = LoadInt(S); f->locvars[i].endpc = LoadInt(S);
} }
n = LoadInt(S); n = LoadInt(S);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
f->upvalues[i].name = LoadString(S); f->upvalues[i].name = LoadString(S, f);
} }
static void LoadFunction (LoadState *S, Proto *f, TString *psource) { static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
f->source = LoadString(S); f->source = LoadString(S, f);
if (f->source == NULL) /* no source in dump? */ if (f->source == NULL) /* no source in dump? */
f->source = psource; /* reuse parent's source */ f->source = psource; /* reuse parent's source */
f->linedefined = LoadInt(S); f->linedefined = LoadInt(S);
@ -271,6 +278,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
setclLvalue(L, L->top, cl); setclLvalue(L, L->top, cl);
luaD_inctop(L); luaD_inctop(L);
cl->p = luaF_newproto(L); cl->p = luaF_newproto(L);
luaC_objbarrier(L, cl, cl->p);
LoadFunction(&S, cl->p, NULL); LoadFunction(&S, cl->p, NULL);
lua_assert(cl->nupvalues == cl->p->sizeupvalues); lua_assert(cl->nupvalues == cl->p->sizeupvalues);
luai_verifycode(L, buff, cl->p); luai_verifycode(L, buff, cl->p);

@ -1,5 +1,5 @@
/* /*
** $Id: lutf8lib.c,v 1.15 2015/03/28 19:16:55 roberto Exp $ ** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard library for UTF-8 manipulation ** Standard library for UTF-8 manipulation
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -171,7 +171,7 @@ static int byteoffset (lua_State *L) {
} }
else { else {
if (iscont(s + posi)) if (iscont(s + posi))
luaL_error(L, "initial position is a continuation byte"); return luaL_error(L, "initial position is a continuation byte");
if (n < 0) { if (n < 0) {
while (n < 0 && posi > 0) { /* move back */ while (n < 0 && posi > 0) { /* move back */
do { /* find beginning of previous character */ do { /* find beginning of previous character */

@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 2.268 2016/02/05 19:59:14 roberto Exp $ ** $Id: lvm.c,v 2.268.1.1 2017/04/19 17:39:34 roberto Exp $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */

@ -1,5 +1,5 @@
/* /*
** $Id: lzio.c,v 1.37 2015/09/08 15:41:05 roberto Exp $ ** $Id: lzio.c,v 1.37.1.1 2017/04/19 17:20:42 roberto Exp $
** Buffered streams ** Buffered streams
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */