Bump to LUA 5.3.3 37/98637/1 tizen
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 18 Nov 2016 04:42:02 +0000 (13:42 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 18 Nov 2016 04:52:37 +0000 (13:52 +0900)
    1. merge from origin
    2. add shared library creating patch
        https://build.opensuse.org/package/view_file/home:ithod/lua/lua-5.3.3-shared.patch?expand=1
    3. add api visible patch
        https://build.opensuse.org/package/view_file/home:ithod/lua/lua-5.3.3-visible.patch?expand=1

Change-Id: I35ade59b19afbbee3ba69291cf7c8bae94ea3327
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
14 files changed:
1  2 
COPYRIGHT
Makefile
packaging/lua.spec
src/Makefile
src/lcode.c
src/ldblib.c
src/liolib.c
src/llex.c
src/loadlib.c
src/lopcodes.h
src/lstrlib.c
src/luaconf.h
src/lundump.h
src/lvm.c

diff --cc COPYRIGHT
index 0000000,3a53e74..847d9ae
mode 000000,100644..100644
--- /dev/null
+++ b/COPYRIGHT
@@@ -1,0 -1,34 +1,34 @@@
 -Copyright (C) 1994-2008 Lua.org, PUC-Rio.
+ Lua License
+ -----------
+ Lua is licensed under the terms of the MIT license reproduced below.
+ This means that Lua is free software and can be used for both academic
+ and commercial purposes at absolutely no cost.
+ For details and rationale, see http://www.lua.org/license.html .
+ ===============================================================================
 -The above copyright notice and this permission notice shall be included in
 -all copies or substantial portions of the Software.
++Copyright © 1994–2016 Lua.org, PUC-Rio.
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
++The above copyright notice and this permission notice shall be included
++in all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ===============================================================================
+ (end of COPYRIGHT)
diff --cc Makefile
+++ b/Makefile
@@@ -40,8 -42,8 +40,8 @@@ PLATS= aix bsd c89 freebsd generic linu
  
  # What to install.
  TO_BIN= lua luac
--TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp
--TO_LIB= liblua.a liblua.so.$(V)
++TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp
++TO_LIB= liblua.a liblua.so.$V
  TO_MAN= lua.1 luac.1
  
  # Lua version and release.
@@@ -61,7 -62,7 +61,7 @@@ install: dumm
        cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD)
        cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
        cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
--      ln -s liblua.so.$(V) $(INSTALL_LIB)/liblua.so
++      ln -s liblua.so.$V $(INSTALL_LIB)/liblua.so
        cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
        cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
  
@@@ -1,5 -1,5 +1,6 @@@
  Name:           lua
--Version:        5.1.4
++Version:        5.3.3
++%define major_version 5.3
  Release:        0
  License:        MIT
  Summary:        Small Embeddable Language with Simple Procedural Syntax
@@@ -8,11 -8,11 +9,11 @@@ Group:          Base/Librarie
  Source:         %{name}-%{version}.tar.gz
  Source1:        macros.lua
  Source2:        baselibs.conf
--Source1001:   lua.manifest
--%define major_version 5.1
++Source1001:     lua.manifest
  BuildRequires:  pkg-config
  BuildRequires:  readline-devel
  
++
  %description
  Lua is a programming language originally designed for extending
  applications, but also frequently used as a general-purpose,
@@@ -56,47 -56,47 +57,41 @@@ scripting, and rapid prototyping. Lua i
  of C functions, written in ANSI C, and the implementation goals are
  simplicity, efficiency, portability, and low embedding cost.
  
--%package doc
--Summary:        Small Embeddable Language with Simple Procedural Syntax
--Group:          Documentation
--BuildArch:      noarch
--
--%description doc
--Lua is a programming language originally designed for extending
--applications, but also frequently used as a general-purpose,
--stand-alone language.
--
--Lua combines simple procedural syntax (similar to Pascal) with powerful
--data description constructs based on associative arrays and extensible
--semantics. Lua is dynamically typed, interpreted from byte codes, and
--has automatic memory management, making it ideal for configuration,
--scripting, and rapid prototyping. Lua is implemented as a small library
--of C functions, written in ANSI C, and the implementation goals are
--simplicity, efficiency, portability, and low embedding cost.
--
  %prep
  %setup -q -n lua-%{version}
  cp %{SOURCE1001} .
  
  %build
  export LDFLAGS+=" -Wl,-E -ldl -lreadline -lhistory -lncurses"
--sed -i 's:LUA_ROOT2 "LIBDIR/lua/%{major_version}/":LUA_ROOT2 \"%{_lib}/lua/%{major_version}/":' src/luaconf.h
++sed -i -e "s@/usr/local/@/usr/@g" src/luaconf.h
  make %{?_smp_mflags} -C src CC="%{__cc}" MYCFLAGS="%{optflags} -fPIC -DLUA_USE_LINUX" MYLIBS="$LDFLAGS" V=%{major_version} all
  
  %install
  make install INSTALL_TOP="%{buildroot}%{_prefix}" INSTALL_LIB="%{buildroot}%{_libdir}" INSTALL_CMOD=%{buildroot}%{_libdir}/lua/%{major_version} INSTALL_MAN="%{buildroot}%{_mandir}/man1"
--install -D -m644 etc/lua.pc %{buildroot}%{_libdir}/pkgconfig/lua.pc
--for file in lua luac ; do
--    mv "%{buildroot}%{_bindir}/${file}"        "%{buildroot}%{_bindir}/${file}%{major_version}"
--    mv "%{buildroot}%{_mandir}/man1/${file}.1" "%{buildroot}%{_mandir}/man1/${file}%{major_version}.1"
--done
++
++install -D -m 644 %{SOURCE1} %{buildroot}%{_sysconfdir}/rpm/macros.lua
++
++# create pkg-config file
++cat > lua.pc <<-EOF
++prefix=%{_prefix}
++exec_prefix=%{_prefix}
++libdir=%{_libdir}
++includedir=%{_prefix}}/include
++
++Name: Lua
++Description: An Extensible Extension Language
++Version: %{version}
++Libs: -llua -lm
++Cflags:
++EOF
++
  install -d -m 0755 %{buildroot}%{_libdir}/lua/%{major_version}
  install -d -m 0755 %{buildroot}%{_datadir}/lua/%{major_version}
--install -D -m644 %{SOURCE1} %{buildroot}%{_sysconfdir}/rpm/macros.lua
++install -D -m 644 lua.pc %{buildroot}/%{_libdir}/pkgconfig/lua.pc
  
  chmod +x %{buildroot}/%{_libdir}/liblua.so.%{major_version}
  
--ln -s lua%{major_version} %{buildroot}%{_bindir}/lua
++%remove_docs
  
  %post -n liblua -p /sbin/ldconfig
  
  %files
  %manifest %{name}.manifest
  %defattr(-,root,root)
--%{_mandir}/man1/lua%{major_version}.1*
--%{_mandir}/man1/luac%{major_version}.1*
  %{_bindir}/lua
--%{_bindir}/lua%{major_version}
--%{_bindir}/luac%{major_version}
++%{_bindir}/luac
  %dir %{_libdir}/lua
  %dir %{_libdir}/lua/%{major_version}
  %dir %{_datadir}/lua
  %files devel
  %manifest %{name}.manifest
  %defattr(-,root,root)
++%config %{_sysconfdir}/rpm/macros.lua
  %{_includedir}/lauxlib.h
  %{_includedir}/lua.h
  %{_includedir}/lua.hpp
  %{_includedir}/luaconf.h
  %{_includedir}/lualib.h
--%{_libdir}/pkgconfig/lua.pc
  %{_libdir}/liblua.a
  %{_libdir}/liblua.so
--
--%files doc
--%manifest %{name}.manifest
--%defattr(-,root,root)
--%doc doc/*
++%{_libdir}/pkgconfig/lua.pc
  
  %changelog
++
diff --cc src/Makefile
@@@ -22,27 -17,26 +22,28 @@@ SYSLIBS
  MYCFLAGS=
  MYLDFLAGS=
  MYLIBS=
 +MYOBJS=
  
 -# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
 +# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
  
 -PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
 +PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
  
  LUA_A=        liblua.a
--LUA_SO=       liblua.so
--CORE_O=       lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
--      lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o  \
--      lundump.o lvm.o lzio.o
--LIB_O=        lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
--      lstrlib.o loadlib.o linit.o
++LUA_SO= liblua.so
++CORE_O=       lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
++      lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
++      ltm.o lundump.o lvm.o lzio.o
++LIB_O=        lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
++      lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
++BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
  
  LUA_T=        lua
  LUA_O=        lua.o
  
  LUAC_T=       luac
 -LUAC_O=       luac.o print.o
 +LUAC_O=       luac.o
  
--ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
++ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
  ALL_T= $(LUA_SO) $(LUA_A) $(LUA_T) $(LUAC_T)
  ALL_A= $(LUA_A)
  
@@@ -55,42 -48,42 +56,42 @@@ o: $(ALL_O
  
  a:    $(ALL_A)
  
--# shared libraries (for Linux)
++# shared libraries (for linux)
  $(LUA_SO): $(CORE_O) $(LIB_O)
--      $(CC) -o $(LUA_SO).$V -shared -Wl,-soname,$(LUA_SO).$V $(CORE_O) $(LIB_O) -lm -ldl
--      ln -fs $(LUA_SO).$(V) $(LUA_SO)
++      $(CC) $(MYCFLAGS) -o $(LUA_SO).$V -shared -Wl,-soname,$(LUA_SO).$V $(CORE_O) $(LIB_O) -lm -ldl
++      ln -sf $(LUA_SO).$V $(LUA_SO)
  
--$(LUA_A): $(CORE_O) $(LIB_O)
--      $(AR) $@ $?
++$(LUA_A): $(BASE_O)
++      $(AR) $@ $(BASE_O)
        $(RANLIB) $@
  
--$(LUA_T): $(LUA_O) $(LUA_A)
--      $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) -L. -llua $(LIBS)
++$(LUA_T): $(LUA_O) $(LUA_SO)
++      $(CC) $(MYCFLAGS) -o $@ $(MYLDFLAGS) $(LUA_O) -L. -llua $(LIBS)
  
--$(LUAC_T): $(LUAC_O) $(LUA_A)
--      $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) -L. -llua $(LIBS)
++$(LUAC_T): $(LUAC_O) $(LUA_SO)
++      $(CC) $(MYCFLAGS) -o $@ $(MYLDFLAGS) $(LUAC_O) -L. -llua $(LIBS)
  
  clean:
        $(RM) $(ALL_T) $(ALL_O)
  
  depend:
-       @$(CC) $(CFLAGS) -MM l*.c
 -      @$(CC) $(CFLAGS) -MM l*.c print.c
++      @$(CC) $(MYCFLAGS) -MM l*.c@$(CC) $(MYCFLAGS) -MM l*.c
  
  echo:
 -      @echo "PLAT = $(PLAT)"
 -      @echo "CC = $(CC)"
 -      @echo "CFLAGS = $(CFLAGS)"
 -      @echo "AR = $(AR)"
 -      @echo "RANLIB = $(RANLIB)"
 -      @echo "RM = $(RM)"
 -      @echo "MYCFLAGS = $(MYCFLAGS)"
 -      @echo "MYLDFLAGS = $(MYLDFLAGS)"
 -      @echo "MYLIBS = $(MYLIBS)"
 -
 -# convenience targets for popular platforms
 +      @echo "PLAT= $(PLAT)"
 +      @echo "CC= $(CC)"
 +      @echo "CFLAGS= $(CFLAGS)"
 +      @echo "LDFLAGS= $(SYSLDFLAGS)"
 +      @echo "LIBS= $(LIBS)"
 +      @echo "AR= $(AR)"
 +      @echo "RANLIB= $(RANLIB)"
 +      @echo "RM= $(RM)"
 +
 +# Convenience targets for popular platforms
 +ALL= all
  
  none:
 -      @echo "Please choose a platform:"
 +      @echo "Please do 'make PLATFORM' where PLATFORM is one of these:"
        @echo "   $(PLATS)"
  
  aix:
diff --cc src/lcode.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
--** $Id: lcode.c,v 2.25.1.4 2009/06/15 14:12:25 roberto Exp $
++** $Id: lcode.c,v 2.109 2016/05/13 19:09:21 roberto Exp $
  ** Code generator for Lua
  ** See Copyright Notice in lua.h
  */
@@@ -851,32 -536,28 +851,24 @@@ static int jumponcond (FuncState *fs, e
  }
  
  
 +/*
 +** Emit code to go through if 'e' is true, jump otherwise.
 +*/
  void luaK_goiftrue (FuncState *fs, expdesc *e) {
 -  int pc;  /* pc of last jump */
 +  int pc;  /* pc of new jump */
    luaK_dischargevars(fs, e);
    switch (e->k) {
 -    case VK: case VKNUM: case VTRUE: {
 -      pc = NO_JUMP;  /* always true; do nothing */
 +    case VJMP: {  /* condition? */
 +      negatecondition(fs, e);  /* jump when it is false */
 +      pc = e->u.info;  /* save jump position */
        break;
      }
--    case VJMP: {
--      invertjump(fs, e);
--      pc = e->u.s.info;
++    case VK: case VKFLT: case VKINT: case VTRUE: {
++      pc = NO_JUMP;  /* always true; do nothing */
        break;
      }
--    case VFALSE: {
--      if (!hasjumps(e)) {
--        pc = luaK_jump(fs);  /* always jump */
--        break;
--      }
--      /* else go through */
--    }
      default: {
 -      pc = jumponcond(fs, e, 0);
 +      pc = jumponcond(fs, e, 0);  /* jump when false */
        break;
      }
    }
  }
  
  
 -static void luaK_goiffalse (FuncState *fs, expdesc *e) {
 -  int pc;  /* pc of last jump */
 +/*
 +** Emit code to go through if 'e' is false, jump otherwise.
 +*/
 +void luaK_goiffalse (FuncState *fs, expdesc *e) {
 +  int pc;  /* pc of new jump */
    luaK_dischargevars(fs, e);
    switch (e->k) {
--    case VNIL: case VFALSE: {
--      pc = NO_JUMP;  /* always false; do nothing */
--      break;
--    }
      case VJMP: {
--      pc = e->u.s.info;
++      pc = e->u.info;  /* already jump if true */
        break;
      }
--    case VTRUE: {
--      if (!hasjumps(e)) {
--        pc = luaK_jump(fs);  /* always jump */
--        break;
--      }
--      /* else go through */
++    case VNIL: case VFALSE: {
++      pc = NO_JUMP;  /* always false; do nothing */
++      break;
      }
      default: {
 -      pc = jumponcond(fs, e, 1);
 +      pc = jumponcond(fs, e, 1);  /* jump if true */
        break;
      }
    }
diff --cc src/ldblib.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
--** $Id: ldblib.c,v 1.104.1.4 2009/08/04 18:50:18 roberto Exp $
++** $Id: ldblib.c,v 1.151 2015/11/23 11:29:43 roberto Exp $
  ** Interface from Lua to its debug API
  ** See Copyright Notice in lua.h
  */
@@@ -63,9 -44,9 +63,11 @@@ static int db_setmetatable (lua_State *
  }
  
  
--static int db_getfenv (lua_State *L) {
--  luaL_checkany(L, 1);
--  lua_getfenv(L, 1);
++static int db_getuservalue (lua_State *L) {
++  if (lua_type(L, 1) != LUA_TUSERDATA)
++    lua_pushnil(L);
++  else
++    lua_getuservalue(L, 1);
    return 1;
  }
  
diff --cc src/liolib.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
--** $Id: liolib.c,v 2.73.1.4 2010/05/14 15:33:51 roberto Exp $
++** $Id: liolib.c,v 2.149 2016/05/02 14:03:19 roberto Exp $
  ** Standard I/O (and system) library
  ** See Copyright Notice in lua.h
  */
@@@ -374,37 -270,15 +374,93 @@@ static int io_lines (lua_State *L) 
  */
  
  
 -static int read_number (lua_State *L, FILE *f) {
 -  lua_Number d;
 -  if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
 -    lua_pushnumber(L, d);
 -    return 1;
 +/* maximum length of a numeral */
 +#if !defined (L_MAXLENNUM)
 +#define L_MAXLENNUM     200
 +#endif
 +
 +
 +/* auxiliary structure used by 'read_number' */
 +typedef struct {
 +  FILE *f;  /* file being read */
 +  int c;  /* current character (look ahead) */
 +  int n;  /* number of elements in buffer 'buff' */
 +  char buff[L_MAXLENNUM + 1];  /* +1 for ending '\0' */
 +} RN;
 +
 +
 +/*
 +** Add current char to buffer (if not out of space) and read next one
 +*/
 +static int nextc (RN *rn) {
 +  if (rn->n >= L_MAXLENNUM) {  /* buffer overflow? */
 +    rn->buff[0] = '\0';  /* invalidate result */
 +    return 0;  /* fail */
    }
    else {
 -    lua_pushnil(L);  /* "result" to be removed */
 -    return 0;  /* read fails */
 +    rn->buff[rn->n++] = rn->c;  /* save current char */
 +    rn->c = l_getc(rn->f);  /* read next one */
 +    return 1;
 +  }
-   else {
-     lua_pushnil(L);  /* "result" to be removed */
-     return 0;  /* read fails */
++}
++
++
++/*
++** Accept current char if it is in 'set' (of size 2)
++*/
++static int test2 (RN *rn, const char *set) {
++  if (rn->c == set[0] || rn->c == set[1])
++    return nextc(rn);
++  else return 0;
++}
++
++
++/*
++** Read a sequence of (hex)digits
++*/
++static int readdigits (RN *rn, int hex) {
++  int count = 0;
++  while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn))
++    count++;
++  return count;
++}
++
++
++/*
++** Read a number: first reads a valid prefix of a numeral into a buffer.
++** Then it calls 'lua_stringtonumber' to check whether the format is
++** correct and to convert it to a Lua number
++*/
++static int read_number (lua_State *L, FILE *f) {
++  RN rn;
++  int count = 0;
++  int hex = 0;
++  char decp[2];
++  rn.f = f; rn.n = 0;
++  decp[0] = lua_getlocaledecpoint();  /* get decimal point from locale */
++  decp[1] = '.';  /* always accept a dot */
++  l_lockfile(rn.f);
++  do { rn.c = l_getc(rn.f); } while (isspace(rn.c));  /* skip spaces */
++  test2(&rn, "-+");  /* optional signal */
++  if (test2(&rn, "00")) {
++    if (test2(&rn, "xX")) hex = 1;  /* numeral is hexadecimal */
++    else count = 1;  /* count initial '0' as a valid digit */
++  }
++  count += readdigits(&rn, hex);  /* integral part */
++  if (test2(&rn, decp))  /* decimal point? */
++    count += readdigits(&rn, hex);  /* fractional part */
++  if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) {  /* exponent mark? */
++    test2(&rn, "-+");  /* exponent signal */
++    readdigits(&rn, 0);  /* exponent digits */
++  }
++  ungetc(rn.c, rn.f);  /* unread look-ahead char */
++  l_unlockfile(rn.f);
++  rn.buff[rn.n] = '\0';  /* finish string */
++  if (lua_stringtonumber(L, rn.buff))  /* is this a valid number? */
++    return 1;  /* ok */
++  else {  /* invalid format */
++   lua_pushnil(L);  /* "result" to be removed */
++   return 0;  /* read fails */
    }
  }
  
diff --cc src/llex.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
--** $Id: llex.c,v 2.20.1.2 2009/11/23 14:58:22 roberto Exp $
++** $Id: llex.c,v 2.96 2016/05/02 14:02:12 roberto Exp $
  ** Lexical Analyzer
  ** See Copyright Notice in lua.h
  */
@@@ -119,19 -114,14 +119,27 @@@ l_noret luaX_syntaxerror (LexState *ls
  }
  
  
 +/*
 +** creates a new string and anchors it in scanner's table so that
 +** it will not be collected until the end of the compilation
 +** (by that time it should be anchored somewhere)
 +*/
  TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
    lua_State *L = ls->L;
--  TString *ts = luaS_newlstr(L, str, l);
--  TValue *o = luaH_setstr(L, ls->fs->h, ts);  /* entry for `str' */
--  if (ttisnil(o)) {
--    setbvalue(o, 1);  /* make sure `str' will not be collected */
++  TValue *o;  /* entry for 'str' */
++  TString *ts = luaS_newlstr(L, str, l);  /* create new string */
++  setsvalue2s(L, L->top++, ts);  /* temporarily anchor it in stack */
++  o = luaH_set(L, ls->h, L->top - 1);
++  if (ttisnil(o)) {  /* not in use yet? */
++    /* boolean value does not need GC barrier;
++       table has no metatable, so it does not need to invalidate cache */
++    setbvalue(o, 1);  /* t[string] = true */
      luaC_checkGC(L);
    }
++  else {  /* string already present */
++    ts = tsvalue(keyfromval(o));  /* re-use value previously stored */
++  }
++  L->top--;  /* remove string from stack */
    return ts;
  }
  
diff --cc src/loadlib.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
--** $Id: loadlib.c,v 1.52.1.4 2009/09/09 13:17:16 roberto Exp $
++** $Id: loadlib.c,v 1.127 2015/11/23 11:30:45 roberto Exp $
  ** Dynamic library loader for Lua
  ** See Copyright Notice in lua.h
  **
@@@ -726,73 -620,47 +726,62 @@@ static const luaL_Reg ll_funcs[] = 
  };
  
  
 -static const lua_CFunction loaders[] =
 -  {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
 -
 -
 -LUALIB_API int luaopen_package (lua_State *L) {
 +static void createsearcherstable (lua_State *L) {
 +  static const lua_CFunction searchers[] =
 +    {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
    int i;
--  /* create new type _LOADLIB */
--  luaL_newmetatable(L, "_LOADLIB");
--  lua_pushcfunction(L, gctm);
--  lua_setfield(L, -2, "__gc");
--  /* create `package' table */
--  luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
--#if defined(LUA_COMPAT_LOADLIB) 
--  lua_getfield(L, -1, "loadlib");
--  lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
--#endif
--  lua_pushvalue(L, -1);
--  lua_replace(L, LUA_ENVIRONINDEX);
--  /* create `loaders' table */
--  lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0);
--  /* fill it with pre-defined loaders */
--  for (i=0; loaders[i] != NULL; i++) {
--    lua_pushcfunction(L, loaders[i]);
++  /* create 'searchers' table */
++  lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
++  /* fill it with predefined searchers */
++  for (i=0; searchers[i] != NULL; i++) {
++    lua_pushvalue(L, -2);  /* set 'package' as upvalue for all searchers */
++    lua_pushcclosure(L, searchers[i], 1);
      lua_rawseti(L, -2, i+1);
    }
 -  lua_setfield(L, -2, "loaders");  /* put it in field `loaders' */
 -  setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT);  /* set field `path' */
 -  setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
 +#if defined(LUA_COMPAT_LOADERS)
 +  lua_pushvalue(L, -1);  /* make a copy of 'searchers' table */
 +  lua_setfield(L, -3, "loaders");  /* put it in field 'loaders' */
 +#endif
 +  lua_setfield(L, -2, "searchers");  /* put it in field 'searchers' */
 +}
 +
 +
 +/*
 +** create table CLIBS to keep track of loaded C libraries,
 +** setting a finalizer to close all libraries when closing state.
 +*/
 +static void createclibstable (lua_State *L) {
 +  lua_newtable(L);  /* create CLIBS table */
 +  lua_createtable(L, 0, 1);  /* create metatable for CLIBS */
 +  lua_pushcfunction(L, gctm);
 +  lua_setfield(L, -2, "__gc");  /* set finalizer for CLIBS table */
 +  lua_setmetatable(L, -2);
 +  lua_rawsetp(L, LUA_REGISTRYINDEX, &CLIBS);  /* set CLIBS table in registry */
 +}
 +
 +
 +LUAMOD_API int luaopen_package (lua_State *L) {
 +  createclibstable(L);
 +  luaL_newlib(L, pk_funcs);  /* create 'package' table */
 +  createsearcherstable(L);
 +  /* set field 'path' */
 +  setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
 +  /* set field 'cpath' */
 +  setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
    /* store config information */
 -  lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
 -                     LUA_EXECDIR "\n" LUA_IGMARK);
 +  lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
 +                     LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
    lua_setfield(L, -2, "config");
 -  /* set field `loaded' */
 -  luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
 +  /* set field 'loaded' */
 +  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
    lua_setfield(L, -2, "loaded");
 -  /* set field `preload' */
 -  lua_newtable(L);
 +  /* set field 'preload' */
 +  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
    lua_setfield(L, -2, "preload");
 -  lua_pushvalue(L, LUA_GLOBALSINDEX);
 -  luaL_register(L, NULL, ll_funcs);  /* open lib into global table */
 -  lua_pop(L, 1);
 +  lua_pushglobaltable(L);
 +  lua_pushvalue(L, -2);  /* set 'package' as upvalue for next lib */
 +  luaL_setfuncs(L, ll_funcs, 1);  /* open lib into global table */
 +  lua_pop(L, 1);  /* pop global table */
    return 1;  /* return 'package' table */
  }
  
diff --cc src/lopcodes.h
@@@ -276,7 -249,7 +276,7 @@@ enum OpArgMask 
    OpArgK   /* argument is a constant or register/constant */
  };
  
- LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES];
 -LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
++LUA_API const lu_byte luaP_opmodes[NUM_OPCODES];
  
  #define getOpMode(m)  (cast(enum OpMode, luaP_opmodes[m] & 3))
  #define getBMode(m)   (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
  #define testTMode(m)  (luaP_opmodes[m] & (1 << 7))
  
  
- LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1];  /* opcode names */
 -LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1];  /* opcode names */
++LUA_API const char *const luaP_opnames[NUM_OPCODES+1];  /* opcode names */
  
  
  /* number of list items to accumulate before a SETLIST instruction */
diff --cc src/lstrlib.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
--** $Id: lstrlib.c,v 1.132.1.5 2010/05/14 15:34:19 roberto Exp $
++** $Id: lstrlib.c,v 1.251 2016/05/20 14:13:21 roberto Exp $
  ** Standard library for string operations and pattern-matching
  ** See Copyright Notice in lua.h
  */
@@@ -1026,8 -767,8 +1026,9 @@@ static int str_format (lua_State *L) 
      else if (*++strfrmt == L_ESC)
        luaL_addchar(&b, *strfrmt++);  /* %% */
      else { /* format item */
--      char form[MAX_FORMAT];  /* to store the format (`%...') */
--      char buff[MAX_ITEM];  /* to store the formatted item */
++      char form[MAX_FORMAT];  /* to store the format ('%...') */
++      char *buff = luaL_prepbuffsize(&b, MAX_ITEM);  /* to put formatted item */
++      int nb = 0;  /* number of bytes in added item */
        if (++arg > top)
          luaL_argerror(L, arg, "no value");
        strfrmt = scanformat(L, strfrmt, form);
diff --cc src/luaconf.h
  */
  #define LUA_LDIR      "!\\lua\\"
  #define LUA_CDIR      "!\\"
 +#define LUA_SHRDIR    "!\\..\\share\\lua\\" LUA_VDIR "\\"
  #define LUA_PATH_DEFAULT  \
 -              ".\\?.lua;"  LUA_LDIR"?.lua;"  LUA_LDIR"?\\init.lua;" \
 -                           LUA_CDIR"?.lua;"  LUA_CDIR"?\\init.lua"
 +              LUA_LDIR"?.lua;"  LUA_LDIR"?\\init.lua;" \
 +              LUA_CDIR"?.lua;"  LUA_CDIR"?\\init.lua;" \
 +              LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \
 +              ".\\?.lua;" ".\\?\\init.lua"
  #define LUA_CPATH_DEFAULT \
 -      ".\\?.dll;"  LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
 +              LUA_CDIR"?.dll;" \
 +              LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \
 +              LUA_CDIR"loadall.dll;" ".\\?.dll"
 +
 +#else                 /* }{ */
  
 -#else
  #define LUA_ROOT      "/usr/local/"
--#define LUA_ROOT2     "/usr/"
--#define LUA_LDIR      LUA_ROOT "share/lua/5.1/"
--#define LUA_LDIR2     LUA_ROOT2 "share/lua/5.1/"
--#define LUA_CDIR      LUA_ROOT "lib/lua/5.1/"
--#define LUA_CDIR2     LUA_ROOT2 "LIBDIR/lua/5.1/"
++#define LUA_LDIR      LUA_ROOT "share/lua/" LUA_VDIR "/"
++#define LUA_CDIR      LUA_ROOT "lib/lua/" LUA_VDIR "/"
  #define LUA_PATH_DEFAULT  \
--              "./?.lua;"  LUA_LDIR"?.lua;"  LUA_LDIR"?/init.lua;" \
--                          LUA_CDIR"?.lua;"  LUA_CDIR"?/init.lua;" \
--                          LUA_LDIR2"?.lua;"  LUA_LDIR2"?/init.lua"
++              LUA_LDIR"?.lua;"  LUA_LDIR"?/init.lua;" \
++              LUA_CDIR"?.lua;"  LUA_CDIR"?/init.lua;" \
++              "./?.lua;" "./?/init.lua"
  #define LUA_CPATH_DEFAULT \
--      "./?.so;" LUA_CDIR"?.so;" LUA_CDIR2"?.so;" LUA_CDIR"loadall.so"
--#endif
++              LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
++#endif                        /* } */
  
  
  /*
  
  /*
  @@ LUAI_FUNC is a mark for all extern functions that are not to be
 -@* exported to outside modules.
 -@@ LUAI_DATA is a mark for all extern (const) variables that are not to
 -@* be exported to outside modules.
 +** exported to outside modules.
 +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
 +** that are not to be exported to outside modules (LUAI_DDEF for
 +** definitions and LUAI_DDEC for declarations).
  ** CHANGE them if you need to mark them in some special way. Elf/gcc
  ** (versions 3.2 and later) mark them as "hidden" to optimize access
--** when Lua is compiled as a shared library.
 -*/
 -#if defined(luaall_c)
 -#define LUAI_FUNC     static
 -#define LUAI_DATA     /* empty */
 -
 -#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
 -      defined(__ELF__)
++** when Lua is compiled as a shared library. Not all elf targets support
++** this attribute. Unfortunately, gcc does not offer a way to check
++** whether the target offers that support, and those without support
++** give a warning about it. To avoid these warnings, change to the
++** default definition.
 +*/
- #if defined(luaall_c)
- #define LUAI_FUNC     static
- #define LUAI_DATA     /* empty */
- #elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
-       defined(__ELF__)
- #define LUAI_FUNC     extern
- #define LUAI_DATA     LUAI_FUNC
- #else
++#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
++    defined(__ELF__)          /* { */
++#define LUAI_FUNC     __attribute__((visibility("hidden"))) extern
++#else                         /* }{ */
  #define LUAI_FUNC     extern
 -#define LUAI_DATA     LUAI_FUNC
 -
 -#else
 -#define LUAI_FUNC     extern
 -#define LUAI_DATA     extern
 -#endif
 -
 +#endif                                /* } */
  
 +#define LUAI_DDEC     LUAI_FUNC
 +#define LUAI_DDEF     /* empty */
  
 -/*
 -@@ LUA_QL describes how error messages quote program elements.
 -** CHANGE it if you want a different appearance.
 -*/
 -#define LUA_QL(x)     "'" x "'"
 -#define LUA_QS                LUA_QL("%s")
 -
 -
 -/*
 -@@ LUA_IDSIZE gives the maximum size for the description of the source
 -@* of a function in debug information.
 -** CHANGE it if you want a different size.
 -*/
 -#define LUA_IDSIZE    60
 +/* }================================================================== */
  
  
  /*
diff --cc src/lundump.h
  #include "lobject.h"
  #include "lzio.h"
  
 -/* load one chunk; from lundump.c */
 -LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
 -
 -/* make header; from lundump.c */
 -LUAI_FUNC void luaU_header (char* h);
  
 -/* dump one chunk; from ldump.c */
 -LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
 +/* data to catch conversion errors */
 +#define LUAC_DATA     "\x19\x93\r\n\x1a\n"
  
 -#ifdef luac_c
 -/* print one chunk; from print.c */
 -LUAI_FUNC void luaU_print (const Proto* f, int full);
 -#endif
 +#define LUAC_INT      0x5678
 +#define LUAC_NUM      cast_num(370.5)
  
 -/* for header of binary files -- this is Lua 5.1 */
 -#define LUAC_VERSION          0x51
 +#define MYINT(s)      (s[0]-'0')
 +#define LUAC_VERSION  (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR))
 +#define LUAC_FORMAT   0       /* this is the official format */
  
 -/* for header of binary files -- this is the official format */
 -#define LUAC_FORMAT           0
 +/* load one chunk; from lundump.c */
 +LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name);
  
 -/* size of header of binary files */
 -#define LUAC_HEADERSIZE               12
 +/* dump one chunk; from ldump.c */
- LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
++LUA_API int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
 +                         void* data, int strip);
  
  #endif
diff --cc src/lvm.c
+++ b/src/lvm.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
--** $Id: lvm.c,v 2.63.1.4 2009/07/01 21:10:33 roberto Exp $
++** $Id: lvm.c,v 2.268 2016/02/05 19:59:14 roberto Exp $
  ** Lua virtual machine
  ** See Copyright Notice in lua.h
  */
@@@ -193,40 -131,33 +193,48 @@@ void luaV_finishget (lua_State *L, cons
  }
  
  
--void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
--  int loop;
--  TValue temp;
++/*
++** Finish a table assignment 't[key] = val'.
++** If 'slot' is NULL, 't' is not a table.  Otherwise, 'slot' points
++** to the entry 't[key]', or to 'luaO_nilobject' if there is no such
++** entry.  (The value at 'slot' must be nil, otherwise 'luaV_fastset'
++** would have done the job.)
++*/
++void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
++                     StkId val, const TValue *slot) {
++  int loop;  /* counter to avoid infinite loops */
    for (loop = 0; loop < MAXTAGLOOP; loop++) {
 -    const TValue *tm;
 -    if (ttistable(t)) {  /* `t' is a table? */
 -      Table *h = hvalue(t);
 -      TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
 -      if (!ttisnil(oldval) ||  /* result is no nil? */
 -          (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
 -        setobj2t(L, oldval, val);
 -        luaC_barriert(L, h, val);
 +    const TValue *tm;  /* '__newindex' metamethod */
 +    if (slot != NULL) {  /* is 't' a table? */
 +      Table *h = hvalue(t);  /* save 't' table */
 +      lua_assert(ttisnil(slot));  /* old value must be nil */
 +      tm = fasttm(L, h->metatable, TM_NEWINDEX);  /* get metamethod */
 +      if (tm == NULL) {  /* no metamethod? */
 +        if (slot == luaO_nilobject)  /* no previous entry? */
 +          slot = luaH_newkey(L, h, key);  /* create one */
 +        /* no metamethod and (now) there is an entry with given key */
 +        setobj2t(L, cast(TValue *, slot), val);  /* set its new value */
 +        invalidateTMcache(h);
 +        luaC_barrierback(L, h, val);
          return;
        }
 -      /* else will try the tag method */
 +      /* else will try the metamethod */
 +    }
 +    else {  /* not a table; check metamethod */
 +      if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
 +        luaG_typeerror(L, t, "index");
      }
 -    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
 -      luaG_typeerror(L, t, "index");
 +    /* try the metamethod */
      if (ttisfunction(tm)) {
 -      callTM(L, tm, t, key, val);
 +      luaT_callTM(L, tm, t, key, val, 0);
        return;
      }
--    /* else repeat with `tm' */
--    setobj(L, &temp, tm);  /* avoid pointing inside table (may rehash) */
--    t = &temp;
++    t = tm;  /* else repeat assignment over 'tm' */
++    if (luaV_fastset(L, t, key, slot, luaH_get, val))
++      return;  /* done */
++    /* else loop */
    }
 -  luaG_runerror(L, "loop in settable");
 +  luaG_runerror(L, "'__newindex' chain too long; possible loop");
  }