Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Import lua 5.3.5
Baptiste Daroussin committed 6 years ago
commit 4521cfbdea13076f2ac07795a91b1d27654d6e8d
parent fe61047
80 files changed +36970 -2
modified auto.def
@@ -308,7 +308,8 @@ make-template Makefile.autosetup Makefile
foreach dir [list external/expat external/blake2 external/picosat \
	external/linenoise external/libfetch external/sqlite \
	external compat libpkg libpkg/repo libpkg/repo/binary src \
-
	external/libucl external/libelf external/libmachista tests docs scripts] {
+
	external/libucl external/libelf external/libmachista tests docs \
+
	external/liblua scripts] {
	make-template $dir/Makefile.autosetup $dir/Makefile
}

modified external/Makefile.autosetup
@@ -1,3 +1,3 @@
include @builddir@/mk/defs.mk
-
DIRS=	expat blake2 picosat linenoise libfetch sqlite libucl @libabidir@
+
DIRS=	expat blake2 picosat linenoise libfetch sqlite libucl liblua @libabidir@
include $(MK)/dir.mk
added external/liblua/Makefile
@@ -0,0 +1,40 @@
+
include /usr/home/bapt/dev/pkg/mk/defs.mk
+

+
LIB=	lua
+
.PATH:	$(top_srcdir)/external/lua/src/
+

+
SRCS=	lapi.c \
+
	lcode.c \
+
	lctype.c \
+
	ldebug.c \
+
	ldo.c \
+
	ldump.c \
+
	lfunc.c \
+
	lgc.c \
+
	llex.c \
+
	lmem.c \
+
	lobject.c \
+
	lopcodes.c \
+
	lparser.c \
+
	lstate.c \
+
	lstring.c \
+
	ltable.c \
+
	ltm.c \
+
	lundump.c \
+
	lvm.c \
+
	lzio.c \
+
	lauxlib.c \
+
	lbaselib.c \
+
	lbitlib.c \
+
	lcorolib.c \
+
	ldblib.c \
+
	liolib.c \
+
	lmathlib.c \
+
	loslib.c \
+
	lstrlib.c \
+
	ltablib.c \
+
	lutf8lib.c \
+
	loadlib.c \
+
	linit.c
+

+
include $(MK)/static-lib.mk
added external/liblua/Makefile.autosetup
@@ -0,0 +1,40 @@
+
include @builddir@/mk/defs.mk
+

+
LIB=	lua
+
.PATH:	$(top_srcdir)/external/lua/src/
+

+
SRCS=	lapi.c \
+
	lcode.c \
+
	lctype.c \
+
	ldebug.c \
+
	ldo.c \
+
	ldump.c \
+
	lfunc.c \
+
	lgc.c \
+
	llex.c \
+
	lmem.c \
+
	lobject.c \
+
	lopcodes.c \
+
	lparser.c \
+
	lstate.c \
+
	lstring.c \
+
	ltable.c \
+
	ltm.c \
+
	lundump.c \
+
	lvm.c \
+
	lzio.c \
+
	lauxlib.c \
+
	lbaselib.c \
+
	lbitlib.c \
+
	lcorolib.c \
+
	ldblib.c \
+
	liolib.c \
+
	lmathlib.c \
+
	loslib.c \
+
	lstrlib.c \
+
	ltablib.c \
+
	lutf8lib.c \
+
	loadlib.c \
+
	linit.c
+

+
include $(MK)/static-lib.mk
added external/lua/Makefile
@@ -0,0 +1,114 @@
+
# Makefile for installing Lua
+
# See doc/readme.html for installation and customization instructions.
+

+
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
+

+
# Your platform. See PLATS for possible values.
+
PLAT= none
+

+
# Where to install. The installation starts in the src and doc directories,
+
# so take care if INSTALL_TOP is not an absolute path. See the local target.
+
# You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with
+
# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h.
+
INSTALL_TOP= /usr/local
+
INSTALL_BIN= $(INSTALL_TOP)/bin
+
INSTALL_INC= $(INSTALL_TOP)/include
+
INSTALL_LIB= $(INSTALL_TOP)/lib
+
INSTALL_MAN= $(INSTALL_TOP)/man/man1
+
INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V
+
INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V
+

+
# How to install. If your install program does not support "-p", then
+
# you may have to run ranlib on the installed liblua.a.
+
INSTALL= install -p
+
INSTALL_EXEC= $(INSTALL) -m 0755
+
INSTALL_DATA= $(INSTALL) -m 0644
+
#
+
# If you don't have "install" you can use "cp" instead.
+
# INSTALL= cp -p
+
# INSTALL_EXEC= $(INSTALL)
+
# INSTALL_DATA= $(INSTALL)
+

+
# Other utilities.
+
MKDIR= mkdir -p
+
RM= rm -f
+

+
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
+

+
# Convenience platforms targets.
+
PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
+

+
# What to install.
+
TO_BIN= lua luac
+
TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp
+
TO_LIB= liblua.a
+
TO_MAN= lua.1 luac.1
+

+
# Lua version and release.
+
V= 5.3
+
R= $V.4
+

+
# Targets start here.
+
all:	$(PLAT)
+

+
$(PLATS) clean:
+
	cd src && $(MAKE) $@
+

+
test:	dummy
+
	src/lua -v
+

+
install: dummy
+
	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)
+
	cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
+
	cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
+

+
uninstall:
+
	cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN)
+
	cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC)
+
	cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB)
+
	cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN)
+

+
local:
+
	$(MAKE) install INSTALL_TOP=../install
+

+
none:
+
	@echo "Please do 'make PLATFORM' where PLATFORM is one of these:"
+
	@echo "   $(PLATS)"
+
	@echo "See doc/readme.html for complete instructions."
+

+
# make may get confused with test/ and install/
+
dummy:
+

+
# echo config parameters
+
echo:
+
	@cd src && $(MAKE) -s echo
+
	@echo "PLAT= $(PLAT)"
+
	@echo "V= $V"
+
	@echo "R= $R"
+
	@echo "TO_BIN= $(TO_BIN)"
+
	@echo "TO_INC= $(TO_INC)"
+
	@echo "TO_LIB= $(TO_LIB)"
+
	@echo "TO_MAN= $(TO_MAN)"
+
	@echo "INSTALL_TOP= $(INSTALL_TOP)"
+
	@echo "INSTALL_BIN= $(INSTALL_BIN)"
+
	@echo "INSTALL_INC= $(INSTALL_INC)"
+
	@echo "INSTALL_LIB= $(INSTALL_LIB)"
+
	@echo "INSTALL_MAN= $(INSTALL_MAN)"
+
	@echo "INSTALL_LMOD= $(INSTALL_LMOD)"
+
	@echo "INSTALL_CMOD= $(INSTALL_CMOD)"
+
	@echo "INSTALL_EXEC= $(INSTALL_EXEC)"
+
	@echo "INSTALL_DATA= $(INSTALL_DATA)"
+

+
# echo pkg-config data
+
pc:
+
	@echo "version=$R"
+
	@echo "prefix=$(INSTALL_TOP)"
+
	@echo "libdir=$(INSTALL_LIB)"
+
	@echo "includedir=$(INSTALL_INC)"
+

+
# list targets that do not create files (but not all makes understand .PHONY)
+
.PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho
+

+
# (end of Makefile)
added external/lua/README
@@ -0,0 +1,6 @@
+

+
This is Lua 5.3.5, released on 26 Jun 2018.
+

+
For installation instructions, license details, and
+
further information about Lua, see doc/readme.html.
+

added external/lua/doc/contents.html
@@ -0,0 +1,619 @@
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
<HTML>
+
<HEAD>
+
<TITLE>Lua 5.3 Reference Manual - contents</TITLE>
+
<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
+
<LINK REL="stylesheet" TYPE="text/css" HREF="index.css">
+
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
+
</HEAD>
+

+
<BODY>
+

+
<H1>
+
<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
+
Lua 5.3 Reference Manual
+
</H1>
+

+
<P>
+
The reference manual is the official definition of the Lua language.
+
<BR>
+
For a complete introduction to Lua programming, see the book
+
<A HREF="http://www.lua.org/pil/">Programming in Lua</A>.
+

+
<DIV CLASS="menubar">
+
<A HREF="manual.html">start</A>
+
&middot;
+
<A HREF="#contents">contents</A>
+
&middot;
+
<A HREF="#index">index</A>
+
&middot;
+
<A HREF="http://www.lua.org/manual/">other versions</A>
+
</DIV>
+

+
<P>
+
<SMALL>
+
Copyright &copy; 2015&ndash;2018 Lua.org, PUC-Rio.
+
Freely available under the terms of the
+
<A HREF="http://www.lua.org/license.html">Lua license</A>.
+
</SMALL>
+

+
<H2><A NAME="contents">Contents</A></H2>
+
<UL CLASS="contents menubar">
+
<LI><A HREF="manual.html">1 &ndash; Introduction</A>
+
<P>
+
<LI><A HREF="manual.html#2">2 &ndash; Basic Concepts</A>
+
<UL>
+
<LI><A HREF="manual.html#2.1">2.1 &ndash; Values and Types</A>
+
<LI><A HREF="manual.html#2.2">2.2 &ndash; Environments and the Global Environment</A>
+
<LI><A HREF="manual.html#2.3">2.3 &ndash; Error Handling</A>
+
<LI><A HREF="manual.html#2.4">2.4 &ndash; Metatables and Metamethods</A>
+
<LI><A HREF="manual.html#2.5">2.5 &ndash; Garbage Collection</A>
+
<UL>
+
<LI><A HREF="manual.html#2.5.1">2.5.1 &ndash; Garbage-Collection Metamethods</A>
+
<LI><A HREF="manual.html#2.5.2">2.5.2 &ndash; Weak Tables</A>
+
</UL>
+
<LI><A HREF="manual.html#2.6">2.6 &ndash; Coroutines</A>
+
</UL>
+
<P>
+
<LI><A HREF="manual.html#3">3 &ndash; The Language</A>
+
<UL>
+
<LI><A HREF="manual.html#3.1">3.1 &ndash; Lexical Conventions</A>
+
<LI><A HREF="manual.html#3.2">3.2 &ndash; Variables</A>
+
<LI><A HREF="manual.html#3.3">3.3 &ndash; Statements</A>
+
<UL>
+
<LI><A HREF="manual.html#3.3.1">3.3.1 &ndash; Blocks</A>
+
<LI><A HREF="manual.html#3.3.2">3.3.2 &ndash; Chunks</A>
+
<LI><A HREF="manual.html#3.3.3">3.3.3 &ndash; Assignment</A>
+
<LI><A HREF="manual.html#3.3.4">3.3.4 &ndash; Control Structures</A>
+
<LI><A HREF="manual.html#3.3.5">3.3.5 &ndash; For Statement</A>
+
<LI><A HREF="manual.html#3.3.6">3.3.6 &ndash; Function Calls as Statements</A>
+
<LI><A HREF="manual.html#3.3.7">3.3.7 &ndash; Local Declarations</A>
+
</UL>
+
<LI><A HREF="manual.html#3.4">3.4 &ndash; Expressions</A>
+
<UL>
+
<LI><A HREF="manual.html#3.4.1">3.4.1 &ndash; Arithmetic Operators</A>
+
<LI><A HREF="manual.html#3.4.2">3.4.2 &ndash; Bitwise Operators</A>
+
<LI><A HREF="manual.html#3.4.3">3.4.3 &ndash; Coercions and Conversions</A>
+
<LI><A HREF="manual.html#3.4.4">3.4.4 &ndash; Relational Operators</A>
+
<LI><A HREF="manual.html#3.4.5">3.4.5 &ndash; Logical Operators</A>
+
<LI><A HREF="manual.html#3.4.6">3.4.6 &ndash; Concatenation</A>
+
<LI><A HREF="manual.html#3.4.7">3.4.7 &ndash; The Length Operator</A>
+
<LI><A HREF="manual.html#3.4.8">3.4.8 &ndash; Precedence</A>
+
<LI><A HREF="manual.html#3.4.9">3.4.9 &ndash; Table Constructors</A>
+
<LI><A HREF="manual.html#3.4.10">3.4.10 &ndash; Function Calls</A>
+
<LI><A HREF="manual.html#3.4.11">3.4.11 &ndash; Function Definitions</A>
+
</UL>
+
<LI><A HREF="manual.html#3.5">3.5 &ndash; Visibility Rules</A>
+
</UL>
+
<P>
+
<LI><A HREF="manual.html#4">4 &ndash; The Application Program Interface</A>
+
<UL>
+
<LI><A HREF="manual.html#4.1">4.1 &ndash; The Stack</A>
+
<LI><A HREF="manual.html#4.2">4.2 &ndash; Stack Size</A>
+
<LI><A HREF="manual.html#4.3">4.3 &ndash; Valid and Acceptable Indices</A>
+
<LI><A HREF="manual.html#4.4">4.4 &ndash; C Closures</A>
+
<LI><A HREF="manual.html#4.5">4.5 &ndash; Registry</A>
+
<LI><A HREF="manual.html#4.6">4.6 &ndash; Error Handling in C</A>
+
<LI><A HREF="manual.html#4.7">4.7 &ndash; Handling Yields in C</A>
+
<LI><A HREF="manual.html#4.8">4.8 &ndash; Functions and Types</A>
+
<LI><A HREF="manual.html#4.9">4.9 &ndash; The Debug Interface</A>
+
</UL>
+
<P>
+
<LI><A HREF="manual.html#5">5 &ndash; The Auxiliary Library</A>
+
<UL>
+
<LI><A HREF="manual.html#5.1">5.1 &ndash; Functions and Types</A>
+
</UL>
+
<P>
+
<LI><A HREF="manual.html#6">6 &ndash; Standard Libraries</A>
+
<UL>
+
<LI><A HREF="manual.html#6.1">6.1 &ndash; Basic Functions</A>
+
<LI><A HREF="manual.html#6.2">6.2 &ndash; Coroutine Manipulation</A>
+
<LI><A HREF="manual.html#6.3">6.3 &ndash; Modules</A>
+
<LI><A HREF="manual.html#6.4">6.4 &ndash; String Manipulation</A>
+
<UL>
+
<LI><A HREF="manual.html#6.4.1">6.4.1 &ndash; Patterns</A>
+
<LI><A HREF="manual.html#6.4.2">6.4.2 &ndash; Format Strings for Pack and Unpack</A>
+
</UL>
+
<LI><A HREF="manual.html#6.5">6.5 &ndash; UTF-8 Support</A>
+
<LI><A HREF="manual.html#6.6">6.6 &ndash; Table Manipulation</A>
+
<LI><A HREF="manual.html#6.7">6.7 &ndash; Mathematical Functions</A>
+
<LI><A HREF="manual.html#6.8">6.8 &ndash; Input and Output Facilities</A>
+
<LI><A HREF="manual.html#6.9">6.9 &ndash; Operating System Facilities</A>
+
<LI><A HREF="manual.html#6.10">6.10 &ndash; The Debug Library</A>
+
</UL>
+
<P>
+
<LI><A HREF="manual.html#7">7 &ndash; Lua Standalone</A>
+
<P>
+
<LI><A HREF="manual.html#8">8 &ndash; Incompatibilities with the Previous Version</A>
+
<UL>
+
<LI><A HREF="manual.html#8.1">8.1 &ndash; Changes in the Language</A>
+
<LI><A HREF="manual.html#8.2">8.2 &ndash; Changes in the Libraries</A>
+
<LI><A HREF="manual.html#8.3">8.3 &ndash; Changes in the API</A>
+
</UL>
+
<P>
+
<LI><A HREF="manual.html#9">9 &ndash; The Complete Syntax of Lua</A>
+
</UL>
+

+
<H2><A NAME="index">Index</A></H2>
+
<TABLE CLASS="menubar" WIDTH="100%">
+
<TR>
+
<TD>
+
<H3><A NAME="functions">Lua functions</A></H3>
+
<P>
+
<A HREF="manual.html#6.1">basic</A><BR>
+
<A HREF="manual.html#pdf-_G">_G</A><BR>
+
<A HREF="manual.html#pdf-_VERSION">_VERSION</A><BR>
+
<A HREF="manual.html#pdf-assert">assert</A><BR>
+
<A HREF="manual.html#pdf-collectgarbage">collectgarbage</A><BR>
+
<A HREF="manual.html#pdf-dofile">dofile</A><BR>
+
<A HREF="manual.html#pdf-error">error</A><BR>
+
<A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR>
+
<A HREF="manual.html#pdf-ipairs">ipairs</A><BR>
+
<A HREF="manual.html#pdf-load">load</A><BR>
+
<A HREF="manual.html#pdf-loadfile">loadfile</A><BR>
+
<A HREF="manual.html#pdf-next">next</A><BR>
+
<A HREF="manual.html#pdf-pairs">pairs</A><BR>
+
<A HREF="manual.html#pdf-pcall">pcall</A><BR>
+
<A HREF="manual.html#pdf-print">print</A><BR>
+
<A HREF="manual.html#pdf-rawequal">rawequal</A><BR>
+
<A HREF="manual.html#pdf-rawget">rawget</A><BR>
+
<A HREF="manual.html#pdf-rawlen">rawlen</A><BR>
+
<A HREF="manual.html#pdf-rawset">rawset</A><BR>
+
<A HREF="manual.html#pdf-require">require</A><BR>
+
<A HREF="manual.html#pdf-select">select</A><BR>
+
<A HREF="manual.html#pdf-setmetatable">setmetatable</A><BR>
+
<A HREF="manual.html#pdf-tonumber">tonumber</A><BR>
+
<A HREF="manual.html#pdf-tostring">tostring</A><BR>
+
<A HREF="manual.html#pdf-type">type</A><BR>
+
<A HREF="manual.html#pdf-xpcall">xpcall</A><BR>
+

+
<P>
+
<A HREF="manual.html#6.2">coroutine</A><BR>
+
<A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR>
+
<A HREF="manual.html#pdf-coroutine.isyieldable">coroutine.isyieldable</A><BR>
+
<A HREF="manual.html#pdf-coroutine.resume">coroutine.resume</A><BR>
+
<A HREF="manual.html#pdf-coroutine.running">coroutine.running</A><BR>
+
<A HREF="manual.html#pdf-coroutine.status">coroutine.status</A><BR>
+
<A HREF="manual.html#pdf-coroutine.wrap">coroutine.wrap</A><BR>
+
<A HREF="manual.html#pdf-coroutine.yield">coroutine.yield</A><BR>
+

+
<P>
+
<A HREF="manual.html#6.10">debug</A><BR>
+
<A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR>
+
<A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR>
+
<A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR>
+
<A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR>
+
<A HREF="manual.html#pdf-debug.getmetatable">debug.getmetatable</A><BR>
+
<A HREF="manual.html#pdf-debug.getregistry">debug.getregistry</A><BR>
+
<A HREF="manual.html#pdf-debug.getupvalue">debug.getupvalue</A><BR>
+
<A HREF="manual.html#pdf-debug.getuservalue">debug.getuservalue</A><BR>
+
<A HREF="manual.html#pdf-debug.sethook">debug.sethook</A><BR>
+
<A HREF="manual.html#pdf-debug.setlocal">debug.setlocal</A><BR>
+
<A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR>
+
<A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR>
+
<A HREF="manual.html#pdf-debug.setuservalue">debug.setuservalue</A><BR>
+
<A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR>
+
<A HREF="manual.html#pdf-debug.upvalueid">debug.upvalueid</A><BR>
+
<A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR>
+

+
<P>
+
<A HREF="manual.html#6.8">io</A><BR>
+
<A HREF="manual.html#pdf-io.close">io.close</A><BR>
+
<A HREF="manual.html#pdf-io.flush">io.flush</A><BR>
+
<A HREF="manual.html#pdf-io.input">io.input</A><BR>
+
<A HREF="manual.html#pdf-io.lines">io.lines</A><BR>
+
<A HREF="manual.html#pdf-io.open">io.open</A><BR>
+
<A HREF="manual.html#pdf-io.output">io.output</A><BR>
+
<A HREF="manual.html#pdf-io.popen">io.popen</A><BR>
+
<A HREF="manual.html#pdf-io.read">io.read</A><BR>
+
<A HREF="manual.html#pdf-io.stderr">io.stderr</A><BR>
+
<A HREF="manual.html#pdf-io.stdin">io.stdin</A><BR>
+
<A HREF="manual.html#pdf-io.stdout">io.stdout</A><BR>
+
<A HREF="manual.html#pdf-io.tmpfile">io.tmpfile</A><BR>
+
<A HREF="manual.html#pdf-io.type">io.type</A><BR>
+
<A HREF="manual.html#pdf-io.write">io.write</A><BR>
+

+
<A HREF="manual.html#pdf-file:close">file:close</A><BR>
+
<A HREF="manual.html#pdf-file:flush">file:flush</A><BR>
+
<A HREF="manual.html#pdf-file:lines">file:lines</A><BR>
+
<A HREF="manual.html#pdf-file:read">file:read</A><BR>
+
<A HREF="manual.html#pdf-file:seek">file:seek</A><BR>
+
<A HREF="manual.html#pdf-file:setvbuf">file:setvbuf</A><BR>
+
<A HREF="manual.html#pdf-file:write">file:write</A><BR>
+

+
</TD>
+
<TD>
+
<H3>&nbsp;</H3>
+
<P>
+
<A HREF="manual.html#6.7">math</A><BR>
+
<A HREF="manual.html#pdf-math.abs">math.abs</A><BR>
+
<A HREF="manual.html#pdf-math.acos">math.acos</A><BR>
+
<A HREF="manual.html#pdf-math.asin">math.asin</A><BR>
+
<A HREF="manual.html#pdf-math.atan">math.atan</A><BR>
+
<A HREF="manual.html#pdf-math.ceil">math.ceil</A><BR>
+
<A HREF="manual.html#pdf-math.cos">math.cos</A><BR>
+
<A HREF="manual.html#pdf-math.deg">math.deg</A><BR>
+
<A HREF="manual.html#pdf-math.exp">math.exp</A><BR>
+
<A HREF="manual.html#pdf-math.floor">math.floor</A><BR>
+
<A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR>
+
<A HREF="manual.html#pdf-math.huge">math.huge</A><BR>
+
<A HREF="manual.html#pdf-math.log">math.log</A><BR>
+
<A HREF="manual.html#pdf-math.max">math.max</A><BR>
+
<A HREF="manual.html#pdf-math.maxinteger">math.maxinteger</A><BR>
+
<A HREF="manual.html#pdf-math.min">math.min</A><BR>
+
<A HREF="manual.html#pdf-math.mininteger">math.mininteger</A><BR>
+
<A HREF="manual.html#pdf-math.modf">math.modf</A><BR>
+
<A HREF="manual.html#pdf-math.pi">math.pi</A><BR>
+
<A HREF="manual.html#pdf-math.rad">math.rad</A><BR>
+
<A HREF="manual.html#pdf-math.random">math.random</A><BR>
+
<A HREF="manual.html#pdf-math.randomseed">math.randomseed</A><BR>
+
<A HREF="manual.html#pdf-math.sin">math.sin</A><BR>
+
<A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR>
+
<A HREF="manual.html#pdf-math.tan">math.tan</A><BR>
+
<A HREF="manual.html#pdf-math.tointeger">math.tointeger</A><BR>
+
<A HREF="manual.html#pdf-math.type">math.type</A><BR>
+
<A HREF="manual.html#pdf-math.ult">math.ult</A><BR>
+

+
<P>
+
<A HREF="manual.html#6.9">os</A><BR>
+
<A HREF="manual.html#pdf-os.clock">os.clock</A><BR>
+
<A HREF="manual.html#pdf-os.date">os.date</A><BR>
+
<A HREF="manual.html#pdf-os.difftime">os.difftime</A><BR>
+
<A HREF="manual.html#pdf-os.execute">os.execute</A><BR>
+
<A HREF="manual.html#pdf-os.exit">os.exit</A><BR>
+
<A HREF="manual.html#pdf-os.getenv">os.getenv</A><BR>
+
<A HREF="manual.html#pdf-os.remove">os.remove</A><BR>
+
<A HREF="manual.html#pdf-os.rename">os.rename</A><BR>
+
<A HREF="manual.html#pdf-os.setlocale">os.setlocale</A><BR>
+
<A HREF="manual.html#pdf-os.time">os.time</A><BR>
+
<A HREF="manual.html#pdf-os.tmpname">os.tmpname</A><BR>
+

+
<P>
+
<A HREF="manual.html#6.3">package</A><BR>
+
<A HREF="manual.html#pdf-package.config">package.config</A><BR>
+
<A HREF="manual.html#pdf-package.cpath">package.cpath</A><BR>
+
<A HREF="manual.html#pdf-package.loaded">package.loaded</A><BR>
+
<A HREF="manual.html#pdf-package.loadlib">package.loadlib</A><BR>
+
<A HREF="manual.html#pdf-package.path">package.path</A><BR>
+
<A HREF="manual.html#pdf-package.preload">package.preload</A><BR>
+
<A HREF="manual.html#pdf-package.searchers">package.searchers</A><BR>
+
<A HREF="manual.html#pdf-package.searchpath">package.searchpath</A><BR>
+

+
<P>
+
<A HREF="manual.html#6.4">string</A><BR>
+
<A HREF="manual.html#pdf-string.byte">string.byte</A><BR>
+
<A HREF="manual.html#pdf-string.char">string.char</A><BR>
+
<A HREF="manual.html#pdf-string.dump">string.dump</A><BR>
+
<A HREF="manual.html#pdf-string.find">string.find</A><BR>
+
<A HREF="manual.html#pdf-string.format">string.format</A><BR>
+
<A HREF="manual.html#pdf-string.gmatch">string.gmatch</A><BR>
+
<A HREF="manual.html#pdf-string.gsub">string.gsub</A><BR>
+
<A HREF="manual.html#pdf-string.len">string.len</A><BR>
+
<A HREF="manual.html#pdf-string.lower">string.lower</A><BR>
+
<A HREF="manual.html#pdf-string.match">string.match</A><BR>
+
<A HREF="manual.html#pdf-string.pack">string.pack</A><BR>
+
<A HREF="manual.html#pdf-string.packsize">string.packsize</A><BR>
+
<A HREF="manual.html#pdf-string.rep">string.rep</A><BR>
+
<A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR>
+
<A HREF="manual.html#pdf-string.sub">string.sub</A><BR>
+
<A HREF="manual.html#pdf-string.unpack">string.unpack</A><BR>
+
<A HREF="manual.html#pdf-string.upper">string.upper</A><BR>
+

+
<P>
+
<A HREF="manual.html#6.6">table</A><BR>
+
<A HREF="manual.html#pdf-table.concat">table.concat</A><BR>
+
<A HREF="manual.html#pdf-table.insert">table.insert</A><BR>
+
<A HREF="manual.html#pdf-table.move">table.move</A><BR>
+
<A HREF="manual.html#pdf-table.pack">table.pack</A><BR>
+
<A HREF="manual.html#pdf-table.remove">table.remove</A><BR>
+
<A HREF="manual.html#pdf-table.sort">table.sort</A><BR>
+
<A HREF="manual.html#pdf-table.unpack">table.unpack</A><BR>
+

+
<P>
+
<A HREF="manual.html#6.5">utf8</A><BR>
+
<A HREF="manual.html#pdf-utf8.char">utf8.char</A><BR>
+
<A HREF="manual.html#pdf-utf8.charpattern">utf8.charpattern</A><BR>
+
<A HREF="manual.html#pdf-utf8.codepoint">utf8.codepoint</A><BR>
+
<A HREF="manual.html#pdf-utf8.codes">utf8.codes</A><BR>
+
<A HREF="manual.html#pdf-utf8.len">utf8.len</A><BR>
+
<A HREF="manual.html#pdf-utf8.offset">utf8.offset</A><BR>
+

+
<H3><A NAME="env">environment<BR>variables</A></H3>
+
<P>
+
<A HREF="manual.html#pdf-LUA_CPATH">LUA_CPATH</A><BR>
+
<A HREF="manual.html#pdf-LUA_CPATH_5_3">LUA_CPATH_5_3</A><BR>
+
<A HREF="manual.html#pdf-LUA_INIT">LUA_INIT</A><BR>
+
<A HREF="manual.html#pdf-LUA_INIT_5_3">LUA_INIT_5_3</A><BR>
+
<A HREF="manual.html#pdf-LUA_PATH">LUA_PATH</A><BR>
+
<A HREF="manual.html#pdf-LUA_PATH_5_3">LUA_PATH_5_3</A><BR>
+

+
</TD>
+
<TD>
+
<H3><A NAME="api">C API</A></H3>
+
<P>
+
<A HREF="manual.html#lua_Alloc">lua_Alloc</A><BR>
+
<A HREF="manual.html#lua_CFunction">lua_CFunction</A><BR>
+
<A HREF="manual.html#lua_Debug">lua_Debug</A><BR>
+
<A HREF="manual.html#lua_Hook">lua_Hook</A><BR>
+
<A HREF="manual.html#lua_Integer">lua_Integer</A><BR>
+
<A HREF="manual.html#lua_KContext">lua_KContext</A><BR>
+
<A HREF="manual.html#lua_KFunction">lua_KFunction</A><BR>
+
<A HREF="manual.html#lua_Number">lua_Number</A><BR>
+
<A HREF="manual.html#lua_Reader">lua_Reader</A><BR>
+
<A HREF="manual.html#lua_State">lua_State</A><BR>
+
<A HREF="manual.html#lua_Unsigned">lua_Unsigned</A><BR>
+
<A HREF="manual.html#lua_Writer">lua_Writer</A><BR>
+

+
<P>
+
<A HREF="manual.html#lua_absindex">lua_absindex</A><BR>
+
<A HREF="manual.html#lua_arith">lua_arith</A><BR>
+
<A HREF="manual.html#lua_atpanic">lua_atpanic</A><BR>
+
<A HREF="manual.html#lua_call">lua_call</A><BR>
+
<A HREF="manual.html#lua_callk">lua_callk</A><BR>
+
<A HREF="manual.html#lua_checkstack">lua_checkstack</A><BR>
+
<A HREF="manual.html#lua_close">lua_close</A><BR>
+
<A HREF="manual.html#lua_compare">lua_compare</A><BR>
+
<A HREF="manual.html#lua_concat">lua_concat</A><BR>
+
<A HREF="manual.html#lua_copy">lua_copy</A><BR>
+
<A HREF="manual.html#lua_createtable">lua_createtable</A><BR>
+
<A HREF="manual.html#lua_dump">lua_dump</A><BR>
+
<A HREF="manual.html#lua_error">lua_error</A><BR>
+
<A HREF="manual.html#lua_gc">lua_gc</A><BR>
+
<A HREF="manual.html#lua_getallocf">lua_getallocf</A><BR>
+
<A HREF="manual.html#lua_getextraspace">lua_getextraspace</A><BR>
+
<A HREF="manual.html#lua_getfield">lua_getfield</A><BR>
+
<A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR>
+
<A HREF="manual.html#lua_gethook">lua_gethook</A><BR>
+
<A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR>
+
<A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR>
+
<A HREF="manual.html#lua_geti">lua_geti</A><BR>
+
<A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR>
+
<A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR>
+
<A HREF="manual.html#lua_getmetatable">lua_getmetatable</A><BR>
+
<A HREF="manual.html#lua_getstack">lua_getstack</A><BR>
+
<A HREF="manual.html#lua_gettable">lua_gettable</A><BR>
+
<A HREF="manual.html#lua_gettop">lua_gettop</A><BR>
+
<A HREF="manual.html#lua_getupvalue">lua_getupvalue</A><BR>
+
<A HREF="manual.html#lua_getuservalue">lua_getuservalue</A><BR>
+
<A HREF="manual.html#lua_insert">lua_insert</A><BR>
+
<A HREF="manual.html#lua_isboolean">lua_isboolean</A><BR>
+
<A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR>
+
<A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR>
+
<A HREF="manual.html#lua_isinteger">lua_isinteger</A><BR>
+
<A HREF="manual.html#lua_islightuserdata">lua_islightuserdata</A><BR>
+
<A HREF="manual.html#lua_isnil">lua_isnil</A><BR>
+
<A HREF="manual.html#lua_isnone">lua_isnone</A><BR>
+
<A HREF="manual.html#lua_isnoneornil">lua_isnoneornil</A><BR>
+
<A HREF="manual.html#lua_isnumber">lua_isnumber</A><BR>
+
<A HREF="manual.html#lua_isstring">lua_isstring</A><BR>
+
<A HREF="manual.html#lua_istable">lua_istable</A><BR>
+
<A HREF="manual.html#lua_isthread">lua_isthread</A><BR>
+
<A HREF="manual.html#lua_isuserdata">lua_isuserdata</A><BR>
+
<A HREF="manual.html#lua_isyieldable">lua_isyieldable</A><BR>
+
<A HREF="manual.html#lua_len">lua_len</A><BR>
+
<A HREF="manual.html#lua_load">lua_load</A><BR>
+
<A HREF="manual.html#lua_newstate">lua_newstate</A><BR>
+
<A HREF="manual.html#lua_newtable">lua_newtable</A><BR>
+
<A HREF="manual.html#lua_newthread">lua_newthread</A><BR>
+
<A HREF="manual.html#lua_newuserdata">lua_newuserdata</A><BR>
+
<A HREF="manual.html#lua_next">lua_next</A><BR>
+
<A HREF="manual.html#lua_numbertointeger">lua_numbertointeger</A><BR>
+
<A HREF="manual.html#lua_pcall">lua_pcall</A><BR>
+
<A HREF="manual.html#lua_pcallk">lua_pcallk</A><BR>
+
<A HREF="manual.html#lua_pop">lua_pop</A><BR>
+
<A HREF="manual.html#lua_pushboolean">lua_pushboolean</A><BR>
+
<A HREF="manual.html#lua_pushcclosure">lua_pushcclosure</A><BR>
+
<A HREF="manual.html#lua_pushcfunction">lua_pushcfunction</A><BR>
+
<A HREF="manual.html#lua_pushfstring">lua_pushfstring</A><BR>
+
<A HREF="manual.html#lua_pushglobaltable">lua_pushglobaltable</A><BR>
+
<A HREF="manual.html#lua_pushinteger">lua_pushinteger</A><BR>
+
<A HREF="manual.html#lua_pushlightuserdata">lua_pushlightuserdata</A><BR>
+
<A HREF="manual.html#lua_pushliteral">lua_pushliteral</A><BR>
+
<A HREF="manual.html#lua_pushlstring">lua_pushlstring</A><BR>
+
<A HREF="manual.html#lua_pushnil">lua_pushnil</A><BR>
+
<A HREF="manual.html#lua_pushnumber">lua_pushnumber</A><BR>
+
<A HREF="manual.html#lua_pushstring">lua_pushstring</A><BR>
+
<A HREF="manual.html#lua_pushthread">lua_pushthread</A><BR>
+
<A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR>
+
<A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR>
+
<A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR>
+
<A HREF="manual.html#lua_rawget">lua_rawget</A><BR>
+
<A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR>
+
<A HREF="manual.html#lua_rawgetp">lua_rawgetp</A><BR>
+
<A HREF="manual.html#lua_rawlen">lua_rawlen</A><BR>
+
<A HREF="manual.html#lua_rawset">lua_rawset</A><BR>
+
<A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR>
+
<A HREF="manual.html#lua_rawsetp">lua_rawsetp</A><BR>
+
<A HREF="manual.html#lua_register">lua_register</A><BR>
+
<A HREF="manual.html#lua_remove">lua_remove</A><BR>
+
<A HREF="manual.html#lua_replace">lua_replace</A><BR>
+
<A HREF="manual.html#lua_resume">lua_resume</A><BR>
+
<A HREF="manual.html#lua_rotate">lua_rotate</A><BR>
+
<A HREF="manual.html#lua_setallocf">lua_setallocf</A><BR>
+
<A HREF="manual.html#lua_setfield">lua_setfield</A><BR>
+
<A HREF="manual.html#lua_setglobal">lua_setglobal</A><BR>
+
<A HREF="manual.html#lua_sethook">lua_sethook</A><BR>
+
<A HREF="manual.html#lua_seti">lua_seti</A><BR>
+
<A HREF="manual.html#lua_setlocal">lua_setlocal</A><BR>
+
<A HREF="manual.html#lua_setmetatable">lua_setmetatable</A><BR>
+
<A HREF="manual.html#lua_settable">lua_settable</A><BR>
+
<A HREF="manual.html#lua_settop">lua_settop</A><BR>
+
<A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR>
+
<A HREF="manual.html#lua_setuservalue">lua_setuservalue</A><BR>
+
<A HREF="manual.html#lua_status">lua_status</A><BR>
+
<A HREF="manual.html#lua_stringtonumber">lua_stringtonumber</A><BR>
+
<A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR>
+
<A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR>
+
<A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR>
+
<A HREF="manual.html#lua_tointegerx">lua_tointegerx</A><BR>
+
<A HREF="manual.html#lua_tolstring">lua_tolstring</A><BR>
+
<A HREF="manual.html#lua_tonumber">lua_tonumber</A><BR>
+
<A HREF="manual.html#lua_tonumberx">lua_tonumberx</A><BR>
+
<A HREF="manual.html#lua_topointer">lua_topointer</A><BR>
+
<A HREF="manual.html#lua_tostring">lua_tostring</A><BR>
+
<A HREF="manual.html#lua_tothread">lua_tothread</A><BR>
+
<A HREF="manual.html#lua_touserdata">lua_touserdata</A><BR>
+
<A HREF="manual.html#lua_type">lua_type</A><BR>
+
<A HREF="manual.html#lua_typename">lua_typename</A><BR>
+
<A HREF="manual.html#lua_upvalueid">lua_upvalueid</A><BR>
+
<A HREF="manual.html#lua_upvalueindex">lua_upvalueindex</A><BR>
+
<A HREF="manual.html#lua_upvaluejoin">lua_upvaluejoin</A><BR>
+
<A HREF="manual.html#lua_version">lua_version</A><BR>
+
<A HREF="manual.html#lua_xmove">lua_xmove</A><BR>
+
<A HREF="manual.html#lua_yield">lua_yield</A><BR>
+
<A HREF="manual.html#lua_yieldk">lua_yieldk</A><BR>
+

+
</TD>
+
<TD>
+
<H3><A NAME="auxlib">auxiliary library</A></H3>
+
<P>
+
<A HREF="manual.html#luaL_Buffer">luaL_Buffer</A><BR>
+
<A HREF="manual.html#luaL_Reg">luaL_Reg</A><BR>
+
<A HREF="manual.html#luaL_Stream">luaL_Stream</A><BR>
+

+
<P>
+
<A HREF="manual.html#luaL_addchar">luaL_addchar</A><BR>
+
<A HREF="manual.html#luaL_addlstring">luaL_addlstring</A><BR>
+
<A HREF="manual.html#luaL_addsize">luaL_addsize</A><BR>
+
<A HREF="manual.html#luaL_addstring">luaL_addstring</A><BR>
+
<A HREF="manual.html#luaL_addvalue">luaL_addvalue</A><BR>
+
<A HREF="manual.html#luaL_argcheck">luaL_argcheck</A><BR>
+
<A HREF="manual.html#luaL_argerror">luaL_argerror</A><BR>
+
<A HREF="manual.html#luaL_buffinit">luaL_buffinit</A><BR>
+
<A HREF="manual.html#luaL_buffinitsize">luaL_buffinitsize</A><BR>
+
<A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR>
+
<A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR>
+
<A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR>
+
<A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR>
+
<A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR>
+
<A HREF="manual.html#luaL_checkoption">luaL_checkoption</A><BR>
+
<A HREF="manual.html#luaL_checkstack">luaL_checkstack</A><BR>
+
<A HREF="manual.html#luaL_checkstring">luaL_checkstring</A><BR>
+
<A HREF="manual.html#luaL_checktype">luaL_checktype</A><BR>
+
<A HREF="manual.html#luaL_checkudata">luaL_checkudata</A><BR>
+
<A HREF="manual.html#luaL_checkversion">luaL_checkversion</A><BR>
+
<A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR>
+
<A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR>
+
<A HREF="manual.html#luaL_error">luaL_error</A><BR>
+
<A HREF="manual.html#luaL_execresult">luaL_execresult</A><BR>
+
<A HREF="manual.html#luaL_fileresult">luaL_fileresult</A><BR>
+
<A HREF="manual.html#luaL_getmetafield">luaL_getmetafield</A><BR>
+
<A HREF="manual.html#luaL_getmetatable">luaL_getmetatable</A><BR>
+
<A HREF="manual.html#luaL_getsubtable">luaL_getsubtable</A><BR>
+
<A HREF="manual.html#luaL_gsub">luaL_gsub</A><BR>
+
<A HREF="manual.html#luaL_len">luaL_len</A><BR>
+
<A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR>
+
<A HREF="manual.html#luaL_loadbufferx">luaL_loadbufferx</A><BR>
+
<A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR>
+
<A HREF="manual.html#luaL_loadfilex">luaL_loadfilex</A><BR>
+
<A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR>
+
<A HREF="manual.html#luaL_newlib">luaL_newlib</A><BR>
+
<A HREF="manual.html#luaL_newlibtable">luaL_newlibtable</A><BR>
+
<A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR>
+
<A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR>
+
<A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR>
+
<A HREF="manual.html#luaL_opt">luaL_opt</A><BR>
+
<A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR>
+
<A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR>
+
<A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR>
+
<A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR>
+
<A HREF="manual.html#luaL_prepbuffer">luaL_prepbuffer</A><BR>
+
<A HREF="manual.html#luaL_prepbuffsize">luaL_prepbuffsize</A><BR>
+
<A HREF="manual.html#luaL_pushresult">luaL_pushresult</A><BR>
+
<A HREF="manual.html#luaL_pushresultsize">luaL_pushresultsize</A><BR>
+
<A HREF="manual.html#luaL_ref">luaL_ref</A><BR>
+
<A HREF="manual.html#luaL_requiref">luaL_requiref</A><BR>
+
<A HREF="manual.html#luaL_setfuncs">luaL_setfuncs</A><BR>
+
<A HREF="manual.html#luaL_setmetatable">luaL_setmetatable</A><BR>
+
<A HREF="manual.html#luaL_testudata">luaL_testudata</A><BR>
+
<A HREF="manual.html#luaL_tolstring">luaL_tolstring</A><BR>
+
<A HREF="manual.html#luaL_traceback">luaL_traceback</A><BR>
+
<A HREF="manual.html#luaL_typename">luaL_typename</A><BR>
+
<A HREF="manual.html#luaL_unref">luaL_unref</A><BR>
+
<A HREF="manual.html#luaL_where">luaL_where</A><BR>
+

+
<H3><A NAME="library">standard library</A></H3>
+
<P>
+
<A HREF="manual.html#pdf-luaopen_base">luaopen_base</A><BR>
+
<A HREF="manual.html#pdf-luaopen_coroutine">luaopen_coroutine</A><BR>
+
<A HREF="manual.html#pdf-luaopen_debug">luaopen_debug</A><BR>
+
<A HREF="manual.html#pdf-luaopen_io">luaopen_io</A><BR>
+
<A HREF="manual.html#pdf-luaopen_math">luaopen_math</A><BR>
+
<A HREF="manual.html#pdf-luaopen_os">luaopen_os</A><BR>
+
<A HREF="manual.html#pdf-luaopen_package">luaopen_package</A><BR>
+
<A HREF="manual.html#pdf-luaopen_string">luaopen_string</A><BR>
+
<A HREF="manual.html#pdf-luaopen_table">luaopen_table</A><BR>
+
<A HREF="manual.html#pdf-luaopen_utf8">luaopen_utf8</A><BR>
+

+
<H3><A NAME="constants">constants</A></H3>
+
<P>
+
<A HREF="manual.html#pdf-LUA_ERRERR">LUA_ERRERR</A><BR>
+
<A HREF="manual.html#pdf-LUA_ERRFILE">LUA_ERRFILE</A><BR>
+
<A HREF="manual.html#pdf-LUA_ERRGCMM">LUA_ERRGCMM</A><BR>
+
<A HREF="manual.html#pdf-LUA_ERRMEM">LUA_ERRMEM</A><BR>
+
<A HREF="manual.html#pdf-LUA_ERRRUN">LUA_ERRRUN</A><BR>
+
<A HREF="manual.html#pdf-LUA_ERRSYNTAX">LUA_ERRSYNTAX</A><BR>
+
<A HREF="manual.html#pdf-LUA_HOOKCALL">LUA_HOOKCALL</A><BR>
+
<A HREF="manual.html#pdf-LUA_HOOKCOUNT">LUA_HOOKCOUNT</A><BR>
+
<A HREF="manual.html#pdf-LUA_HOOKLINE">LUA_HOOKLINE</A><BR>
+
<A HREF="manual.html#pdf-LUA_HOOKRET">LUA_HOOKRET</A><BR>
+
<A HREF="manual.html#pdf-LUA_HOOKTAILCALL">LUA_HOOKTAILCALL</A><BR>
+
<A HREF="manual.html#pdf-LUA_MASKCALL">LUA_MASKCALL</A><BR>
+
<A HREF="manual.html#pdf-LUA_MASKCOUNT">LUA_MASKCOUNT</A><BR>
+
<A HREF="manual.html#pdf-LUA_MASKLINE">LUA_MASKLINE</A><BR>
+
<A HREF="manual.html#pdf-LUA_MASKRET">LUA_MASKRET</A><BR>
+
<A HREF="manual.html#pdf-LUA_MAXINTEGER">LUA_MAXINTEGER</A><BR>
+
<A HREF="manual.html#pdf-LUA_MININTEGER">LUA_MININTEGER</A><BR>
+
<A HREF="manual.html#pdf-LUA_MINSTACK">LUA_MINSTACK</A><BR>
+
<A HREF="manual.html#pdf-LUA_MULTRET">LUA_MULTRET</A><BR>
+
<A HREF="manual.html#pdf-LUA_NOREF">LUA_NOREF</A><BR>
+
<A HREF="manual.html#pdf-LUA_OK">LUA_OK</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPADD">LUA_OPADD</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPBAND">LUA_OPBAND</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPBNOT">LUA_OPBNOT</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPBOR">LUA_OPBOR</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPBXOR">LUA_OPBXOR</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPDIV">LUA_OPDIV</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPEQ">LUA_OPEQ</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPIDIV">LUA_OPIDIV</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPLE">LUA_OPLE</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPLT">LUA_OPLT</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPMOD">LUA_OPMOD</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPMUL">LUA_OPMUL</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPPOW">LUA_OPPOW</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPSHL">LUA_OPSHL</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPSHR">LUA_OPSHR</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPSUB">LUA_OPSUB</A><BR>
+
<A HREF="manual.html#pdf-LUA_OPUNM">LUA_OPUNM</A><BR>
+
<A HREF="manual.html#pdf-LUA_REFNIL">LUA_REFNIL</A><BR>
+
<A HREF="manual.html#pdf-LUA_REGISTRYINDEX">LUA_REGISTRYINDEX</A><BR>
+
<A HREF="manual.html#pdf-LUA_RIDX_GLOBALS">LUA_RIDX_GLOBALS</A><BR>
+
<A HREF="manual.html#pdf-LUA_RIDX_MAINTHREAD">LUA_RIDX_MAINTHREAD</A><BR>
+
<A HREF="manual.html#pdf-LUA_TBOOLEAN">LUA_TBOOLEAN</A><BR>
+
<A HREF="manual.html#pdf-LUA_TFUNCTION">LUA_TFUNCTION</A><BR>
+
<A HREF="manual.html#pdf-LUA_TLIGHTUSERDATA">LUA_TLIGHTUSERDATA</A><BR>
+
<A HREF="manual.html#pdf-LUA_TNIL">LUA_TNIL</A><BR>
+
<A HREF="manual.html#pdf-LUA_TNONE">LUA_TNONE</A><BR>
+
<A HREF="manual.html#pdf-LUA_TNUMBER">LUA_TNUMBER</A><BR>
+
<A HREF="manual.html#pdf-LUA_TSTRING">LUA_TSTRING</A><BR>
+
<A HREF="manual.html#pdf-LUA_TTABLE">LUA_TTABLE</A><BR>
+
<A HREF="manual.html#pdf-LUA_TTHREAD">LUA_TTHREAD</A><BR>
+
<A HREF="manual.html#pdf-LUA_TUSERDATA">LUA_TUSERDATA</A><BR>
+
<A HREF="manual.html#pdf-LUA_USE_APICHECK">LUA_USE_APICHECK</A><BR>
+
<A HREF="manual.html#pdf-LUA_YIELD">LUA_YIELD</A><BR>
+
<A HREF="manual.html#pdf-LUAL_BUFFERSIZE">LUAL_BUFFERSIZE</A><BR>
+

+
</TD>
+
</TR>
+
</TABLE>
+

+
<P CLASS="footer">
+
Last update:
+
Mon Jun 18 22:56:06 -03 2018
+
</P>
+
<!--
+
Last change: revised for Lua 5.3.5
+
-->
+

+
</BODY>
+
</HTML>
added external/lua/doc/index.css
@@ -0,0 +1,21 @@
+
ul {
+
	list-style-type: none ;
+
}
+

+
ul.contents {
+
	padding: 0 ;
+
}
+

+
table {
+
	border: none ;
+
	border-spacing: 0 ;
+
	border-collapse: collapse ;
+
}
+

+
td {
+
	vertical-align: top ;
+
	padding: 0 ;
+
	text-align: left ;
+
	line-height: 1.25 ;
+
	width: 15% ;
+
}
added external/lua/doc/logo.gif
added external/lua/doc/lua.1
@@ -0,0 +1,112 @@
+
.\" $Id: lua.man,v 1.14 2016/10/17 15:43:50 lhf Exp $
+
.TH LUA 1 "$Date: 2016/10/17 15:43:50 $"
+
.SH NAME
+
lua \- Lua interpreter
+
.SH SYNOPSIS
+
.B lua
+
[
+
.I options
+
]
+
[
+
.I script
+
[
+
.I args
+
]
+
]
+
.SH DESCRIPTION
+
.B lua
+
is the standalone Lua interpreter.
+
It loads and executes Lua programs,
+
either in textual source form or
+
in precompiled binary form.
+
(Precompiled binaries are output by
+
.BR luac ,
+
the Lua compiler.)
+
.B lua
+
can be used as a batch interpreter and also interactively.
+
.LP
+
The given
+
.I options
+
are handled in order and then
+
the Lua program in file
+
.I script
+
is loaded and executed.
+
The given
+
.I args
+
are available to
+
.I script
+
as strings in a global table named
+
.BR arg .
+
If no options or arguments are given,
+
then
+
.B "\-v \-i"
+
is assumed when the standard input is a terminal;
+
otherwise,
+
.B "\-"
+
is assumed.
+
.LP
+
In interactive mode,
+
.B lua
+
prompts the user,
+
reads lines from the standard input,
+
and executes them as they are read.
+
If the line contains an expression or list of expressions,
+
then the line is evaluated and the results are printed.
+
If a line does not contain a complete statement,
+
then a secondary prompt is displayed and
+
lines are read until a complete statement is formed or
+
a syntax error is found.
+
.LP
+
At the very start,
+
before even handling the command line,
+
.B lua
+
checks the contents of the environment variables
+
.B LUA_INIT_5_3
+
or
+
.BR LUA_INIT ,
+
in that order.
+
If the contents is of the form
+
.RI '@ filename ',
+
then
+
.I filename
+
is executed.
+
Otherwise, the string is assumed to be a Lua statement and is executed.
+
.SH OPTIONS
+
.TP
+
.BI \-e " stat"
+
execute statement
+
.IR stat .
+
.TP
+
.B \-i
+
enter interactive mode after executing
+
.IR script .
+
.TP
+
.BI \-l " name"
+
execute the equivalent of
+
.IB name =require(' name ')
+
before executing
+
.IR script .
+
.TP
+
.B \-v
+
show version information.
+
.TP
+
.B \-E
+
ignore environment variables.
+
.TP
+
.B \-\-
+
stop handling options.
+
.TP
+
.B \-
+
stop handling options and execute the standard input as a file.
+
.SH "SEE ALSO"
+
.BR luac (1)
+
.br
+
The documentation at lua.org,
+
especially section 7 of the reference manual.
+
.SH DIAGNOSTICS
+
Error messages should be self explanatory.
+
.SH AUTHORS
+
R. Ierusalimschy,
+
L. H. de Figueiredo,
+
W. Celes
+
.\" EOF
added external/lua/doc/lua.css
@@ -0,0 +1,161 @@
+
html {
+
	background-color: #F8F8F8 ;
+
}
+

+
body {
+
	background-color: #FFFFFF ;
+
	color: #000000 ;
+
	font-family: Helvetica, Arial, sans-serif ;
+
	text-align: justify ;
+
	line-height: 1.25 ;
+
	margin: 16px auto ;
+
	padding: 32px ;
+
	border: solid #ccc 1px ;
+
	border-radius: 20px ;
+
	max-width: 70em ;
+
	width: 90% ;
+
}
+

+
h1, h2, h3, h4 {
+
	color: #000080 ;
+
	font-family: Verdana, Geneva, sans-serif ;
+
	font-weight: normal ;
+
	font-style: normal ;
+
	text-align: left ;
+
}
+

+
h1 {
+
	font-size: 28pt ;
+
}
+

+
h1 img {
+
	vertical-align: text-bottom ;
+
}
+

+
h2:before {
+
	content: "\2756" ;
+
	padding-right: 0.5em ;
+
}
+

+
a {
+
	text-decoration: none ;
+
}
+

+
a:link {
+
	color: #000080 ;
+
}
+

+
a:link:hover, a:visited:hover {
+
	background-color: #D0D0FF ;
+
	color: #000080 ;
+
	border-radius: 4px ;
+
}
+

+
a:link:active, a:visited:active {
+
	color: #FF0000 ;
+
}
+

+
div.menubar {
+
	padding-bottom: 0.5em ;
+
}
+

+
p.menubar {
+
	margin-left: 2.5em ;
+
}
+

+
.menubar a:hover  {
+
	margin: -3px -3px -3px -3px ;
+
	padding: 3px  3px  3px  3px ;
+
	border-radius: 4px ;
+
}
+

+
:target {
+
	background-color: #F0F0F0 ;
+
	margin: -8px ;
+
	padding: 8px ;
+
	border-radius: 8px ;
+
	outline: none ;
+
}
+

+
hr {
+
	display: none ;
+
}
+

+
table hr {
+
	background-color: #a0a0a0 ;
+
	color: #a0a0a0 ;
+
	border: 0 ;
+
	height: 1px ;
+
	display: block ;
+
}
+

+
.footer {
+
	color: gray ;
+
	font-size: x-small ;
+
	text-transform: lowercase ;
+
}
+

+
input[type=text] {
+
	border: solid #a0a0a0 2px ;
+
	border-radius: 2em ;
+
	background-image: url('images/search.png') ;
+
	background-repeat: no-repeat ;
+
	background-position: 4px center ;
+
	padding-left: 20px ;
+
	height: 2em ;
+
}
+

+
pre.session {
+
	background-color: #F8F8F8 ;
+
	padding: 1em ;
+
	border-radius: 8px ;
+
}
+

+
table {
+
	border: none ;
+
	border-spacing: 0 ;
+
	border-collapse: collapse ;
+
}
+

+
td {
+
	padding: 0 ;
+
	margin: 0 ;
+
}
+

+
td.gutter {
+
	width: 4% ;
+
}
+

+
table.columns td {
+
	vertical-align: top ;
+
	padding-bottom: 1em ;
+
	text-align: justify ;
+
	line-height: 1.25 ;
+
}
+

+
table.book td {
+
	vertical-align: top ;
+
}
+

+
table.book td.cover {
+
	padding-right: 1em ;
+
}
+

+
table.book img {
+
	border: solid #000080 1px ;
+
}
+

+
table.book span {
+
	font-size: small ;
+
	text-align: left ;
+
	display: block ;
+
	margin-top: 0.25em ;
+
}
+

+
p.logos a:link:hover, p.logos a:visited:hover {
+
	background-color: inherit ;
+
}
+

+
img {
+
	background-color: white ;
+
}
added external/lua/doc/luac.1
@@ -0,0 +1,118 @@
+
.\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $
+
.TH LUAC 1 "$Date: 2011/11/16 13:53:40 $"
+
.SH NAME
+
luac \- Lua compiler
+
.SH SYNOPSIS
+
.B luac
+
[
+
.I options
+
] [
+
.I filenames
+
]
+
.SH DESCRIPTION
+
.B luac
+
is the Lua compiler.
+
It translates programs written in the Lua programming language
+
into binary files containing precompiled chunks
+
that can be later loaded and executed.
+
.LP
+
The main advantages of precompiling chunks are:
+
faster loading,
+
protecting source code from accidental user changes,
+
and
+
off-line syntax checking.
+
Precompiling does not imply faster execution
+
because in Lua chunks are always compiled into bytecodes before being executed.
+
.B luac
+
simply allows those bytecodes to be saved in a file for later execution.
+
Precompiled chunks are not necessarily smaller than the corresponding source.
+
The main goal in precompiling is faster loading.
+
.LP
+
In the command line,
+
you can mix
+
text files containing Lua source and
+
binary files containing precompiled chunks.
+
.B luac
+
produces a single output file containing the combined bytecodes
+
for all files given.
+
Executing the combined file is equivalent to executing the given files.
+
By default,
+
the output file is named
+
.BR luac.out ,
+
but you can change this with the
+
.B \-o
+
option.
+
.LP
+
Precompiled chunks are
+
.I not
+
portable across different architectures.
+
Moreover,
+
the internal format of precompiled chunks
+
is likely to change when a new version of Lua is released.
+
Make sure you save the source files of all Lua programs that you precompile.
+
.LP
+
.SH OPTIONS
+
.TP
+
.B \-l
+
produce a listing of the compiled bytecode for Lua's virtual machine.
+
Listing bytecodes is useful to learn about Lua's virtual machine.
+
If no files are given, then
+
.B luac
+
loads
+
.B luac.out
+
and lists its contents.
+
Use
+
.B \-l \-l
+
for a full listing.
+
.TP
+
.BI \-o " file"
+
output to
+
.IR file ,
+
instead of the default
+
.BR luac.out .
+
(You can use
+
.B "'\-'"
+
for standard output,
+
but not on platforms that open standard output in text mode.)
+
The output file may be one of the given files because
+
all files are loaded before the output file is written.
+
Be careful not to overwrite precious files.
+
.TP
+
.B \-p
+
load files but do not generate any output file.
+
Used mainly for syntax checking and for testing precompiled chunks:
+
corrupted files will probably generate errors when loaded.
+
If no files are given, then
+
.B luac
+
loads
+
.B luac.out
+
and tests its contents.
+
No messages are displayed if the file loads without errors.
+
.TP
+
.B \-s
+
strip debug information before writing the output file.
+
This saves some space in very large chunks,
+
but if errors occur when running a stripped chunk,
+
then the error messages may not contain the full information they usually do.
+
In particular,
+
line numbers and names of local variables are lost.
+
.TP
+
.B \-v
+
show version information.
+
.TP
+
.B \-\-
+
stop handling options.
+
.TP
+
.B \-
+
stop handling options and process standard input.
+
.SH "SEE ALSO"
+
.BR lua (1)
+
.br
+
The documentation at lua.org.
+
.SH DIAGNOSTICS
+
Error messages should be self explanatory.
+
.SH AUTHORS
+
R. Ierusalimschy,
+
L. H. de Figueiredo,
+
W. Celes
+
.\" EOF
added external/lua/doc/manual.css
@@ -0,0 +1,21 @@
+
h3 code {
+
	font-family: inherit ;
+
	font-size: inherit ;
+
}
+

+
pre, code {
+
	font-size: 12pt ;
+
}
+

+
span.apii {
+
	color: gray ;
+
	float: right ;
+
	font-family: inherit ;
+
	font-style: normal ;
+
	font-size: small ;
+
}
+

+
h2:before {
+
	content: "" ;
+
	padding-right: 0em ;
+
}
added external/lua/doc/manual.html
@@ -0,0 +1,10982 @@
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
<HTML>
+
<HEAD>
+
<TITLE>Lua 5.3 Reference Manual</TITLE>
+
<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
+
<LINK REL="stylesheet" TYPE="text/css" HREF="manual.css">
+
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
+
</HEAD>
+

+
<BODY>
+

+
<H1>
+
<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
+
Lua 5.3 Reference Manual
+
</H1>
+

+
<P>
+
by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
+

+
<P>
+
<SMALL>
+
Copyright &copy; 2015&ndash;2018 Lua.org, PUC-Rio.
+
Freely available under the terms of the
+
<a href="http://www.lua.org/license.html">Lua license</a>.
+
</SMALL>
+

+
<DIV CLASS="menubar">
+
<A HREF="contents.html#contents">contents</A>
+
&middot;
+
<A HREF="contents.html#index">index</A>
+
&middot;
+
<A HREF="http://www.lua.org/manual/">other versions</A>
+
</DIV>
+

+
<!-- ====================================================================== -->
+
<p>
+

+
<!-- $Id: manual.of,v 1.167.1.2 2018/06/26 15:49:07 roberto Exp $ -->
+

+

+

+

+
<h1>1 &ndash; <a name="1">Introduction</a></h1>
+

+
<p>
+
Lua is a powerful, efficient, lightweight, embeddable scripting language.
+
It supports procedural programming,
+
object-oriented programming, functional programming,
+
data-driven programming, and data description.
+

+

+
<p>
+
Lua combines simple procedural syntax with powerful data description
+
constructs based on associative arrays and extensible semantics.
+
Lua is dynamically typed,
+
runs by interpreting bytecode with a register-based
+
virtual machine,
+
and has automatic memory management with
+
incremental garbage collection,
+
making it ideal for configuration, scripting,
+
and rapid prototyping.
+

+

+
<p>
+
Lua is implemented as a library, written in <em>clean C</em>,
+
the common subset of Standard&nbsp;C and C++.
+
The Lua distribution includes a host program called <code>lua</code>,
+
which uses the Lua library to offer a complete,
+
standalone Lua interpreter,
+
for interactive or batch use.
+
Lua is intended to be used both as a powerful, lightweight,
+
embeddable scripting language for any program that needs one,
+
and as a powerful but lightweight and efficient stand-alone language.
+

+

+
<p>
+
As an extension language, Lua has no notion of a "main" program:
+
it works <em>embedded</em> in a host client,
+
called the <em>embedding program</em> or simply the <em>host</em>.
+
(Frequently, this host is the stand-alone <code>lua</code> program.)
+
The host program can invoke functions to execute a piece of Lua code,
+
can write and read Lua variables,
+
and can register C&nbsp;functions to be called by Lua code.
+
Through the use of C&nbsp;functions, Lua can be augmented to cope with
+
a wide range of different domains,
+
thus creating customized programming languages sharing a syntactical framework.
+

+

+
<p>
+
Lua is free software,
+
and is provided as usual with no guarantees,
+
as stated in its license.
+
The implementation described in this manual is available
+
at Lua's official web site, <code>www.lua.org</code>.
+

+

+
<p>
+
Like any other reference manual,
+
this document is dry in places.
+
For a discussion of the decisions behind the design of Lua,
+
see the technical papers available at Lua's web site.
+
For a detailed introduction to programming in Lua,
+
see Roberto's book, <em>Programming in Lua</em>.
+

+

+

+
<h1>2 &ndash; <a name="2">Basic Concepts</a></h1>
+

+
<p>
+
This section describes the basic concepts of the language.
+

+

+

+
<h2>2.1 &ndash; <a name="2.1">Values and Types</a></h2>
+

+
<p>
+
Lua is a <em>dynamically typed language</em>.
+
This means that
+
variables do not have types; only values do.
+
There are no type definitions in the language.
+
All values carry their own type.
+

+

+
<p>
+
All values in Lua are <em>first-class values</em>.
+
This means that all values can be stored in variables,
+
passed as arguments to other functions, and returned as results.
+

+

+
<p>
+
There are eight basic types in Lua:
+
<em>nil</em>, <em>boolean</em>, <em>number</em>,
+
<em>string</em>, <em>function</em>, <em>userdata</em>,
+
<em>thread</em>, and <em>table</em>.
+
The type <em>nil</em> has one single value, <b>nil</b>,
+
whose main property is to be different from any other value;
+
it usually represents the absence of a useful value.
+
The type <em>boolean</em> has two values, <b>false</b> and <b>true</b>.
+
Both <b>nil</b> and <b>false</b> make a condition false;
+
any other value makes it true.
+
The type <em>number</em> represents both
+
integer numbers and real (floating-point) numbers.
+
The type <em>string</em> represents immutable sequences of bytes.
+

+
Lua is 8-bit clean:
+
strings can contain any 8-bit value,
+
including embedded zeros ('<code>\0</code>').
+
Lua is also encoding-agnostic;
+
it makes no assumptions about the contents of a string.
+

+

+
<p>
+
The type <em>number</em> uses two internal representations,
+
or two subtypes,
+
one called <em>integer</em> and the other called <em>float</em>.
+
Lua has explicit rules about when each representation is used,
+
but it also converts between them automatically as needed (see <a href="#3.4.3">&sect;3.4.3</a>).
+
Therefore,
+
the programmer may choose to mostly ignore the difference
+
between integers and floats
+
or to assume complete control over the representation of each number.
+
Standard Lua uses 64-bit integers and double-precision (64-bit) floats,
+
but you can also compile Lua so that it
+
uses 32-bit integers and/or single-precision (32-bit) floats.
+
The option with 32 bits for both integers and floats
+
is particularly attractive
+
for small machines and embedded systems.
+
(See macro <code>LUA_32BITS</code> in file <code>luaconf.h</code>.)
+

+

+
<p>
+
Lua can call (and manipulate) functions written in Lua and
+
functions written in C (see <a href="#3.4.10">&sect;3.4.10</a>).
+
Both are represented by the type <em>function</em>.
+

+

+
<p>
+
The type <em>userdata</em> is provided to allow arbitrary C&nbsp;data to
+
be stored in Lua variables.
+
A userdata value represents a block of raw memory.
+
There are two kinds of userdata:
+
<em>full userdata</em>,
+
which is an object with a block of memory managed by Lua,
+
and <em>light userdata</em>,
+
which is simply a C&nbsp;pointer value.
+
Userdata has no predefined operations in Lua,
+
except assignment and identity test.
+
By using <em>metatables</em>,
+
the programmer can define operations for full userdata values
+
(see <a href="#2.4">&sect;2.4</a>).
+
Userdata values cannot be created or modified in Lua,
+
only through the C&nbsp;API.
+
This guarantees the integrity of data owned by the host program.
+

+

+
<p>
+
The type <em>thread</em> represents independent threads of execution
+
and it is used to implement coroutines (see <a href="#2.6">&sect;2.6</a>).
+
Lua threads are not related to operating-system threads.
+
Lua supports coroutines on all systems,
+
even those that do not support threads natively.
+

+

+
<p>
+
The type <em>table</em> implements associative arrays,
+
that is, arrays that can have as indices not only numbers,
+
but any Lua value except <b>nil</b> and NaN.
+
(<em>Not a Number</em> is a special value used to represent
+
undefined or unrepresentable numerical results, such as <code>0/0</code>.)
+
Tables can be <em>heterogeneous</em>;
+
that is, they can contain values of all types (except <b>nil</b>).
+
Any key with value <b>nil</b> is not considered part of the table.
+
Conversely, any key that is not part of a table has
+
an associated value <b>nil</b>.
+

+

+
<p>
+
Tables are the sole data-structuring mechanism in Lua;
+
they can be used to represent ordinary arrays, lists,
+
symbol tables, sets, records, graphs, trees, etc.
+
To represent records, Lua uses the field name as an index.
+
The language supports this representation by
+
providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>.
+
There are several convenient ways to create tables in Lua
+
(see <a href="#3.4.9">&sect;3.4.9</a>).
+

+

+
<p>
+
Like indices,
+
the values of table fields can be of any type.
+
In particular,
+
because functions are first-class values,
+
table fields can contain functions.
+
Thus tables can also carry <em>methods</em> (see <a href="#3.4.11">&sect;3.4.11</a>).
+

+

+
<p>
+
The indexing of tables follows
+
the definition of raw equality in the language.
+
The expressions <code>a[i]</code> and <code>a[j]</code>
+
denote the same table element
+
if and only if <code>i</code> and <code>j</code> are raw equal
+
(that is, equal without metamethods).
+
In particular, floats with integral values
+
are equal to their respective integers
+
(e.g., <code>1.0 == 1</code>).
+
To avoid ambiguities,
+
any float with integral value used as a key
+
is converted to its respective integer.
+
For instance, if you write <code>a[2.0] = true</code>,
+
the actual key inserted into the table will be the
+
integer <code>2</code>.
+
(On the other hand,
+
2 and "<code>2</code>" are different Lua values and therefore
+
denote different table entries.)
+

+

+
<p>
+
Tables, functions, threads, and (full) userdata values are <em>objects</em>:
+
variables do not actually <em>contain</em> these values,
+
only <em>references</em> to them.
+
Assignment, parameter passing, and function returns
+
always manipulate references to such values;
+
these operations do not imply any kind of copy.
+

+

+
<p>
+
The library function <a href="#pdf-type"><code>type</code></a> returns a string describing the type
+
of a given value (see <a href="#6.1">&sect;6.1</a>).
+

+

+

+

+

+
<h2>2.2 &ndash; <a name="2.2">Environments and the Global Environment</a></h2>
+

+
<p>
+
As will be discussed in <a href="#3.2">&sect;3.2</a> and <a href="#3.3.3">&sect;3.3.3</a>,
+
any reference to a free name
+
(that is, a name not bound to any declaration) <code>var</code>
+
is syntactically translated to <code>_ENV.var</code>.
+
Moreover, every chunk is compiled in the scope of
+
an external local variable named <code>_ENV</code> (see <a href="#3.3.2">&sect;3.3.2</a>),
+
so <code>_ENV</code> itself is never a free name in a chunk.
+

+

+
<p>
+
Despite the existence of this external <code>_ENV</code> variable and
+
the translation of free names,
+
<code>_ENV</code> is a completely regular name.
+
In particular,
+
you can define new variables and parameters with that name.
+
Each reference to a free name uses the <code>_ENV</code> that is
+
visible at that point in the program,
+
following the usual visibility rules of Lua (see <a href="#3.5">&sect;3.5</a>).
+

+

+
<p>
+
Any table used as the value of <code>_ENV</code> is called an <em>environment</em>.
+

+

+
<p>
+
Lua keeps a distinguished environment called the <em>global environment</em>.
+
This value is kept at a special index in the C registry (see <a href="#4.5">&sect;4.5</a>).
+
In Lua, the global variable <a href="#pdf-_G"><code>_G</code></a> is initialized with this same value.
+
(<a href="#pdf-_G"><code>_G</code></a> is never used internally.)
+

+

+
<p>
+
When Lua loads a chunk,
+
the default value for its <code>_ENV</code> upvalue
+
is the global environment (see <a href="#pdf-load"><code>load</code></a>).
+
Therefore, by default,
+
free names in Lua code refer to entries in the global environment
+
(and, therefore, they are also called <em>global variables</em>).
+
Moreover, all standard libraries are loaded in the global environment
+
and some functions there operate on that environment.
+
You can use <a href="#pdf-load"><code>load</code></a> (or <a href="#pdf-loadfile"><code>loadfile</code></a>)
+
to load a chunk with a different environment.
+
(In C, you have to load the chunk and then change the value
+
of its first upvalue.)
+

+

+

+

+

+
<h2>2.3 &ndash; <a name="2.3">Error Handling</a></h2>
+

+
<p>
+
Because Lua is an embedded extension language,
+
all Lua actions start from C&nbsp;code in the host program
+
calling a function from the Lua library.
+
(When you use Lua standalone,
+
the <code>lua</code> application is the host program.)
+
Whenever an error occurs during
+
the compilation or execution of a Lua chunk,
+
control returns to the host,
+
which can take appropriate measures
+
(such as printing an error message).
+

+

+
<p>
+
Lua code can explicitly generate an error by calling the
+
<a href="#pdf-error"><code>error</code></a> function.
+
If you need to catch errors in Lua,
+
you can use <a href="#pdf-pcall"><code>pcall</code></a> or <a href="#pdf-xpcall"><code>xpcall</code></a>
+
to call a given function in <em>protected mode</em>.
+

+

+
<p>
+
Whenever there is an error,
+
an <em>error object</em> (also called an <em>error message</em>)
+
is propagated with information about the error.
+
Lua itself only generates errors whose error object is a string,
+
but programs may generate errors with
+
any value as the error object.
+
It is up to the Lua program or its host to handle such error objects.
+

+

+
<p>
+
When you use <a href="#pdf-xpcall"><code>xpcall</code></a> or <a href="#lua_pcall"><code>lua_pcall</code></a>,
+
you may give a <em>message handler</em>
+
to be called in case of errors.
+
This function is called with the original error object
+
and returns a new error object.
+
It is called before the error unwinds the stack,
+
so that it can gather more information about the error,
+
for instance by inspecting the stack and creating a stack traceback.
+
This message handler is still protected by the protected call;
+
so, an error inside the message handler
+
will call the message handler again.
+
If this loop goes on for too long,
+
Lua breaks it and returns an appropriate message.
+
(The message handler is called only for regular runtime errors.
+
It is not called for memory-allocation errors
+
nor for errors while running finalizers.)
+

+

+

+

+

+
<h2>2.4 &ndash; <a name="2.4">Metatables and Metamethods</a></h2>
+

+
<p>
+
Every value in Lua can have a <em>metatable</em>.
+
This <em>metatable</em> is an ordinary Lua table
+
that defines the behavior of the original value
+
under certain special operations.
+
You can change several aspects of the behavior
+
of operations over a value by setting specific fields in its metatable.
+
For instance, when a non-numeric value is the operand of an addition,
+
Lua checks for a function in the field "<code>__add</code>" of the value's metatable.
+
If it finds one,
+
Lua calls this function to perform the addition.
+

+

+
<p>
+
The key for each event in a metatable is a string
+
with the event name prefixed by two underscores;
+
the corresponding values are called <em>metamethods</em>.
+
In the previous example, the key is "<code>__add</code>"
+
and the metamethod is the function that performs the addition.
+
Unless stated otherwise,
+
metamethods should be function values.
+

+

+
<p>
+
You can query the metatable of any value
+
using the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function.
+
Lua queries metamethods in metatables using a raw access (see <a href="#pdf-rawget"><code>rawget</code></a>).
+
So, to retrieve the metamethod for event <code>ev</code> in object <code>o</code>,
+
Lua does the equivalent to the following code:
+

+
<pre>
+
     rawget(getmetatable(<em>o</em>) or {}, "__<em>ev</em>")
+
</pre>
+

+
<p>
+
You can replace the metatable of tables
+
using the <a href="#pdf-setmetatable"><code>setmetatable</code></a> function.
+
You cannot change the metatable of other types from Lua code
+
(except by using the debug library (<a href="#6.10">&sect;6.10</a>));
+
you should use the C&nbsp;API for that.
+

+

+
<p>
+
Tables and full userdata have individual metatables
+
(although multiple tables and userdata can share their metatables).
+
Values of all other types share one single metatable per type;
+
that is, there is one single metatable for all numbers,
+
one for all strings, etc.
+
By default, a value has no metatable,
+
but the string library sets a metatable for the string type (see <a href="#6.4">&sect;6.4</a>).
+

+

+
<p>
+
A metatable controls how an object behaves in
+
arithmetic operations, bitwise operations,
+
order comparisons, concatenation, length operation, calls, and indexing.
+
A metatable also can define a function to be called
+
when a userdata or a table is garbage collected (<a href="#2.5">&sect;2.5</a>).
+

+

+
<p>
+
For the unary operators (negation, length, and bitwise NOT),
+
the metamethod is computed and called with a dummy second operand,
+
equal to the first one.
+
This extra operand is only to simplify Lua's internals
+
(by making these operators behave like a binary operation)
+
and may be removed in future versions.
+
(For most uses this extra operand is irrelevant.)
+

+

+
<p>
+
A detailed list of events controlled by metatables is given next.
+
Each operation is identified by its corresponding key.
+

+

+

+
<ul>
+

+
<li><b><code>__add</code>: </b>
+
the addition (<code>+</code>) operation.
+
If any operand for an addition is not a number
+
(nor a string coercible to a number),
+
Lua will try to call a metamethod.
+
First, Lua will check the first operand (even if it is valid).
+
If that operand does not define a metamethod for <code>__add</code>,
+
then Lua will check the second operand.
+
If Lua can find a metamethod,
+
it calls the metamethod with the two operands as arguments,
+
and the result of the call
+
(adjusted to one value)
+
is the result of the operation.
+
Otherwise,
+
it raises an error.
+
</li>
+

+
<li><b><code>__sub</code>: </b>
+
the subtraction (<code>-</code>) operation.
+
Behavior similar to the addition operation.
+
</li>
+

+
<li><b><code>__mul</code>: </b>
+
the multiplication (<code>*</code>) operation.
+
Behavior similar to the addition operation.
+
</li>
+

+
<li><b><code>__div</code>: </b>
+
the division (<code>/</code>) operation.
+
Behavior similar to the addition operation.
+
</li>
+

+
<li><b><code>__mod</code>: </b>
+
the modulo (<code>%</code>) operation.
+
Behavior similar to the addition operation.
+
</li>
+

+
<li><b><code>__pow</code>: </b>
+
the exponentiation (<code>^</code>) operation.
+
Behavior similar to the addition operation.
+
</li>
+

+
<li><b><code>__unm</code>: </b>
+
the negation (unary <code>-</code>) operation.
+
Behavior similar to the addition operation.
+
</li>
+

+
<li><b><code>__idiv</code>: </b>
+
the floor division (<code>//</code>) operation.
+
Behavior similar to the addition operation.
+
</li>
+

+
<li><b><code>__band</code>: </b>
+
the bitwise AND (<code>&amp;</code>) operation.
+
Behavior similar to the addition operation,
+
except that Lua will try a metamethod
+
if any operand is neither an integer
+
nor a value coercible to an integer (see <a href="#3.4.3">&sect;3.4.3</a>).
+
</li>
+

+
<li><b><code>__bor</code>: </b>
+
the bitwise OR (<code>|</code>) operation.
+
Behavior similar to the bitwise AND operation.
+
</li>
+

+
<li><b><code>__bxor</code>: </b>
+
the bitwise exclusive OR (binary <code>~</code>) operation.
+
Behavior similar to the bitwise AND operation.
+
</li>
+

+
<li><b><code>__bnot</code>: </b>
+
the bitwise NOT (unary <code>~</code>) operation.
+
Behavior similar to the bitwise AND operation.
+
</li>
+

+
<li><b><code>__shl</code>: </b>
+
the bitwise left shift (<code>&lt;&lt;</code>) operation.
+
Behavior similar to the bitwise AND operation.
+
</li>
+

+
<li><b><code>__shr</code>: </b>
+
the bitwise right shift (<code>&gt;&gt;</code>) operation.
+
Behavior similar to the bitwise AND operation.
+
</li>
+

+
<li><b><code>__concat</code>: </b>
+
the concatenation (<code>..</code>) operation.
+
Behavior similar to the addition operation,
+
except that Lua will try a metamethod
+
if any operand is neither a string nor a number
+
(which is always coercible to a string).
+
</li>
+

+
<li><b><code>__len</code>: </b>
+
the length (<code>#</code>) operation.
+
If the object is not a string,
+
Lua will try its metamethod.
+
If there is a metamethod,
+
Lua calls it with the object as argument,
+
and the result of the call
+
(always adjusted to one value)
+
is the result of the operation.
+
If there is no metamethod but the object is a table,
+
then Lua uses the table length operation (see <a href="#3.4.7">&sect;3.4.7</a>).
+
Otherwise, Lua raises an error.
+
</li>
+

+
<li><b><code>__eq</code>: </b>
+
the equal (<code>==</code>) operation.
+
Behavior similar to the addition operation,
+
except that Lua will try a metamethod only when the values
+
being compared are either both tables or both full userdata
+
and they are not primitively equal.
+
The result of the call is always converted to a boolean.
+
</li>
+

+
<li><b><code>__lt</code>: </b>
+
the less than (<code>&lt;</code>) operation.
+
Behavior similar to the addition operation,
+
except that Lua will try a metamethod only when the values
+
being compared are neither both numbers nor both strings.
+
The result of the call is always converted to a boolean.
+
</li>
+

+
<li><b><code>__le</code>: </b>
+
the less equal (<code>&lt;=</code>) operation.
+
Unlike other operations,
+
the less-equal operation can use two different events.
+
First, Lua looks for the <code>__le</code> metamethod in both operands,
+
like in the less than operation.
+
If it cannot find such a metamethod,
+
then it will try the <code>__lt</code> metamethod,
+
assuming that <code>a &lt;= b</code> is equivalent to <code>not (b &lt; a)</code>.
+
As with the other comparison operators,
+
the result is always a boolean.
+
(This use of the <code>__lt</code> event can be removed in future versions;
+
it is also slower than a real <code>__le</code> metamethod.)
+
</li>
+

+
<li><b><code>__index</code>: </b>
+
The indexing access operation <code>table[key]</code>.
+
This event happens when <code>table</code> is not a table or
+
when <code>key</code> is not present in <code>table</code>.
+
The metamethod is looked up in <code>table</code>.
+

+

+
<p>
+
Despite the name,
+
the metamethod for this event can be either a function or a table.
+
If it is a function,
+
it is called with <code>table</code> and <code>key</code> as arguments,
+
and the result of the call
+
(adjusted to one value)
+
is the result of the operation.
+
If it is a table,
+
the final result is the result of indexing this table with <code>key</code>.
+
(This indexing is regular, not raw,
+
and therefore can trigger another metamethod.)
+
</li>
+

+
<li><b><code>__newindex</code>: </b>
+
The indexing assignment <code>table[key] = value</code>.
+
Like the index event,
+
this event happens when <code>table</code> is not a table or
+
when <code>key</code> is not present in <code>table</code>.
+
The metamethod is looked up in <code>table</code>.
+

+

+
<p>
+
Like with indexing,
+
the metamethod for this event can be either a function or a table.
+
If it is a function,
+
it is called with <code>table</code>, <code>key</code>, and <code>value</code> as arguments.
+
If it is a table,
+
Lua does an indexing assignment to this table with the same key and value.
+
(This assignment is regular, not raw,
+
and therefore can trigger another metamethod.)
+

+

+
<p>
+
Whenever there is a <code>__newindex</code> metamethod,
+
Lua does not perform the primitive assignment.
+
(If necessary,
+
the metamethod itself can call <a href="#pdf-rawset"><code>rawset</code></a>
+
to do the assignment.)
+
</li>
+

+
<li><b><code>__call</code>: </b>
+
The call operation <code>func(args)</code>.
+
This event happens when Lua tries to call a non-function value
+
(that is, <code>func</code> is not a function).
+
The metamethod is looked up in <code>func</code>.
+
If present,
+
the metamethod is called with <code>func</code> as its first argument,
+
followed by the arguments of the original call (<code>args</code>).
+
All results of the call
+
are the result of the operation.
+
(This is the only metamethod that allows multiple results.)
+
</li>
+

+
</ul>
+

+
<p>
+
It is a good practice to add all needed metamethods to a table
+
before setting it as a metatable of some object.
+
In particular, the <code>__gc</code> metamethod works only when this order
+
is followed (see <a href="#2.5.1">&sect;2.5.1</a>).
+

+

+
<p>
+
Because metatables are regular tables,
+
they can contain arbitrary fields,
+
not only the event names defined above.
+
Some functions in the standard library
+
(e.g., <a href="#pdf-tostring"><code>tostring</code></a>)
+
use other fields in metatables for their own purposes.
+

+

+

+

+

+
<h2>2.5 &ndash; <a name="2.5">Garbage Collection</a></h2>
+

+
<p>
+
Lua performs automatic memory management.
+
This means that
+
you do not have to worry about allocating memory for new objects
+
or freeing it when the objects are no longer needed.
+
Lua manages memory automatically by running
+
a <em>garbage collector</em> to collect all <em>dead objects</em>
+
(that is, objects that are no longer accessible from Lua).
+
All memory used by Lua is subject to automatic management:
+
strings, tables, userdata, functions, threads, internal structures, etc.
+

+

+
<p>
+
Lua implements an incremental mark-and-sweep collector.
+
It uses two numbers to control its garbage-collection cycles:
+
the <em>garbage-collector pause</em> and
+
the <em>garbage-collector step multiplier</em>.
+
Both use percentage points as units
+
(e.g., a value of 100 means an internal value of 1).
+

+

+
<p>
+
The garbage-collector pause
+
controls how long the collector waits before starting a new cycle.
+
Larger values make the collector less aggressive.
+
Values smaller than 100 mean the collector will not wait to
+
start a new cycle.
+
A value of 200 means that the collector waits for the total memory in use
+
to double before starting a new cycle.
+

+

+
<p>
+
The garbage-collector step multiplier
+
controls the relative speed of the collector relative to
+
memory allocation.
+
Larger values make the collector more aggressive but also increase
+
the size of each incremental step.
+
You should not use values smaller than 100,
+
because they make the collector too slow and
+
can result in the collector never finishing a cycle.
+
The default is 200,
+
which means that the collector runs at "twice"
+
the speed of memory allocation.
+

+

+
<p>
+
If you set the step multiplier to a very large number
+
(larger than 10% of the maximum number of
+
bytes that the program may use),
+
the collector behaves like a stop-the-world collector.
+
If you then set the pause to 200,
+
the collector behaves as in old Lua versions,
+
doing a complete collection every time Lua doubles its
+
memory usage.
+

+

+
<p>
+
You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C
+
or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua.
+
You can also use these functions to control
+
the collector directly (e.g., stop and restart it).
+

+

+

+
<h3>2.5.1 &ndash; <a name="2.5.1">Garbage-Collection Metamethods</a></h3>
+

+
<p>
+
You can set garbage-collector metamethods for tables
+
and, using the C&nbsp;API,
+
for full userdata (see <a href="#2.4">&sect;2.4</a>).
+
These metamethods are also called <em>finalizers</em>.
+
Finalizers allow you to coordinate Lua's garbage collection
+
with external resource management
+
(such as closing files, network or database connections,
+
or freeing your own memory).
+

+

+
<p>
+
For an object (table or userdata) to be finalized when collected,
+
you must <em>mark</em> it for finalization.
+

+
You mark an object for finalization when you set its metatable
+
and the metatable has a field indexed by the string "<code>__gc</code>".
+
Note that if you set a metatable without a <code>__gc</code> field
+
and later create that field in the metatable,
+
the object will not be marked for finalization.
+

+

+
<p>
+
When a marked object becomes garbage,
+
it is not collected immediately by the garbage collector.
+
Instead, Lua puts it in a list.
+
After the collection,
+
Lua goes through that list.
+
For each object in the list,
+
it checks the object's <code>__gc</code> metamethod:
+
If it is a function,
+
Lua calls it with the object as its single argument;
+
if the metamethod is not a function,
+
Lua simply ignores it.
+

+

+
<p>
+
At the end of each garbage-collection cycle,
+
the finalizers for objects are called in
+
the reverse order that the objects were marked for finalization,
+
among those collected in that cycle;
+
that is, the first finalizer to be called is the one associated
+
with the object marked last in the program.
+
The execution of each finalizer may occur at any point during
+
the execution of the regular code.
+

+

+
<p>
+
Because the object being collected must still be used by the finalizer,
+
that object (and other objects accessible only through it)
+
must be <em>resurrected</em> by Lua.
+
Usually, this resurrection is transient,
+
and the object memory is freed in the next garbage-collection cycle.
+
However, if the finalizer stores the object in some global place
+
(e.g., a global variable),
+
then the resurrection is permanent.
+
Moreover, if the finalizer marks a finalizing object for finalization again,
+
its finalizer will be called again in the next cycle where the
+
object is unreachable.
+
In any case,
+
the object memory is freed only in a GC cycle where
+
the object is unreachable and not marked for finalization.
+

+

+
<p>
+
When you close a state (see <a href="#lua_close"><code>lua_close</code></a>),
+
Lua calls the finalizers of all objects marked for finalization,
+
following the reverse order that they were marked.
+
If any finalizer marks objects for collection during that phase,
+
these marks have no effect.
+

+

+

+

+

+
<h3>2.5.2 &ndash; <a name="2.5.2">Weak Tables</a></h3>
+

+
<p>
+
A <em>weak table</em> is a table whose elements are
+
<em>weak references</em>.
+
A weak reference is ignored by the garbage collector.
+
In other words,
+
if the only references to an object are weak references,
+
then the garbage collector will collect that object.
+

+

+
<p>
+
A weak table can have weak keys, weak values, or both.
+
A table with weak values allows the collection of its values,
+
but prevents the collection of its keys.
+
A table with both weak keys and weak values allows the collection of
+
both keys and values.
+
In any case, if either the key or the value is collected,
+
the whole pair is removed from the table.
+
The weakness of a table is controlled by the
+
<code>__mode</code> field of its metatable.
+
If the <code>__mode</code> field is a string containing the character&nbsp;'<code>k</code>',
+
the keys in the table are weak.
+
If <code>__mode</code> contains '<code>v</code>',
+
the values in the table are weak.
+

+

+
<p>
+
A table with weak keys and strong values
+
is also called an <em>ephemeron table</em>.
+
In an ephemeron table,
+
a value is considered reachable only if its key is reachable.
+
In particular,
+
if the only reference to a key comes through its value,
+
the pair is removed.
+

+

+
<p>
+
Any change in the weakness of a table may take effect only
+
at the next collect cycle.
+
In particular, if you change the weakness to a stronger mode,
+
Lua may still collect some items from that table
+
before the change takes effect.
+

+

+
<p>
+
Only objects that have an explicit construction
+
are removed from weak tables.
+
Values, such as numbers and light C&nbsp;functions,
+
are not subject to garbage collection,
+
and therefore are not removed from weak tables
+
(unless their associated values are collected).
+
Although strings are subject to garbage collection,
+
they do not have an explicit construction,
+
and therefore are not removed from weak tables.
+

+

+
<p>
+
Resurrected objects
+
(that is, objects being finalized
+
and objects accessible only through objects being finalized)
+
have a special behavior in weak tables.
+
They are removed from weak values before running their finalizers,
+
but are removed from weak keys only in the next collection
+
after running their finalizers, when such objects are actually freed.
+
This behavior allows the finalizer to access properties
+
associated with the object through weak tables.
+

+

+
<p>
+
If a weak table is among the resurrected objects in a collection cycle,
+
it may not be properly cleared until the next cycle.
+

+

+

+

+

+

+

+
<h2>2.6 &ndash; <a name="2.6">Coroutines</a></h2>
+

+
<p>
+
Lua supports coroutines,
+
also called <em>collaborative multithreading</em>.
+
A coroutine in Lua represents an independent thread of execution.
+
Unlike threads in multithread systems, however,
+
a coroutine only suspends its execution by explicitly calling
+
a yield function.
+

+

+
<p>
+
You create a coroutine by calling <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>.
+
Its sole argument is a function
+
that is the main function of the coroutine.
+
The <code>create</code> function only creates a new coroutine and
+
returns a handle to it (an object of type <em>thread</em>);
+
it does not start the coroutine.
+

+

+
<p>
+
You execute a coroutine by calling <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
+
When you first call <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
+
passing as its first argument
+
a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
+
the coroutine starts its execution by
+
calling its main function.
+
Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed
+
as arguments to that function.
+
After the coroutine starts running,
+
it runs until it terminates or <em>yields</em>.
+

+

+
<p>
+
A coroutine can terminate its execution in two ways:
+
normally, when its main function returns
+
(explicitly or implicitly, after the last instruction);
+
and abnormally, if there is an unprotected error.
+
In case of normal termination,
+
<a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>,
+
plus any values returned by the coroutine main function.
+
In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b>
+
plus an error object.
+

+

+
<p>
+
A coroutine yields by calling <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
+
When a coroutine yields,
+
the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns immediately,
+
even if the yield happens inside nested function calls
+
(that is, not in the main function,
+
but in a function directly or indirectly called by the main function).
+
In the case of a yield, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> also returns <b>true</b>,
+
plus any values passed to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
+
The next time you resume the same coroutine,
+
it continues its execution from the point where it yielded,
+
with the call to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a> returning any extra
+
arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
+

+

+
<p>
+
Like <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
+
the <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> function also creates a coroutine,
+
but instead of returning the coroutine itself,
+
it returns a function that, when called, resumes the coroutine.
+
Any arguments passed to this function
+
go as extra arguments to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
+
<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> returns all the values returned by <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
+
except the first one (the boolean error code).
+
Unlike <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
+
<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> does not catch errors;
+
any error is propagated to the caller.
+

+

+
<p>
+
As an example of how coroutines work,
+
consider the following code:
+

+
<pre>
+
     function foo (a)
+
       print("foo", a)
+
       return coroutine.yield(2*a)
+
     end
+
     
+
     co = coroutine.create(function (a,b)
+
           print("co-body", a, b)
+
           local r = foo(a+1)
+
           print("co-body", r)
+
           local r, s = coroutine.yield(a+b, a-b)
+
           print("co-body", r, s)
+
           return b, "end"
+
     end)
+
     
+
     print("main", coroutine.resume(co, 1, 10))
+
     print("main", coroutine.resume(co, "r"))
+
     print("main", coroutine.resume(co, "x", "y"))
+
     print("main", coroutine.resume(co, "x", "y"))
+
</pre><p>
+
When you run it, it produces the following output:
+

+
<pre>
+
     co-body 1       10
+
     foo     2
+
     main    true    4
+
     co-body r
+
     main    true    11      -9
+
     co-body x       y
+
     main    true    10      end
+
     main    false   cannot resume dead coroutine
+
</pre>
+

+
<p>
+
You can also create and manipulate coroutines through the C API:
+
see functions <a href="#lua_newthread"><code>lua_newthread</code></a>, <a href="#lua_resume"><code>lua_resume</code></a>,
+
and <a href="#lua_yield"><code>lua_yield</code></a>.
+

+

+

+

+

+
<h1>3 &ndash; <a name="3">The Language</a></h1>
+

+
<p>
+
This section describes the lexis, the syntax, and the semantics of Lua.
+
In other words,
+
this section describes
+
which tokens are valid,
+
how they can be combined,
+
and what their combinations mean.
+

+

+
<p>
+
Language constructs will be explained using the usual extended BNF notation,
+
in which
+
{<em>a</em>}&nbsp;means&nbsp;0 or more <em>a</em>'s, and
+
[<em>a</em>]&nbsp;means an optional <em>a</em>.
+
Non-terminals are shown like non-terminal,
+
keywords are shown like <b>kword</b>,
+
and other terminal symbols are shown like &lsquo;<b>=</b>&rsquo;.
+
The complete syntax of Lua can be found in <a href="#9">&sect;9</a>
+
at the end of this manual.
+

+

+

+
<h2>3.1 &ndash; <a name="3.1">Lexical Conventions</a></h2>
+

+
<p>
+
Lua is a free-form language.
+
It ignores spaces (including new lines) and comments
+
between lexical elements (tokens),
+
except as delimiters between names and keywords.
+

+

+
<p>
+
<em>Names</em>
+
(also called <em>identifiers</em>)
+
in Lua can be any string of letters,
+
digits, and underscores,
+
not beginning with a digit and
+
not being a reserved word.
+
Identifiers are used to name variables, table fields, and labels.
+

+

+
<p>
+
The following <em>keywords</em> are reserved
+
and cannot be used as names:
+

+

+
<pre>
+
     and       break     do        else      elseif    end
+
     false     for       function  goto      if        in
+
     local     nil       not       or        repeat    return
+
     then      true      until     while
+
</pre>
+

+
<p>
+
Lua is a case-sensitive language:
+
<code>and</code> is a reserved word, but <code>And</code> and <code>AND</code>
+
are two different, valid names.
+
As a convention,
+
programs should avoid creating
+
names that start with an underscore followed by
+
one or more uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>).
+

+

+
<p>
+
The following strings denote other tokens:
+

+
<pre>
+
     +     -     *     /     %     ^     #
+
     &amp;     ~     |     &lt;&lt;    &gt;&gt;    //
+
     ==    ~=    &lt;=    &gt;=    &lt;     &gt;     =
+
     (     )     {     }     [     ]     ::
+
     ;     :     ,     .     ..    ...
+
</pre>
+

+
<p>
+
A <em>short literal string</em>
+
can be delimited by matching single or double quotes,
+
and can contain the following C-like escape sequences:
+
'<code>\a</code>' (bell),
+
'<code>\b</code>' (backspace),
+
'<code>\f</code>' (form feed),
+
'<code>\n</code>' (newline),
+
'<code>\r</code>' (carriage return),
+
'<code>\t</code>' (horizontal tab),
+
'<code>\v</code>' (vertical tab),
+
'<code>\\</code>' (backslash),
+
'<code>\"</code>' (quotation mark [double quote]),
+
and '<code>\'</code>' (apostrophe [single quote]).
+
A backslash followed by a line break
+
results in a newline in the string.
+
The escape sequence '<code>\z</code>' skips the following span
+
of white-space characters,
+
including line breaks;
+
it is particularly useful to break and indent a long literal string
+
into multiple lines without adding the newlines and spaces
+
into the string contents.
+
A short literal string cannot contain unescaped line breaks
+
nor escapes not forming a valid escape sequence.
+

+

+
<p>
+
We can specify any byte in a short literal string by its numeric value
+
(including embedded zeros).
+
This can be done
+
with the escape sequence <code>\x<em>XX</em></code>,
+
where <em>XX</em> is a sequence of exactly two hexadecimal digits,
+
or with the escape sequence <code>\<em>ddd</em></code>,
+
where <em>ddd</em> is a sequence of up to three decimal digits.
+
(Note that if a decimal escape sequence is to be followed by a digit,
+
it must be expressed using exactly three digits.)
+

+

+
<p>
+
The UTF-8 encoding of a Unicode character
+
can be inserted in a literal string with
+
the escape sequence <code>\u{<em>XXX</em>}</code>
+
(note the mandatory enclosing brackets),
+
where <em>XXX</em> is a sequence of one or more hexadecimal digits
+
representing the character code point.
+

+

+
<p>
+
Literal strings can also be defined using a long format
+
enclosed by <em>long brackets</em>.
+
We define an <em>opening long bracket of level <em>n</em></em> as an opening
+
square bracket followed by <em>n</em> equal signs followed by another
+
opening square bracket.
+
So, an opening long bracket of level&nbsp;0 is written as <code>[[</code>, 
+
an opening long bracket of level&nbsp;1 is written as <code>[=[</code>, 
+
and so on.
+
A <em>closing long bracket</em> is defined similarly;
+
for instance,
+
a closing long bracket of level&nbsp;4 is written as  <code>]====]</code>.
+
A <em>long literal</em> starts with an opening long bracket of any level and
+
ends at the first closing long bracket of the same level.
+
It can contain any text except a closing bracket of the same level.
+
Literals in this bracketed form can run for several lines,
+
do not interpret any escape sequences,
+
and ignore long brackets of any other level.
+
Any kind of end-of-line sequence
+
(carriage return, newline, carriage return followed by newline,
+
or newline followed by carriage return)
+
is converted to a simple newline.
+

+

+
<p>
+
For convenience,
+
when the opening long bracket is immediately followed by a newline,
+
the newline is not included in the string.
+
As an example, in a system using ASCII
+
(in which '<code>a</code>' is coded as&nbsp;97,
+
newline is coded as&nbsp;10, and '<code>1</code>' is coded as&nbsp;49),
+
the five literal strings below denote the same string:
+

+
<pre>
+
     a = 'alo\n123"'
+
     a = "alo\n123\""
+
     a = '\97lo\10\04923"'
+
     a = [[alo
+
     123"]]
+
     a = [==[
+
     alo
+
     123"]==]
+
</pre>
+

+
<p>
+
Any byte in a literal string not
+
explicitly affected by the previous rules represents itself.
+
However, Lua opens files for parsing in text mode,
+
and the system file functions may have problems with
+
some control characters.
+
So, it is safer to represent
+
non-text data as a quoted literal with
+
explicit escape sequences for the non-text characters.
+

+

+
<p>
+
A <em>numeric constant</em> (or <em>numeral</em>)
+
can be written with an optional fractional part
+
and an optional decimal exponent,
+
marked by a letter '<code>e</code>' or '<code>E</code>'.
+
Lua also accepts hexadecimal constants,
+
which start with <code>0x</code> or <code>0X</code>.
+
Hexadecimal constants also accept an optional fractional part
+
plus an optional binary exponent,
+
marked by a letter '<code>p</code>' or '<code>P</code>'.
+
A numeric constant with a radix point or an exponent
+
denotes a float;
+
otherwise,
+
if its value fits in an integer,
+
it denotes an integer.
+
Examples of valid integer constants are
+

+
<pre>
+
     3   345   0xff   0xBEBADA
+
</pre><p>
+
Examples of valid float constants are
+

+
<pre>
+
     3.0     3.1416     314.16e-2     0.31416E1     34e1
+
     0x0.1E  0xA23p-4   0X1.921FB54442D18P+1
+
</pre>
+

+
<p>
+
A <em>comment</em> starts with a double hyphen (<code>--</code>)
+
anywhere outside a string.
+
If the text immediately after <code>--</code> is not an opening long bracket,
+
the comment is a <em>short comment</em>,
+
which runs until the end of the line.
+
Otherwise, it is a <em>long comment</em>,
+
which runs until the corresponding closing long bracket.
+
Long comments are frequently used to disable code temporarily.
+

+

+

+

+

+
<h2>3.2 &ndash; <a name="3.2">Variables</a></h2>
+

+
<p>
+
Variables are places that store values.
+
There are three kinds of variables in Lua:
+
global variables, local variables, and table fields.
+

+

+
<p>
+
A single name can denote a global variable or a local variable
+
(or a function's formal parameter,
+
which is a particular kind of local variable):
+

+
<pre>
+
	var ::= Name
+
</pre><p>
+
Name denotes identifiers, as defined in <a href="#3.1">&sect;3.1</a>.
+

+

+
<p>
+
Any variable name is assumed to be global unless explicitly declared
+
as a local (see <a href="#3.3.7">&sect;3.3.7</a>).
+
Local variables are <em>lexically scoped</em>:
+
local variables can be freely accessed by functions
+
defined inside their scope (see <a href="#3.5">&sect;3.5</a>).
+

+

+
<p>
+
Before the first assignment to a variable, its value is <b>nil</b>.
+

+

+
<p>
+
Square brackets are used to index a table:
+

+
<pre>
+
	var ::= prefixexp &lsquo;<b>[</b>&rsquo; exp &lsquo;<b>]</b>&rsquo;
+
</pre><p>
+
The meaning of accesses to table fields can be changed via metatables
+
(see <a href="#2.4">&sect;2.4</a>).
+

+

+
<p>
+
The syntax <code>var.Name</code> is just syntactic sugar for
+
<code>var["Name"]</code>:
+

+
<pre>
+
	var ::= prefixexp &lsquo;<b>.</b>&rsquo; Name
+
</pre>
+

+
<p>
+
An access to a global variable <code>x</code>
+
is equivalent to <code>_ENV.x</code>.
+
Due to the way that chunks are compiled,
+
<code>_ENV</code> is never a global name (see <a href="#2.2">&sect;2.2</a>).
+

+

+

+

+

+
<h2>3.3 &ndash; <a name="3.3">Statements</a></h2>
+

+
<p>
+
Lua supports an almost conventional set of statements,
+
similar to those in Pascal or C.
+
This set includes
+
assignments, control structures, function calls,
+
and variable declarations.
+

+

+

+
<h3>3.3.1 &ndash; <a name="3.3.1">Blocks</a></h3>
+

+
<p>
+
A block is a list of statements,
+
which are executed sequentially:
+

+
<pre>
+
	block ::= {stat}
+
</pre><p>
+
Lua has <em>empty statements</em>
+
that allow you to separate statements with semicolons,
+
start a block with a semicolon
+
or write two semicolons in sequence:
+

+
<pre>
+
	stat ::= &lsquo;<b>;</b>&rsquo;
+
</pre>
+

+
<p>
+
Function calls and assignments
+
can start with an open parenthesis.
+
This possibility leads to an ambiguity in Lua's grammar.
+
Consider the following fragment:
+

+
<pre>
+
     a = b + c
+
     (print or io.write)('done')
+
</pre><p>
+
The grammar could see it in two ways:
+

+
<pre>
+
     a = b + c(print or io.write)('done')
+
     
+
     a = b + c; (print or io.write)('done')
+
</pre><p>
+
The current parser always sees such constructions
+
in the first way,
+
interpreting the open parenthesis
+
as the start of the arguments to a call.
+
To avoid this ambiguity,
+
it is a good practice to always precede with a semicolon
+
statements that start with a parenthesis:
+

+
<pre>
+
     ;(print or io.write)('done')
+
</pre>
+

+
<p>
+
A block can be explicitly delimited to produce a single statement:
+

+
<pre>
+
	stat ::= <b>do</b> block <b>end</b>
+
</pre><p>
+
Explicit blocks are useful
+
to control the scope of variable declarations.
+
Explicit blocks are also sometimes used to
+
add a <b>return</b> statement in the middle
+
of another block (see <a href="#3.3.4">&sect;3.3.4</a>).
+

+

+

+

+

+
<h3>3.3.2 &ndash; <a name="3.3.2">Chunks</a></h3>
+

+
<p>
+
The unit of compilation of Lua is called a <em>chunk</em>.
+
Syntactically,
+
a chunk is simply a block:
+

+
<pre>
+
	chunk ::= block
+
</pre>
+

+
<p>
+
Lua handles a chunk as the body of an anonymous function
+
with a variable number of arguments
+
(see <a href="#3.4.11">&sect;3.4.11</a>).
+
As such, chunks can define local variables,
+
receive arguments, and return values.
+
Moreover, such anonymous function is compiled as in the
+
scope of an external local variable called <code>_ENV</code> (see <a href="#2.2">&sect;2.2</a>).
+
The resulting function always has <code>_ENV</code> as its only upvalue,
+
even if it does not use that variable.
+

+

+
<p>
+
A chunk can be stored in a file or in a string inside the host program.
+
To execute a chunk,
+
Lua first <em>loads</em> it,
+
precompiling the chunk's code into instructions for a virtual machine,
+
and then Lua executes the compiled code
+
with an interpreter for the virtual machine.
+

+

+
<p>
+
Chunks can also be precompiled into binary form;
+
see program <code>luac</code> and function <a href="#pdf-string.dump"><code>string.dump</code></a> for details.
+
Programs in source and compiled forms are interchangeable;
+
Lua automatically detects the file type and acts accordingly (see <a href="#pdf-load"><code>load</code></a>).
+

+

+

+

+

+
<h3>3.3.3 &ndash; <a name="3.3.3">Assignment</a></h3>
+

+
<p>
+
Lua allows multiple assignments.
+
Therefore, the syntax for assignment
+
defines a list of variables on the left side
+
and a list of expressions on the right side.
+
The elements in both lists are separated by commas:
+

+
<pre>
+
	stat ::= varlist &lsquo;<b>=</b>&rsquo; explist
+
	varlist ::= var {&lsquo;<b>,</b>&rsquo; var}
+
	explist ::= exp {&lsquo;<b>,</b>&rsquo; exp}
+
</pre><p>
+
Expressions are discussed in <a href="#3.4">&sect;3.4</a>.
+

+

+
<p>
+
Before the assignment,
+
the list of values is <em>adjusted</em> to the length of
+
the list of variables.
+
If there are more values than needed,
+
the excess values are thrown away.
+
If there are fewer values than needed,
+
the list is extended with as many  <b>nil</b>'s as needed.
+
If the list of expressions ends with a function call,
+
then all values returned by that call enter the list of values,
+
before the adjustment
+
(except when the call is enclosed in parentheses; see <a href="#3.4">&sect;3.4</a>).
+

+

+
<p>
+
The assignment statement first evaluates all its expressions
+
and only then the assignments are performed.
+
Thus the code
+

+
<pre>
+
     i = 3
+
     i, a[i] = i+1, 20
+
</pre><p>
+
sets <code>a[3]</code> to 20, without affecting <code>a[4]</code>
+
because the <code>i</code> in <code>a[i]</code> is evaluated (to 3)
+
before it is assigned&nbsp;4.
+
Similarly, the line
+

+
<pre>
+
     x, y = y, x
+
</pre><p>
+
exchanges the values of <code>x</code> and <code>y</code>,
+
and
+

+
<pre>
+
     x, y, z = y, z, x
+
</pre><p>
+
cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</code>.
+

+

+
<p>
+
An assignment to a global name <code>x = val</code>
+
is equivalent to the assignment
+
<code>_ENV.x = val</code> (see <a href="#2.2">&sect;2.2</a>).
+

+

+
<p>
+
The meaning of assignments to table fields and
+
global variables (which are actually table fields, too)
+
can be changed via metatables (see <a href="#2.4">&sect;2.4</a>).
+

+

+

+

+

+
<h3>3.3.4 &ndash; <a name="3.3.4">Control Structures</a></h3><p>
+
The control structures
+
<b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and
+
familiar syntax:
+

+

+

+

+
<pre>
+
	stat ::= <b>while</b> exp <b>do</b> block <b>end</b>
+
	stat ::= <b>repeat</b> block <b>until</b> exp
+
	stat ::= <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b>
+
</pre><p>
+
Lua also has a <b>for</b> statement, in two flavors (see <a href="#3.3.5">&sect;3.3.5</a>).
+

+

+
<p>
+
The condition expression of a
+
control structure can return any value.
+
Both <b>false</b> and <b>nil</b> are considered false.
+
All values different from <b>nil</b> and <b>false</b> are considered true
+
(in particular, the number 0 and the empty string are also true).
+

+

+
<p>
+
In the <b>repeat</b>&ndash;<b>until</b> loop,
+
the inner block does not end at the <b>until</b> keyword,
+
but only after the condition.
+
So, the condition can refer to local variables
+
declared inside the loop block.
+

+

+
<p>
+
The <b>goto</b> statement transfers the program control to a label.
+
For syntactical reasons,
+
labels in Lua are considered statements too:
+

+

+

+
<pre>
+
	stat ::= <b>goto</b> Name
+
	stat ::= label
+
	label ::= &lsquo;<b>::</b>&rsquo; Name &lsquo;<b>::</b>&rsquo;
+
</pre>
+

+
<p>
+
A label is visible in the entire block where it is defined,
+
except
+
inside nested blocks where a label with the same name is defined and
+
inside nested functions.
+
A goto may jump to any visible label as long as it does not
+
enter into the scope of a local variable.
+

+

+
<p>
+
Labels and empty statements are called <em>void statements</em>,
+
as they perform no actions.
+

+

+
<p>
+
The <b>break</b> statement terminates the execution of a
+
<b>while</b>, <b>repeat</b>, or <b>for</b> loop,
+
skipping to the next statement after the loop:
+

+

+
<pre>
+
	stat ::= <b>break</b>
+
</pre><p>
+
A <b>break</b> ends the innermost enclosing loop.
+

+

+
<p>
+
The <b>return</b> statement is used to return values
+
from a function or a chunk
+
(which is an anonymous function).
+

+
Functions can return more than one value,
+
so the syntax for the <b>return</b> statement is
+

+
<pre>
+
	stat ::= <b>return</b> [explist] [&lsquo;<b>;</b>&rsquo;]
+
</pre>
+

+
<p>
+
The <b>return</b> statement can only be written
+
as the last statement of a block.
+
If it is really necessary to <b>return</b> in the middle of a block,
+
then an explicit inner block can be used,
+
as in the idiom <code>do return end</code>,
+
because now <b>return</b> is the last statement in its (inner) block.
+

+

+

+

+

+
<h3>3.3.5 &ndash; <a name="3.3.5">For Statement</a></h3>
+

+
<p>
+

+
The <b>for</b> statement has two forms:
+
one numerical and one generic.
+

+

+
<p>
+
The numerical <b>for</b> loop repeats a block of code while a
+
control variable runs through an arithmetic progression.
+
It has the following syntax:
+

+
<pre>
+
	stat ::= <b>for</b> Name &lsquo;<b>=</b>&rsquo; exp &lsquo;<b>,</b>&rsquo; exp [&lsquo;<b>,</b>&rsquo; exp] <b>do</b> block <b>end</b>
+
</pre><p>
+
The <em>block</em> is repeated for <em>name</em> starting at the value of
+
the first <em>exp</em>, until it passes the second <em>exp</em> by steps of the
+
third <em>exp</em>.
+
More precisely, a <b>for</b> statement like
+

+
<pre>
+
     for v = <em>e1</em>, <em>e2</em>, <em>e3</em> do <em>block</em> end
+
</pre><p>
+
is equivalent to the code:
+

+
<pre>
+
     do
+
       local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>)
+
       if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end
+
       <em>var</em> = <em>var</em> - <em>step</em>
+
       while true do
+
         <em>var</em> = <em>var</em> + <em>step</em>
+
         if (<em>step</em> &gt;= 0 and <em>var</em> &gt; <em>limit</em>) or (<em>step</em> &lt; 0 and <em>var</em> &lt; <em>limit</em>) then
+
           break
+
         end
+
         local v = <em>var</em>
+
         <em>block</em>
+
       end
+
     end
+
</pre>
+

+
<p>
+
Note the following:
+

+
<ul>
+

+
<li>
+
All three control expressions are evaluated only once,
+
before the loop starts.
+
They must all result in numbers.
+
</li>
+

+
<li>
+
<code><em>var</em></code>, <code><em>limit</em></code>, and <code><em>step</em></code> are invisible variables.
+
The names shown here are for explanatory purposes only.
+
</li>
+

+
<li>
+
If the third expression (the step) is absent,
+
then a step of&nbsp;1 is used.
+
</li>
+

+
<li>
+
You can use <b>break</b> and <b>goto</b> to exit a <b>for</b> loop.
+
</li>
+

+
<li>
+
The loop variable <code>v</code> is local to the loop body.
+
If you need its value after the loop,
+
assign it to another variable before exiting the loop.
+
</li>
+

+
</ul>
+

+
<p>
+
The generic <b>for</b> statement works over functions,
+
called <em>iterators</em>.
+
On each iteration, the iterator function is called to produce a new value,
+
stopping when this new value is <b>nil</b>.
+
The generic <b>for</b> loop has the following syntax:
+

+
<pre>
+
	stat ::= <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b>
+
	namelist ::= Name {&lsquo;<b>,</b>&rsquo; Name}
+
</pre><p>
+
A <b>for</b> statement like
+

+
<pre>
+
     for <em>var_1</em>, &middot;&middot;&middot;, <em>var_n</em> in <em>explist</em> do <em>block</em> end
+
</pre><p>
+
is equivalent to the code:
+

+
<pre>
+
     do
+
       local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em>
+
       while true do
+
         local <em>var_1</em>, &middot;&middot;&middot;, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>)
+
         if <em>var_1</em> == nil then break end
+
         <em>var</em> = <em>var_1</em>
+
         <em>block</em>
+
       end
+
     end
+
</pre><p>
+
Note the following:
+

+
<ul>
+

+
<li>
+
<code><em>explist</em></code> is evaluated only once.
+
Its results are an <em>iterator</em> function,
+
a <em>state</em>,
+
and an initial value for the first <em>iterator variable</em>.
+
</li>
+

+
<li>
+
<code><em>f</em></code>, <code><em>s</em></code>, and <code><em>var</em></code> are invisible variables.
+
The names are here for explanatory purposes only.
+
</li>
+

+
<li>
+
You can use <b>break</b> to exit a <b>for</b> loop.
+
</li>
+

+
<li>
+
The loop variables <code><em>var_i</em></code> are local to the loop;
+
you cannot use their values after the <b>for</b> ends.
+
If you need these values,
+
then assign them to other variables before breaking or exiting the loop.
+
</li>
+

+
</ul>
+

+

+

+

+
<h3>3.3.6 &ndash; <a name="3.3.6">Function Calls as Statements</a></h3><p>
+
To allow possible side-effects,
+
function calls can be executed as statements:
+

+
<pre>
+
	stat ::= functioncall
+
</pre><p>
+
In this case, all returned values are thrown away.
+
Function calls are explained in <a href="#3.4.10">&sect;3.4.10</a>.
+

+

+

+

+

+
<h3>3.3.7 &ndash; <a name="3.3.7">Local Declarations</a></h3><p>
+
Local variables can be declared anywhere inside a block.
+
The declaration can include an initial assignment:
+

+
<pre>
+
	stat ::= <b>local</b> namelist [&lsquo;<b>=</b>&rsquo; explist]
+
</pre><p>
+
If present, an initial assignment has the same semantics
+
of a multiple assignment (see <a href="#3.3.3">&sect;3.3.3</a>).
+
Otherwise, all variables are initialized with <b>nil</b>.
+

+

+
<p>
+
A chunk is also a block (see <a href="#3.3.2">&sect;3.3.2</a>),
+
and so local variables can be declared in a chunk outside any explicit block.
+

+

+
<p>
+
The visibility rules for local variables are explained in <a href="#3.5">&sect;3.5</a>.
+

+

+

+

+

+

+

+
<h2>3.4 &ndash; <a name="3.4">Expressions</a></h2>
+

+
<p>
+
The basic expressions in Lua are the following:
+

+
<pre>
+
	exp ::= prefixexp
+
	exp ::= <b>nil</b> | <b>false</b> | <b>true</b>
+
	exp ::= Numeral
+
	exp ::= LiteralString
+
	exp ::= functiondef
+
	exp ::= tableconstructor
+
	exp ::= &lsquo;<b>...</b>&rsquo;
+
	exp ::= exp binop exp
+
	exp ::= unop exp
+
	prefixexp ::= var | functioncall | &lsquo;<b>(</b>&rsquo; exp &lsquo;<b>)</b>&rsquo;
+
</pre>
+

+
<p>
+
Numerals and literal strings are explained in <a href="#3.1">&sect;3.1</a>;
+
variables are explained in <a href="#3.2">&sect;3.2</a>;
+
function definitions are explained in <a href="#3.4.11">&sect;3.4.11</a>;
+
function calls are explained in <a href="#3.4.10">&sect;3.4.10</a>;
+
table constructors are explained in <a href="#3.4.9">&sect;3.4.9</a>.
+
Vararg expressions,
+
denoted by three dots ('<code>...</code>'), can only be used when
+
directly inside a vararg function;
+
they are explained in <a href="#3.4.11">&sect;3.4.11</a>.
+

+

+
<p>
+
Binary operators comprise arithmetic operators (see <a href="#3.4.1">&sect;3.4.1</a>),
+
bitwise operators (see <a href="#3.4.2">&sect;3.4.2</a>),
+
relational operators (see <a href="#3.4.4">&sect;3.4.4</a>), logical operators (see <a href="#3.4.5">&sect;3.4.5</a>),
+
and the concatenation operator (see <a href="#3.4.6">&sect;3.4.6</a>).
+
Unary operators comprise the unary minus (see <a href="#3.4.1">&sect;3.4.1</a>),
+
the unary bitwise NOT (see <a href="#3.4.2">&sect;3.4.2</a>),
+
the unary logical <b>not</b> (see <a href="#3.4.5">&sect;3.4.5</a>),
+
and the unary <em>length operator</em> (see <a href="#3.4.7">&sect;3.4.7</a>).
+

+

+
<p>
+
Both function calls and vararg expressions can result in multiple values.
+
If a function call is used as a statement (see <a href="#3.3.6">&sect;3.3.6</a>),
+
then its return list is adjusted to zero elements,
+
thus discarding all returned values.
+
If an expression is used as the last (or the only) element
+
of a list of expressions,
+
then no adjustment is made
+
(unless the expression is enclosed in parentheses).
+
In all other contexts,
+
Lua adjusts the result list to one element,
+
either discarding all values except the first one
+
or adding a single <b>nil</b> if there are no values.
+

+

+
<p>
+
Here are some examples:
+

+
<pre>
+
     f()                -- adjusted to 0 results
+
     g(f(), x)          -- f() is adjusted to 1 result
+
     g(x, f())          -- g gets x plus all results from f()
+
     a,b,c = f(), x     -- f() is adjusted to 1 result (c gets nil)
+
     a,b = ...          -- a gets the first vararg argument, b gets
+
                        -- the second (both a and b can get nil if there
+
                        -- is no corresponding vararg argument)
+
     
+
     a,b,c = x, f()     -- f() is adjusted to 2 results
+
     a,b,c = f()        -- f() is adjusted to 3 results
+
     return f()         -- returns all results from f()
+
     return ...         -- returns all received vararg arguments
+
     return x,y,f()     -- returns x, y, and all results from f()
+
     {f()}              -- creates a list with all results from f()
+
     {...}              -- creates a list with all vararg arguments
+
     {f(), nil}         -- f() is adjusted to 1 result
+
</pre>
+

+
<p>
+
Any expression enclosed in parentheses always results in only one value.
+
Thus,
+
<code>(f(x,y,z))</code> is always a single value,
+
even if <code>f</code> returns several values.
+
(The value of <code>(f(x,y,z))</code> is the first value returned by <code>f</code>
+
or <b>nil</b> if <code>f</code> does not return any values.)
+

+

+

+
<h3>3.4.1 &ndash; <a name="3.4.1">Arithmetic Operators</a></h3><p>
+
Lua supports the following arithmetic operators:
+

+
<ul>
+
<li><b><code>+</code>: </b>addition</li>
+
<li><b><code>-</code>: </b>subtraction</li>
+
<li><b><code>*</code>: </b>multiplication</li>
+
<li><b><code>/</code>: </b>float division</li>
+
<li><b><code>//</code>: </b>floor division</li>
+
<li><b><code>%</code>: </b>modulo</li>
+
<li><b><code>^</code>: </b>exponentiation</li>
+
<li><b><code>-</code>: </b>unary minus</li>
+
</ul>
+

+
<p>
+
With the exception of exponentiation and float division,
+
the arithmetic operators work as follows:
+
If both operands are integers,
+
the operation is performed over integers and the result is an integer.
+
Otherwise, if both operands are numbers
+
or strings that can be converted to
+
numbers (see <a href="#3.4.3">&sect;3.4.3</a>),
+
then they are converted to floats,
+
the operation is performed following the usual rules
+
for floating-point arithmetic
+
(usually the IEEE 754 standard),
+
and the result is a float.
+

+

+
<p>
+
Exponentiation and float division (<code>/</code>)
+
always convert their operands to floats
+
and the result is always a float.
+
Exponentiation uses the ISO&nbsp;C function <code>pow</code>,
+
so that it works for non-integer exponents too.
+

+

+
<p>
+
Floor division (<code>//</code>) is a division
+
that rounds the quotient towards minus infinity,
+
that is, the floor of the division of its operands.
+

+

+
<p>
+
Modulo is defined as the remainder of a division
+
that rounds the quotient towards minus infinity (floor division).
+

+

+
<p>
+
In case of overflows in integer arithmetic,
+
all operations <em>wrap around</em>,
+
according to the usual rules of two-complement arithmetic.
+
(In other words,
+
they return the unique representable integer
+
that is equal modulo <em>2<sup>64</sup></em> to the mathematical result.)
+

+

+

+
<h3>3.4.2 &ndash; <a name="3.4.2">Bitwise Operators</a></h3><p>
+
Lua supports the following bitwise operators:
+

+
<ul>
+
<li><b><code>&amp;</code>: </b>bitwise AND</li>
+
<li><b><code>&#124;</code>: </b>bitwise OR</li>
+
<li><b><code>~</code>: </b>bitwise exclusive OR</li>
+
<li><b><code>&gt;&gt;</code>: </b>right shift</li>
+
<li><b><code>&lt;&lt;</code>: </b>left shift</li>
+
<li><b><code>~</code>: </b>unary bitwise NOT</li>
+
</ul>
+

+
<p>
+
All bitwise operations convert its operands to integers
+
(see <a href="#3.4.3">&sect;3.4.3</a>),
+
operate on all bits of those integers,
+
and result in an integer.
+

+

+
<p>
+
Both right and left shifts fill the vacant bits with zeros.
+
Negative displacements shift to the other direction;
+
displacements with absolute values equal to or higher than
+
the number of bits in an integer
+
result in zero (as all bits are shifted out).
+

+

+

+

+

+
<h3>3.4.3 &ndash; <a name="3.4.3">Coercions and Conversions</a></h3><p>
+
Lua provides some automatic conversions between some
+
types and representations at run time.
+
Bitwise operators always convert float operands to integers.
+
Exponentiation and float division
+
always convert integer operands to floats.
+
All other arithmetic operations applied to mixed numbers
+
(integers and floats) convert the integer operand to a float;
+
this is called the <em>usual rule</em>.
+
The C API also converts both integers to floats and
+
floats to integers, as needed.
+
Moreover, string concatenation accepts numbers as arguments,
+
besides strings.
+

+

+
<p>
+
Lua also converts strings to numbers,
+
whenever a number is expected.
+

+

+
<p>
+
In a conversion from integer to float,
+
if the integer value has an exact representation as a float,
+
that is the result.
+
Otherwise,
+
the conversion gets the nearest higher or
+
the nearest lower representable value.
+
This kind of conversion never fails.
+

+

+
<p>
+
The conversion from float to integer
+
checks whether the float has an exact representation as an integer
+
(that is, the float has an integral value and
+
it is in the range of integer representation).
+
If it does, that representation is the result.
+
Otherwise, the conversion fails.
+

+

+
<p>
+
The conversion from strings to numbers goes as follows:
+
First, the string is converted to an integer or a float,
+
following its syntax and the rules of the Lua lexer.
+
(The string may have also leading and trailing spaces and a sign.)
+
Then, the resulting number (float or integer)
+
is converted to the type (float or integer) required by the context
+
(e.g., the operation that forced the conversion).
+

+

+
<p>
+
All conversions from strings to numbers
+
accept both a dot and the current locale mark
+
as the radix character.
+
(The Lua lexer, however, accepts only a dot.)
+

+

+
<p>
+
The conversion from numbers to strings uses a
+
non-specified human-readable format.
+
For complete control over how numbers are converted to strings,
+
use the <code>format</code> function from the string library
+
(see <a href="#pdf-string.format"><code>string.format</code></a>).
+

+

+

+

+

+
<h3>3.4.4 &ndash; <a name="3.4.4">Relational Operators</a></h3><p>
+
Lua supports the following relational operators:
+

+
<ul>
+
<li><b><code>==</code>: </b>equality</li>
+
<li><b><code>~=</code>: </b>inequality</li>
+
<li><b><code>&lt;</code>: </b>less than</li>
+
<li><b><code>&gt;</code>: </b>greater than</li>
+
<li><b><code>&lt;=</code>: </b>less or equal</li>
+
<li><b><code>&gt;=</code>: </b>greater or equal</li>
+
</ul><p>
+
These operators always result in <b>false</b> or <b>true</b>.
+

+

+
<p>
+
Equality (<code>==</code>) first compares the type of its operands.
+
If the types are different, then the result is <b>false</b>.
+
Otherwise, the values of the operands are compared.
+
Strings are compared in the obvious way.
+
Numbers are equal if they denote the same mathematical value.
+

+

+
<p>
+
Tables, userdata, and threads
+
are compared by reference:
+
two objects are considered equal only if they are the same object.
+
Every time you create a new object
+
(a table, userdata, or thread),
+
this new object is different from any previously existing object.
+
A closure is always equal to itself.
+
Closures with any detectable difference
+
(different behavior, different definition) are always different.
+
Closures created at different times but with no detectable differences
+
may be classified as equal or not
+
(depending on internal caching details).
+

+

+
<p>
+
You can change the way that Lua compares tables and userdata
+
by using the "eq" metamethod (see <a href="#2.4">&sect;2.4</a>).
+

+

+
<p>
+
Equality comparisons do not convert strings to numbers
+
or vice versa.
+
Thus, <code>"0"==0</code> evaluates to <b>false</b>,
+
and <code>t[0]</code> and <code>t["0"]</code> denote different
+
entries in a table.
+

+

+
<p>
+
The operator <code>~=</code> is exactly the negation of equality (<code>==</code>).
+

+

+
<p>
+
The order operators work as follows.
+
If both arguments are numbers,
+
then they are compared according to their mathematical values
+
(regardless of their subtypes).
+
Otherwise, if both arguments are strings,
+
then their values are compared according to the current locale.
+
Otherwise, Lua tries to call the "lt" or the "le"
+
metamethod (see <a href="#2.4">&sect;2.4</a>).
+
A comparison <code>a &gt; b</code> is translated to <code>b &lt; a</code>
+
and <code>a &gt;= b</code> is translated to <code>b &lt;= a</code>.
+

+

+
<p>
+
Following the IEEE 754 standard,
+
NaN is considered neither smaller than,
+
nor equal to, nor greater than any value (including itself).
+

+

+

+

+

+
<h3>3.4.5 &ndash; <a name="3.4.5">Logical Operators</a></h3><p>
+
The logical operators in Lua are
+
<b>and</b>, <b>or</b>, and <b>not</b>.
+
Like the control structures (see <a href="#3.3.4">&sect;3.3.4</a>),
+
all logical operators consider both <b>false</b> and <b>nil</b> as false
+
and anything else as true.
+

+

+
<p>
+
The negation operator <b>not</b> always returns <b>false</b> or <b>true</b>.
+
The conjunction operator <b>and</b> returns its first argument
+
if this value is <b>false</b> or <b>nil</b>;
+
otherwise, <b>and</b> returns its second argument.
+
The disjunction operator <b>or</b> returns its first argument
+
if this value is different from <b>nil</b> and <b>false</b>;
+
otherwise, <b>or</b> returns its second argument.
+
Both <b>and</b> and <b>or</b> use short-circuit evaluation;
+
that is,
+
the second operand is evaluated only if necessary.
+
Here are some examples:
+

+
<pre>
+
     10 or 20            --&gt; 10
+
     10 or error()       --&gt; 10
+
     nil or "a"          --&gt; "a"
+
     nil and 10          --&gt; nil
+
     false and error()   --&gt; false
+
     false and nil       --&gt; false
+
     false or nil        --&gt; nil
+
     10 and 20           --&gt; 20
+
</pre><p>
+
(In this manual,
+
<code>--&gt;</code> indicates the result of the preceding expression.)
+

+

+

+

+

+
<h3>3.4.6 &ndash; <a name="3.4.6">Concatenation</a></h3><p>
+
The string concatenation operator in Lua is
+
denoted by two dots ('<code>..</code>').
+
If both operands are strings or numbers, then they are converted to
+
strings according to the rules described in <a href="#3.4.3">&sect;3.4.3</a>.
+
Otherwise, the <code>__concat</code> metamethod is called (see <a href="#2.4">&sect;2.4</a>).
+

+

+

+

+

+
<h3>3.4.7 &ndash; <a name="3.4.7">The Length Operator</a></h3>
+

+
<p>
+
The length operator is denoted by the unary prefix operator <code>#</code>.
+

+

+
<p>
+
The length of a string is its number of bytes
+
(that is, the usual meaning of string length when each
+
character is one byte).
+

+

+
<p>
+
The length operator applied on a table
+
returns a border in that table.
+
A <em>border</em> in a table <code>t</code> is any natural number
+
that satisfies the following condition:
+

+
<pre>
+
     (border == 0 or t[border] ~= nil) and t[border + 1] == nil
+
</pre><p>
+
In words,
+
a border is any (natural) index in a table
+
where a non-nil value is followed by a nil value
+
(or zero, when index 1 is nil).
+

+

+
<p>
+
A table with exactly one border is called a <em>sequence</em>.
+
For instance, the table <code>{10, 20, 30, 40, 50}</code> is a sequence,
+
as it has only one border (5).
+
The table <code>{10, 20, 30, nil, 50}</code> has two borders (3 and 5),
+
and therefore it is not a sequence.
+
The table <code>{nil, 20, 30, nil, nil, 60, nil}</code>
+
has three borders (0, 3, and 6),
+
so it is not a sequence, too.
+
The table <code>{}</code> is a sequence with border 0.
+
Note that non-natural keys do not interfere
+
with whether a table is a sequence.
+

+

+
<p>
+
When <code>t</code> is a sequence,
+
<code>#t</code> returns its only border,
+
which corresponds to the intuitive notion of the length of the sequence.
+
When <code>t</code> is not a sequence,
+
<code>#t</code> can return any of its borders.
+
(The exact one depends on details of
+
the internal representation of the table,
+
which in turn can depend on how the table was populated and
+
the memory addresses of its non-numeric keys.)
+

+

+
<p>
+
The computation of the length of a table
+
has a guaranteed worst time of <em>O(log n)</em>,
+
where <em>n</em> is the largest natural key in the table.
+

+

+
<p>
+
A program can modify the behavior of the length operator for
+
any value but strings through the <code>__len</code> metamethod (see <a href="#2.4">&sect;2.4</a>).
+

+

+

+

+

+
<h3>3.4.8 &ndash; <a name="3.4.8">Precedence</a></h3><p>
+
Operator precedence in Lua follows the table below,
+
from lower to higher priority:
+

+
<pre>
+
     or
+
     and
+
     &lt;     &gt;     &lt;=    &gt;=    ~=    ==
+
     |
+
     ~
+
     &amp;
+
     &lt;&lt;    &gt;&gt;
+
     ..
+
     +     -
+
     *     /     //    %
+
     unary operators (not   #     -     ~)
+
     ^
+
</pre><p>
+
As usual,
+
you can use parentheses to change the precedences of an expression.
+
The concatenation ('<code>..</code>') and exponentiation ('<code>^</code>')
+
operators are right associative.
+
All other binary operators are left associative.
+

+

+

+

+

+
<h3>3.4.9 &ndash; <a name="3.4.9">Table Constructors</a></h3><p>
+
Table constructors are expressions that create tables.
+
Every time a constructor is evaluated, a new table is created.
+
A constructor can be used to create an empty table
+
or to create a table and initialize some of its fields.
+
The general syntax for constructors is
+

+
<pre>
+
	tableconstructor ::= &lsquo;<b>{</b>&rsquo; [fieldlist] &lsquo;<b>}</b>&rsquo;
+
	fieldlist ::= field {fieldsep field} [fieldsep]
+
	field ::= &lsquo;<b>[</b>&rsquo; exp &lsquo;<b>]</b>&rsquo; &lsquo;<b>=</b>&rsquo; exp | Name &lsquo;<b>=</b>&rsquo; exp | exp
+
	fieldsep ::= &lsquo;<b>,</b>&rsquo; | &lsquo;<b>;</b>&rsquo;
+
</pre>
+

+
<p>
+
Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry
+
with key <code>exp1</code> and value <code>exp2</code>.
+
A field of the form <code>name = exp</code> is equivalent to
+
<code>["name"] = exp</code>.
+
Finally, fields of the form <code>exp</code> are equivalent to
+
<code>[i] = exp</code>, where <code>i</code> are consecutive integers
+
starting with 1.
+
Fields in the other formats do not affect this counting.
+
For example,
+

+
<pre>
+
     a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
+
</pre><p>
+
is equivalent to
+

+
<pre>
+
     do
+
       local t = {}
+
       t[f(1)] = g
+
       t[1] = "x"         -- 1st exp
+
       t[2] = "y"         -- 2nd exp
+
       t.x = 1            -- t["x"] = 1
+
       t[3] = f(x)        -- 3rd exp
+
       t[30] = 23
+
       t[4] = 45          -- 4th exp
+
       a = t
+
     end
+
</pre>
+

+
<p>
+
The order of the assignments in a constructor is undefined.
+
(This order would be relevant only when there are repeated keys.)
+

+

+
<p>
+
If the last field in the list has the form <code>exp</code>
+
and the expression is a function call or a vararg expression,
+
then all values returned by this expression enter the list consecutively
+
(see <a href="#3.4.10">&sect;3.4.10</a>).
+

+

+
<p>
+
The field list can have an optional trailing separator,
+
as a convenience for machine-generated code.
+

+

+

+

+

+
<h3>3.4.10 &ndash; <a name="3.4.10">Function Calls</a></h3><p>
+
A function call in Lua has the following syntax:
+

+
<pre>
+
	functioncall ::= prefixexp args
+
</pre><p>
+
In a function call,
+
first prefixexp and args are evaluated.
+
If the value of prefixexp has type <em>function</em>,
+
then this function is called
+
with the given arguments.
+
Otherwise, the prefixexp "call" metamethod is called,
+
having as first argument the value of prefixexp,
+
followed by the original call arguments
+
(see <a href="#2.4">&sect;2.4</a>).
+

+

+
<p>
+
The form
+

+
<pre>
+
	functioncall ::= prefixexp &lsquo;<b>:</b>&rsquo; Name args
+
</pre><p>
+
can be used to call "methods".
+
A call <code>v:name(<em>args</em>)</code>
+
is syntactic sugar for <code>v.name(v,<em>args</em>)</code>,
+
except that <code>v</code> is evaluated only once.
+

+

+
<p>
+
Arguments have the following syntax:
+

+
<pre>
+
	args ::= &lsquo;<b>(</b>&rsquo; [explist] &lsquo;<b>)</b>&rsquo;
+
	args ::= tableconstructor
+
	args ::= LiteralString
+
</pre><p>
+
All argument expressions are evaluated before the call.
+
A call of the form <code>f{<em>fields</em>}</code> is
+
syntactic sugar for <code>f({<em>fields</em>})</code>;
+
that is, the argument list is a single new table.
+
A call of the form <code>f'<em>string</em>'</code>
+
(or <code>f"<em>string</em>"</code> or <code>f[[<em>string</em>]]</code>)
+
is syntactic sugar for <code>f('<em>string</em>')</code>;
+
that is, the argument list is a single literal string.
+

+

+
<p>
+
A call of the form <code>return <em>functioncall</em></code> is called
+
a <em>tail call</em>.
+
Lua implements <em>proper tail calls</em>
+
(or <em>proper tail recursion</em>):
+
in a tail call,
+
the called function reuses the stack entry of the calling function.
+
Therefore, there is no limit on the number of nested tail calls that
+
a program can execute.
+
However, a tail call erases any debug information about the
+
calling function.
+
Note that a tail call only happens with a particular syntax,
+
where the <b>return</b> has one single function call as argument;
+
this syntax makes the calling function return exactly
+
the returns of the called function.
+
So, none of the following examples are tail calls:
+

+
<pre>
+
     return (f(x))        -- results adjusted to 1
+
     return 2 * f(x)
+
     return x, f(x)       -- additional results
+
     f(x); return         -- results discarded
+
     return x or f(x)     -- results adjusted to 1
+
</pre>
+

+

+

+

+
<h3>3.4.11 &ndash; <a name="3.4.11">Function Definitions</a></h3>
+

+
<p>
+
The syntax for function definition is
+

+
<pre>
+
	functiondef ::= <b>function</b> funcbody
+
	funcbody ::= &lsquo;<b>(</b>&rsquo; [parlist] &lsquo;<b>)</b>&rsquo; block <b>end</b>
+
</pre>
+

+
<p>
+
The following syntactic sugar simplifies function definitions:
+

+
<pre>
+
	stat ::= <b>function</b> funcname funcbody
+
	stat ::= <b>local</b> <b>function</b> Name funcbody
+
	funcname ::= Name {&lsquo;<b>.</b>&rsquo; Name} [&lsquo;<b>:</b>&rsquo; Name]
+
</pre><p>
+
The statement
+

+
<pre>
+
     function f () <em>body</em> end
+
</pre><p>
+
translates to
+

+
<pre>
+
     f = function () <em>body</em> end
+
</pre><p>
+
The statement
+

+
<pre>
+
     function t.a.b.c.f () <em>body</em> end
+
</pre><p>
+
translates to
+

+
<pre>
+
     t.a.b.c.f = function () <em>body</em> end
+
</pre><p>
+
The statement
+

+
<pre>
+
     local function f () <em>body</em> end
+
</pre><p>
+
translates to
+

+
<pre>
+
     local f; f = function () <em>body</em> end
+
</pre><p>
+
not to
+

+
<pre>
+
     local f = function () <em>body</em> end
+
</pre><p>
+
(This only makes a difference when the body of the function
+
contains references to <code>f</code>.)
+

+

+
<p>
+
A function definition is an executable expression,
+
whose value has type <em>function</em>.
+
When Lua precompiles a chunk,
+
all its function bodies are precompiled too.
+
Then, whenever Lua executes the function definition,
+
the function is <em>instantiated</em> (or <em>closed</em>).
+
This function instance (or <em>closure</em>)
+
is the final value of the expression.
+

+

+
<p>
+
Parameters act as local variables that are
+
initialized with the argument values:
+

+
<pre>
+
	parlist ::= namelist [&lsquo;<b>,</b>&rsquo; &lsquo;<b>...</b>&rsquo;] | &lsquo;<b>...</b>&rsquo;
+
</pre><p>
+
When a function is called,
+
the list of arguments is adjusted to
+
the length of the list of parameters,
+
unless the function is a <em>vararg function</em>,
+
which is indicated by three dots ('<code>...</code>')
+
at the end of its parameter list.
+
A vararg function does not adjust its argument list;
+
instead, it collects all extra arguments and supplies them
+
to the function through a <em>vararg expression</em>,
+
which is also written as three dots.
+
The value of this expression is a list of all actual extra arguments,
+
similar to a function with multiple results.
+
If a vararg expression is used inside another expression
+
or in the middle of a list of expressions,
+
then its return list is adjusted to one element.
+
If the expression is used as the last element of a list of expressions,
+
then no adjustment is made
+
(unless that last expression is enclosed in parentheses).
+

+

+
<p>
+
As an example, consider the following definitions:
+

+
<pre>
+
     function f(a, b) end
+
     function g(a, b, ...) end
+
     function r() return 1,2,3 end
+
</pre><p>
+
Then, we have the following mapping from arguments to parameters and
+
to the vararg expression:
+

+
<pre>
+
     CALL            PARAMETERS
+
     
+
     f(3)             a=3, b=nil
+
     f(3, 4)          a=3, b=4
+
     f(3, 4, 5)       a=3, b=4
+
     f(r(), 10)       a=1, b=10
+
     f(r())           a=1, b=2
+
     
+
     g(3)             a=3, b=nil, ... --&gt;  (nothing)
+
     g(3, 4)          a=3, b=4,   ... --&gt;  (nothing)
+
     g(3, 4, 5, 8)    a=3, b=4,   ... --&gt;  5  8
+
     g(5, r())        a=5, b=1,   ... --&gt;  2  3
+
</pre>
+

+
<p>
+
Results are returned using the <b>return</b> statement (see <a href="#3.3.4">&sect;3.3.4</a>).
+
If control reaches the end of a function
+
without encountering a <b>return</b> statement,
+
then the function returns with no results.
+

+

+
<p>
+

+
There is a system-dependent limit on the number of values
+
that a function may return.
+
This limit is guaranteed to be larger than 1000.
+

+

+
<p>
+
The <em>colon</em> syntax
+
is used for defining <em>methods</em>,
+
that is, functions that have an implicit extra parameter <code>self</code>.
+
Thus, the statement
+

+
<pre>
+
     function t.a.b.c:f (<em>params</em>) <em>body</em> end
+
</pre><p>
+
is syntactic sugar for
+

+
<pre>
+
     t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end
+
</pre>
+

+

+

+

+

+

+
<h2>3.5 &ndash; <a name="3.5">Visibility Rules</a></h2>
+

+
<p>
+

+
Lua is a lexically scoped language.
+
The scope of a local variable begins at the first statement after
+
its declaration and lasts until the last non-void statement
+
of the innermost block that includes the declaration.
+
Consider the following example:
+

+
<pre>
+
     x = 10                -- global variable
+
     do                    -- new block
+
       local x = x         -- new 'x', with value 10
+
       print(x)            --&gt; 10
+
       x = x+1
+
       do                  -- another block
+
         local x = x+1     -- another 'x'
+
         print(x)          --&gt; 12
+
       end
+
       print(x)            --&gt; 11
+
     end
+
     print(x)              --&gt; 10  (the global one)
+
</pre>
+

+
<p>
+
Notice that, in a declaration like <code>local x = x</code>,
+
the new <code>x</code> being declared is not in scope yet,
+
and so the second <code>x</code> refers to the outside variable.
+

+

+
<p>
+
Because of the lexical scoping rules,
+
local variables can be freely accessed by functions
+
defined inside their scope.
+
A local variable used by an inner function is called
+
an <em>upvalue</em>, or <em>external local variable</em>,
+
inside the inner function.
+

+

+
<p>
+
Notice that each execution of a <b>local</b> statement
+
defines new local variables.
+
Consider the following example:
+

+
<pre>
+
     a = {}
+
     local x = 20
+
     for i=1,10 do
+
       local y = 0
+
       a[i] = function () y=y+1; return x+y end
+
     end
+
</pre><p>
+
The loop creates ten closures
+
(that is, ten instances of the anonymous function).
+
Each of these closures uses a different <code>y</code> variable,
+
while all of them share the same <code>x</code>.
+

+

+

+

+

+
<h1>4 &ndash; <a name="4">The Application Program Interface</a></h1>
+

+
<p>
+

+
This section describes the C&nbsp;API for Lua, that is,
+
the set of C&nbsp;functions available to the host program to communicate
+
with Lua.
+
All API functions and related types and constants
+
are declared in the header file <a name="pdf-lua.h"><code>lua.h</code></a>.
+

+

+
<p>
+
Even when we use the term "function",
+
any facility in the API may be provided as a macro instead.
+
Except where stated otherwise,
+
all such macros use each of their arguments exactly once
+
(except for the first argument, which is always a Lua state),
+
and so do not generate any hidden side-effects.
+

+

+
<p>
+
As in most C&nbsp;libraries,
+
the Lua API functions do not check their arguments for validity or consistency.
+
However, you can change this behavior by compiling Lua
+
with the macro <a name="pdf-LUA_USE_APICHECK"><code>LUA_USE_APICHECK</code></a> defined.
+

+

+
<p>
+
The Lua library is fully reentrant:
+
it has no global variables.
+
It keeps all information it needs in a dynamic structure,
+
called the <em>Lua state</em>.
+

+

+
<p>
+
Each Lua state has one or more threads,
+
which correspond to independent, cooperative lines of execution.
+
The type <a href="#lua_State"><code>lua_State</code></a> (despite its name) refers to a thread.
+
(Indirectly, through the thread, it also refers to the
+
Lua state associated to the thread.)
+

+

+
<p>
+
A pointer to a thread must be passed as the first argument to
+
every function in the library, except to <a href="#lua_newstate"><code>lua_newstate</code></a>,
+
which creates a Lua state from scratch and returns a pointer
+
to the <em>main thread</em> in the new state.
+

+

+

+
<h2>4.1 &ndash; <a name="4.1">The Stack</a></h2>
+

+
<p>
+
Lua uses a <em>virtual stack</em> to pass values to and from C.
+
Each element in this stack represents a Lua value
+
(<b>nil</b>, number, string, etc.).
+
Functions in the API can access this stack through the
+
Lua state parameter that they receive.
+

+

+
<p>
+
Whenever Lua calls C, the called function gets a new stack,
+
which is independent of previous stacks and of stacks of
+
C&nbsp;functions that are still active.
+
This stack initially contains any arguments to the C&nbsp;function
+
and it is where the C&nbsp;function can store temporary
+
Lua values and must push its results
+
to be returned to the caller (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
+

+

+
<p>
+
For convenience,
+
most query operations in the API do not follow a strict stack discipline.
+
Instead, they can refer to any element in the stack
+
by using an <em>index</em>:
+
A positive index represents an absolute stack position
+
(starting at&nbsp;1);
+
a negative index represents an offset relative to the top of the stack.
+
More specifically, if the stack has <em>n</em> elements,
+
then index&nbsp;1 represents the first element
+
(that is, the element that was pushed onto the stack first)
+
and
+
index&nbsp;<em>n</em> represents the last element;
+
index&nbsp;-1 also represents the last element
+
(that is, the element at the&nbsp;top)
+
and index <em>-n</em> represents the first element.
+

+

+

+

+

+
<h2>4.2 &ndash; <a name="4.2">Stack Size</a></h2>
+

+
<p>
+
When you interact with the Lua API,
+
you are responsible for ensuring consistency.
+
In particular,
+
<em>you are responsible for controlling stack overflow</em>.
+
You can use the function <a href="#lua_checkstack"><code>lua_checkstack</code></a>
+
to ensure that the stack has enough space for pushing new elements.
+

+

+
<p>
+
Whenever Lua calls C,
+
it ensures that the stack has space for
+
at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra slots.
+
<code>LUA_MINSTACK</code> is defined as 20,
+
so that usually you do not have to worry about stack space
+
unless your code has loops pushing elements onto the stack.
+

+

+
<p>
+
When you call a Lua function
+
without a fixed number of results (see <a href="#lua_call"><code>lua_call</code></a>),
+
Lua ensures that the stack has enough space for all results,
+
but it does not ensure any extra space.
+
So, before pushing anything in the stack after such a call
+
you should use <a href="#lua_checkstack"><code>lua_checkstack</code></a>.
+

+

+

+

+

+
<h2>4.3 &ndash; <a name="4.3">Valid and Acceptable Indices</a></h2>
+

+
<p>
+
Any function in the API that receives stack indices
+
works only with <em>valid indices</em> or <em>acceptable indices</em>.
+

+

+
<p>
+
A <em>valid index</em> is an index that refers to a
+
position that stores a modifiable Lua value.
+
It comprises stack indices between&nbsp;1 and the stack top
+
(<code>1 &le; abs(index) &le; top</code>)
+

+
plus <em>pseudo-indices</em>,
+
which represent some positions that are accessible to C&nbsp;code
+
but that are not in the stack.
+
Pseudo-indices are used to access the registry (see <a href="#4.5">&sect;4.5</a>)
+
and the upvalues of a C&nbsp;function (see <a href="#4.4">&sect;4.4</a>).
+

+

+
<p>
+
Functions that do not need a specific mutable position,
+
but only a value (e.g., query functions),
+
can be called with acceptable indices.
+
An <em>acceptable index</em> can be any valid index,
+
but it also can be any positive index after the stack top
+
within the space allocated for the stack,
+
that is, indices up to the stack size.
+
(Note that 0 is never an acceptable index.)
+
Except when noted otherwise,
+
functions in the API work with acceptable indices.
+

+

+
<p>
+
Acceptable indices serve to avoid extra tests
+
against the stack top when querying the stack.
+
For instance, a C&nbsp;function can query its third argument
+
without the need to first check whether there is a third argument,
+
that is, without the need to check whether 3 is a valid index.
+

+

+
<p>
+
For functions that can be called with acceptable indices,
+
any non-valid index is treated as if it
+
contains a value of a virtual type <a name="pdf-LUA_TNONE"><code>LUA_TNONE</code></a>,
+
which behaves like a nil value.
+

+

+

+

+

+
<h2>4.4 &ndash; <a name="4.4">C Closures</a></h2>
+

+
<p>
+
When a C&nbsp;function is created,
+
it is possible to associate some values with it,
+
thus creating a <em>C&nbsp;closure</em>
+
(see <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>);
+
these values are called <em>upvalues</em> and are
+
accessible to the function whenever it is called.
+

+

+
<p>
+
Whenever a C&nbsp;function is called,
+
its upvalues are located at specific pseudo-indices.
+
These pseudo-indices are produced by the macro
+
<a href="#lua_upvalueindex"><code>lua_upvalueindex</code></a>.
+
The first upvalue associated with a function is at index
+
<code>lua_upvalueindex(1)</code>, and so on.
+
Any access to <code>lua_upvalueindex(<em>n</em>)</code>,
+
where <em>n</em> is greater than the number of upvalues of the
+
current function
+
(but not greater than 256,
+
which is one plus the maximum number of upvalues in a closure),
+
produces an acceptable but invalid index.
+

+

+

+

+

+
<h2>4.5 &ndash; <a name="4.5">Registry</a></h2>
+

+
<p>
+
Lua provides a <em>registry</em>,
+
a predefined table that can be used by any C&nbsp;code to
+
store whatever Lua values it needs to store.
+
The registry table is always located at pseudo-index
+
<a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>.
+
Any C&nbsp;library can store data into this table,
+
but it must take care to choose keys
+
that are different from those used
+
by other libraries, to avoid collisions.
+
Typically, you should use as key a string containing your library name,
+
or a light userdata with the address of a C&nbsp;object in your code,
+
or any Lua object created by your code.
+
As with variable names,
+
string keys starting with an underscore followed by
+
uppercase letters are reserved for Lua.
+

+

+
<p>
+
The integer keys in the registry are used
+
by the reference mechanism (see <a href="#luaL_ref"><code>luaL_ref</code></a>)
+
and by some predefined values.
+
Therefore, integer keys must not be used for other purposes.
+

+

+
<p>
+
When you create a new Lua state,
+
its registry comes with some predefined values.
+
These predefined values are indexed with integer keys
+
defined as constants in <code>lua.h</code>.
+
The following constants are defined:
+

+
<ul>
+
<li><b><a name="pdf-LUA_RIDX_MAINTHREAD"><code>LUA_RIDX_MAINTHREAD</code></a>: </b> At this index the registry has
+
the main thread of the state.
+
(The main thread is the one created together with the state.)
+
</li>
+

+
<li><b><a name="pdf-LUA_RIDX_GLOBALS"><code>LUA_RIDX_GLOBALS</code></a>: </b> At this index the registry has
+
the global environment.
+
</li>
+
</ul>
+

+

+

+

+
<h2>4.6 &ndash; <a name="4.6">Error Handling in C</a></h2>
+

+
<p>
+
Internally, Lua uses the C <code>longjmp</code> facility to handle errors.
+
(Lua will use exceptions if you compile it as C++;
+
search for <code>LUAI_THROW</code> in the source code for details.)
+
When Lua faces any error
+
(such as a memory allocation error or a type error)
+
it <em>raises</em> an error;
+
that is, it does a long jump.
+
A <em>protected environment</em> uses <code>setjmp</code>
+
to set a recovery point;
+
any error jumps to the most recent active recovery point.
+

+

+
<p>
+
Inside a C&nbsp;function you can raise an error by calling <a href="#lua_error"><code>lua_error</code></a>.
+

+

+
<p>
+
Most functions in the API can raise an error,
+
for instance due to a memory allocation error.
+
The documentation for each function indicates whether
+
it can raise errors.
+

+

+
<p>
+
If an error happens outside any protected environment,
+
Lua calls a <em>panic function</em> (see <a href="#lua_atpanic"><code>lua_atpanic</code></a>)
+
and then calls <code>abort</code>,
+
thus exiting the host application.
+
Your panic function can avoid this exit by
+
never returning
+
(e.g., doing a long jump to your own recovery point outside Lua).
+

+

+
<p>
+
The panic function,
+
as its name implies,
+
is a mechanism of last resort.
+
Programs should avoid it.
+
As a general rule,
+
when a C&nbsp;function is called by Lua with a Lua state,
+
it can do whatever it wants on that Lua state,
+
as it should be already protected.
+
However,
+
when C code operates on other Lua states
+
(e.g., a Lua argument to the function,
+
a Lua state stored in the registry, or
+
the result of <a href="#lua_newthread"><code>lua_newthread</code></a>),
+
it should use them only in API calls that cannot raise errors.
+

+

+
<p>
+
The panic function runs as if it were a message handler (see <a href="#2.3">&sect;2.3</a>);
+
in particular, the error object is at the top of the stack.
+
However, there is no guarantee about stack space.
+
To push anything on the stack,
+
the panic function must first check the available space (see <a href="#4.2">&sect;4.2</a>).
+

+

+

+

+

+
<h2>4.7 &ndash; <a name="4.7">Handling Yields in C</a></h2>
+

+
<p>
+
Internally, Lua uses the C <code>longjmp</code> facility to yield a coroutine.
+
Therefore, if a C&nbsp;function <code>foo</code> calls an API function
+
and this API function yields
+
(directly or indirectly by calling another function that yields),
+
Lua cannot return to <code>foo</code> any more,
+
because the <code>longjmp</code> removes its frame from the C stack.
+

+

+
<p>
+
To avoid this kind of problem,
+
Lua raises an error whenever it tries to yield across an API call,
+
except for three functions:
+
<a href="#lua_yieldk"><code>lua_yieldk</code></a>, <a href="#lua_callk"><code>lua_callk</code></a>, and <a href="#lua_pcallk"><code>lua_pcallk</code></a>.
+
All those functions receive a <em>continuation function</em>
+
(as a parameter named <code>k</code>) to continue execution after a yield.
+

+

+
<p>
+
We need to set some terminology to explain continuations.
+
We have a C&nbsp;function called from Lua which we will call
+
the <em>original function</em>.
+
This original function then calls one of those three functions in the C API,
+
which we will call the <em>callee function</em>,
+
that then yields the current thread.
+
(This can happen when the callee function is <a href="#lua_yieldk"><code>lua_yieldk</code></a>,
+
or when the callee function is either <a href="#lua_callk"><code>lua_callk</code></a> or <a href="#lua_pcallk"><code>lua_pcallk</code></a>
+
and the function called by them yields.)
+

+

+
<p>
+
Suppose the running thread yields while executing the callee function.
+
After the thread resumes,
+
it eventually will finish running the callee function.
+
However,
+
the callee function cannot return to the original function,
+
because its frame in the C stack was destroyed by the yield.
+
Instead, Lua calls a <em>continuation function</em>,
+
which was given as an argument to the callee function.
+
As the name implies,
+
the continuation function should continue the task
+
of the original function.
+

+

+
<p>
+
As an illustration, consider the following function:
+

+
<pre>
+
     int original_function (lua_State *L) {
+
       ...     /* code 1 */
+
       status = lua_pcall(L, n, m, h);  /* calls Lua */
+
       ...     /* code 2 */
+
     }
+
</pre><p>
+
Now we want to allow
+
the Lua code being run by <a href="#lua_pcall"><code>lua_pcall</code></a> to yield.
+
First, we can rewrite our function like here:
+

+
<pre>
+
     int k (lua_State *L, int status, lua_KContext ctx) {
+
       ...  /* code 2 */
+
     }
+
     
+
     int original_function (lua_State *L) {
+
       ...     /* code 1 */
+
       return k(L, lua_pcall(L, n, m, h), ctx);
+
     }
+
</pre><p>
+
In the above code,
+
the new function <code>k</code> is a
+
<em>continuation function</em> (with type <a href="#lua_KFunction"><code>lua_KFunction</code></a>),
+
which should do all the work that the original function
+
was doing after calling <a href="#lua_pcall"><code>lua_pcall</code></a>.
+
Now, we must inform Lua that it must call <code>k</code> if the Lua code
+
being executed by <a href="#lua_pcall"><code>lua_pcall</code></a> gets interrupted in some way
+
(errors or yielding),
+
so we rewrite the code as here,
+
replacing <a href="#lua_pcall"><code>lua_pcall</code></a> by <a href="#lua_pcallk"><code>lua_pcallk</code></a>:
+

+
<pre>
+
     int original_function (lua_State *L) {
+
       ...     /* code 1 */
+
       return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
+
     }
+
</pre><p>
+
Note the external, explicit call to the continuation:
+
Lua will call the continuation only if needed, that is,
+
in case of errors or resuming after a yield.
+
If the called function returns normally without ever yielding,
+
<a href="#lua_pcallk"><code>lua_pcallk</code></a> (and <a href="#lua_callk"><code>lua_callk</code></a>) will also return normally.
+
(Of course, instead of calling the continuation in that case,
+
you can do the equivalent work directly inside the original function.)
+

+

+
<p>
+
Besides the Lua state,
+
the continuation function has two other parameters:
+
the final status of the call plus the context value (<code>ctx</code>) that
+
was passed originally to <a href="#lua_pcallk"><code>lua_pcallk</code></a>.
+
(Lua does not use this context value;
+
it only passes this value from the original function to the
+
continuation function.)
+
For <a href="#lua_pcallk"><code>lua_pcallk</code></a>,
+
the status is the same value that would be returned by <a href="#lua_pcallk"><code>lua_pcallk</code></a>,
+
except that it is <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> when being executed after a yield
+
(instead of <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>).
+
For <a href="#lua_yieldk"><code>lua_yieldk</code></a> and <a href="#lua_callk"><code>lua_callk</code></a>,
+
the status is always <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> when Lua calls the continuation.
+
(For these two functions,
+
Lua will not call the continuation in case of errors,
+
because they do not handle errors.)
+
Similarly, when using <a href="#lua_callk"><code>lua_callk</code></a>,
+
you should call the continuation function
+
with <a href="#pdf-LUA_OK"><code>LUA_OK</code></a> as the status.
+
(For <a href="#lua_yieldk"><code>lua_yieldk</code></a>, there is not much point in calling
+
directly the continuation function,
+
because <a href="#lua_yieldk"><code>lua_yieldk</code></a> usually does not return.)
+

+

+
<p>
+
Lua treats the continuation function as if it were the original function.
+
The continuation function receives the same Lua stack
+
from the original function,
+
in the same state it would be if the callee function had returned.
+
(For instance,
+
after a <a href="#lua_callk"><code>lua_callk</code></a> the function and its arguments are
+
removed from the stack and replaced by the results from the call.)
+
It also has the same upvalues.
+
Whatever it returns is handled by Lua as if it were the return
+
of the original function.
+

+

+

+

+

+
<h2>4.8 &ndash; <a name="4.8">Functions and Types</a></h2>
+

+
<p>
+
Here we list all functions and types from the C&nbsp;API in
+
alphabetical order.
+
Each function has an indicator like this:
+
<span class="apii">[-o, +p, <em>x</em>]</span>
+

+

+
<p>
+
The first field, <code>o</code>,
+
is how many elements the function pops from the stack.
+
The second field, <code>p</code>,
+
is how many elements the function pushes onto the stack.
+
(Any function always pushes its results after popping its arguments.)
+
A field in the form <code>x|y</code> means the function can push (or pop)
+
<code>x</code> or <code>y</code> elements,
+
depending on the situation;
+
an interrogation mark '<code>?</code>' means that
+
we cannot know how many elements the function pops/pushes
+
by looking only at its arguments
+
(e.g., they may depend on what is on the stack).
+
The third field, <code>x</code>,
+
tells whether the function may raise errors:
+
'<code>-</code>' means the function never raises any error;
+
'<code>m</code>' means the function may raise out-of-memory errors
+
and errors running a <code>__gc</code> metamethod;
+
'<code>e</code>' means the function may raise any errors
+
(it can run arbitrary Lua code,
+
either directly or through metamethods);
+
'<code>v</code>' means the function may raise an error on purpose.
+

+

+

+
<hr><h3><a name="lua_absindex"><code>lua_absindex</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_absindex (lua_State *L, int idx);</pre>
+

+
<p>
+
Converts the acceptable index <code>idx</code>
+
into an equivalent absolute index
+
(that is, one that does not depend on the stack top).
+

+

+

+

+

+
<hr><h3><a name="lua_Alloc"><code>lua_Alloc</code></a></h3>
+
<pre>typedef void * (*lua_Alloc) (void *ud,
+
                             void *ptr,
+
                             size_t osize,
+
                             size_t nsize);</pre>
+

+
<p>
+
The type of the memory-allocation function used by Lua states.
+
The allocator function must provide a
+
functionality similar to <code>realloc</code>,
+
but not exactly the same.
+
Its arguments are
+
<code>ud</code>, an opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>;
+
<code>ptr</code>, a pointer to the block being allocated/reallocated/freed;
+
<code>osize</code>, the original size of the block or some code about what
+
is being allocated;
+
and <code>nsize</code>, the new size of the block.
+

+

+
<p>
+
When <code>ptr</code> is not <code>NULL</code>,
+
<code>osize</code> is the size of the block pointed by <code>ptr</code>,
+
that is, the size given when it was allocated or reallocated.
+

+

+
<p>
+
When <code>ptr</code> is <code>NULL</code>,
+
<code>osize</code> encodes the kind of object that Lua is allocating.
+
<code>osize</code> is any of
+
<a href="#pdf-LUA_TSTRING"><code>LUA_TSTRING</code></a>, <a href="#pdf-LUA_TTABLE"><code>LUA_TTABLE</code></a>, <a href="#pdf-LUA_TFUNCTION"><code>LUA_TFUNCTION</code></a>,
+
<a href="#pdf-LUA_TUSERDATA"><code>LUA_TUSERDATA</code></a>, or <a href="#pdf-LUA_TTHREAD"><code>LUA_TTHREAD</code></a> when (and only when)
+
Lua is creating a new object of that type.
+
When <code>osize</code> is some other value,
+
Lua is allocating memory for something else.
+

+

+
<p>
+
Lua assumes the following behavior from the allocator function:
+

+

+
<p>
+
When <code>nsize</code> is zero,
+
the allocator must behave like <code>free</code>
+
and return <code>NULL</code>.
+

+

+
<p>
+
When <code>nsize</code> is not zero,
+
the allocator must behave like <code>realloc</code>.
+
The allocator returns <code>NULL</code>
+
if and only if it cannot fulfill the request.
+
Lua assumes that the allocator never fails when
+
<code>osize &gt;= nsize</code>.
+

+

+
<p>
+
Here is a simple implementation for the allocator function.
+
It is used in the auxiliary library by <a href="#luaL_newstate"><code>luaL_newstate</code></a>.
+

+
<pre>
+
     static void *l_alloc (void *ud, void *ptr, size_t osize,
+
                                                size_t nsize) {
+
       (void)ud;  (void)osize;  /* not used */
+
       if (nsize == 0) {
+
         free(ptr);
+
         return NULL;
+
       }
+
       else
+
         return realloc(ptr, nsize);
+
     }
+
</pre><p>
+
Note that Standard&nbsp;C ensures
+
that <code>free(NULL)</code> has no effect and that
+
<code>realloc(NULL,size)</code> is equivalent to <code>malloc(size)</code>.
+
This code assumes that <code>realloc</code> does not fail when shrinking a block.
+
(Although Standard&nbsp;C does not ensure this behavior,
+
it seems to be a safe assumption.)
+

+

+

+

+

+
<hr><h3><a name="lua_arith"><code>lua_arith</code></a></h3><p>
+
<span class="apii">[-(2|1), +1, <em>e</em>]</span>
+
<pre>void lua_arith (lua_State *L, int op);</pre>
+

+
<p>
+
Performs an arithmetic or bitwise operation over the two values
+
(or one, in the case of negations)
+
at the top of the stack,
+
with the value at the top being the second operand,
+
pops these values, and pushes the result of the operation.
+
The function follows the semantics of the corresponding Lua operator
+
(that is, it may call metamethods).
+

+

+
<p>
+
The value of <code>op</code> must be one of the following constants:
+

+
<ul>
+

+
<li><b><a name="pdf-LUA_OPADD"><code>LUA_OPADD</code></a>: </b> performs addition (<code>+</code>)</li>
+
<li><b><a name="pdf-LUA_OPSUB"><code>LUA_OPSUB</code></a>: </b> performs subtraction (<code>-</code>)</li>
+
<li><b><a name="pdf-LUA_OPMUL"><code>LUA_OPMUL</code></a>: </b> performs multiplication (<code>*</code>)</li>
+
<li><b><a name="pdf-LUA_OPDIV"><code>LUA_OPDIV</code></a>: </b> performs float division (<code>/</code>)</li>
+
<li><b><a name="pdf-LUA_OPIDIV"><code>LUA_OPIDIV</code></a>: </b> performs floor division (<code>//</code>)</li>
+
<li><b><a name="pdf-LUA_OPMOD"><code>LUA_OPMOD</code></a>: </b> performs modulo (<code>%</code>)</li>
+
<li><b><a name="pdf-LUA_OPPOW"><code>LUA_OPPOW</code></a>: </b> performs exponentiation (<code>^</code>)</li>
+
<li><b><a name="pdf-LUA_OPUNM"><code>LUA_OPUNM</code></a>: </b> performs mathematical negation (unary <code>-</code>)</li>
+
<li><b><a name="pdf-LUA_OPBNOT"><code>LUA_OPBNOT</code></a>: </b> performs bitwise NOT (<code>~</code>)</li>
+
<li><b><a name="pdf-LUA_OPBAND"><code>LUA_OPBAND</code></a>: </b> performs bitwise AND (<code>&amp;</code>)</li>
+
<li><b><a name="pdf-LUA_OPBOR"><code>LUA_OPBOR</code></a>: </b> performs bitwise OR (<code>|</code>)</li>
+
<li><b><a name="pdf-LUA_OPBXOR"><code>LUA_OPBXOR</code></a>: </b> performs bitwise exclusive OR (<code>~</code>)</li>
+
<li><b><a name="pdf-LUA_OPSHL"><code>LUA_OPSHL</code></a>: </b> performs left shift (<code>&lt;&lt;</code>)</li>
+
<li><b><a name="pdf-LUA_OPSHR"><code>LUA_OPSHR</code></a>: </b> performs right shift (<code>&gt;&gt;</code>)</li>
+

+
</ul>
+

+

+

+

+
<hr><h3><a name="lua_atpanic"><code>lua_atpanic</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre>
+

+
<p>
+
Sets a new panic function and returns the old one (see <a href="#4.6">&sect;4.6</a>).
+

+

+

+

+

+
<hr><h3><a name="lua_call"><code>lua_call</code></a></h3><p>
+
<span class="apii">[-(nargs+1), +nresults, <em>e</em>]</span>
+
<pre>void lua_call (lua_State *L, int nargs, int nresults);</pre>
+

+
<p>
+
Calls a function.
+

+

+
<p>
+
To call a function you must use the following protocol:
+
first, the function to be called is pushed onto the stack;
+
then, the arguments to the function are pushed
+
in direct order;
+
that is, the first argument is pushed first.
+
Finally you call <a href="#lua_call"><code>lua_call</code></a>;
+
<code>nargs</code> is the number of arguments that you pushed onto the stack.
+
All arguments and the function value are popped from the stack
+
when the function is called.
+
The function results are pushed onto the stack when the function returns.
+
The number of results is adjusted to <code>nresults</code>,
+
unless <code>nresults</code> is <a name="pdf-LUA_MULTRET"><code>LUA_MULTRET</code></a>.
+
In this case, all results from the function are pushed;
+
Lua takes care that the returned values fit into the stack space,
+
but it does not ensure any extra space in the stack.
+
The function results are pushed onto the stack in direct order
+
(the first result is pushed first),
+
so that after the call the last result is on the top of the stack.
+

+

+
<p>
+
Any error inside the called function is propagated upwards
+
(with a <code>longjmp</code>).
+

+

+
<p>
+
The following example shows how the host program can do the
+
equivalent to this Lua code:
+

+
<pre>
+
     a = f("how", t.x, 14)
+
</pre><p>
+
Here it is in&nbsp;C:
+

+
<pre>
+
     lua_getglobal(L, "f");                  /* function to be called */
+
     lua_pushliteral(L, "how");                       /* 1st argument */
+
     lua_getglobal(L, "t");                    /* table to be indexed */
+
     lua_getfield(L, -1, "x");        /* push result of t.x (2nd arg) */
+
     lua_remove(L, -2);                  /* remove 't' from the stack */
+
     lua_pushinteger(L, 14);                          /* 3rd argument */
+
     lua_call(L, 3, 1);     /* call 'f' with 3 arguments and 1 result */
+
     lua_setglobal(L, "a");                         /* set global 'a' */
+
</pre><p>
+
Note that the code above is <em>balanced</em>:
+
at its end, the stack is back to its original configuration.
+
This is considered good programming practice.
+

+

+

+

+

+
<hr><h3><a name="lua_callk"><code>lua_callk</code></a></h3><p>
+
<span class="apii">[-(nargs + 1), +nresults, <em>e</em>]</span>
+
<pre>void lua_callk (lua_State *L,
+
                int nargs,
+
                int nresults,
+
                lua_KContext ctx,
+
                lua_KFunction k);</pre>
+

+
<p>
+
This function behaves exactly like <a href="#lua_call"><code>lua_call</code></a>,
+
but allows the called function to yield (see <a href="#4.7">&sect;4.7</a>).
+

+

+

+

+

+
<hr><h3><a name="lua_CFunction"><code>lua_CFunction</code></a></h3>
+
<pre>typedef int (*lua_CFunction) (lua_State *L);</pre>
+

+
<p>
+
Type for C&nbsp;functions.
+

+

+
<p>
+
In order to communicate properly with Lua,
+
a C&nbsp;function must use the following protocol,
+
which defines the way parameters and results are passed:
+
a C&nbsp;function receives its arguments from Lua in its stack
+
in direct order (the first argument is pushed first).
+
So, when the function starts,
+
<code>lua_gettop(L)</code> returns the number of arguments received by the function.
+
The first argument (if any) is at index 1
+
and its last argument is at index <code>lua_gettop(L)</code>.
+
To return values to Lua, a C&nbsp;function just pushes them onto the stack,
+
in direct order (the first result is pushed first),
+
and returns the number of results.
+
Any other value in the stack below the results will be properly
+
discarded by Lua.
+
Like a Lua function, a C&nbsp;function called by Lua can also return
+
many results.
+

+

+
<p>
+
As an example, the following function receives a variable number
+
of numeric arguments and returns their average and their sum:
+

+
<pre>
+
     static int foo (lua_State *L) {
+
       int n = lua_gettop(L);    /* number of arguments */
+
       lua_Number sum = 0.0;
+
       int i;
+
       for (i = 1; i &lt;= n; i++) {
+
         if (!lua_isnumber(L, i)) {
+
           lua_pushliteral(L, "incorrect argument");
+
           lua_error(L);
+
         }
+
         sum += lua_tonumber(L, i);
+
       }
+
       lua_pushnumber(L, sum/n);        /* first result */
+
       lua_pushnumber(L, sum);         /* second result */
+
       return 2;                   /* number of results */
+
     }
+
</pre>
+

+

+

+

+
<hr><h3><a name="lua_checkstack"><code>lua_checkstack</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_checkstack (lua_State *L, int n);</pre>
+

+
<p>
+
Ensures that the stack has space for at least <code>n</code> extra slots
+
(that is, that you can safely push up to <code>n</code> values into it).
+
It returns false if it cannot fulfill the request,
+
either because it would cause the stack
+
to be larger than a fixed maximum size
+
(typically at least several thousand elements) or
+
because it cannot allocate memory for the extra space.
+
This function never shrinks the stack;
+
if the stack already has space for the extra slots,
+
it is left unchanged.
+

+

+

+

+

+
<hr><h3><a name="lua_close"><code>lua_close</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void lua_close (lua_State *L);</pre>
+

+
<p>
+
Destroys all objects in the given Lua state
+
(calling the corresponding garbage-collection metamethods, if any)
+
and frees all dynamic memory used by this state.
+
In several platforms, you may not need to call this function,
+
because all resources are naturally released when the host program ends.
+
On the other hand, long-running programs that create multiple states,
+
such as daemons or web servers,
+
will probably need to close states as soon as they are not needed.
+

+

+

+

+

+
<hr><h3><a name="lua_compare"><code>lua_compare</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>e</em>]</span>
+
<pre>int lua_compare (lua_State *L, int index1, int index2, int op);</pre>
+

+
<p>
+
Compares two Lua values.
+
Returns 1 if the value at index <code>index1</code> satisfies <code>op</code>
+
when compared with the value at index <code>index2</code>,
+
following the semantics of the corresponding Lua operator
+
(that is, it may call metamethods).
+
Otherwise returns&nbsp;0.
+
Also returns&nbsp;0 if any of the indices is not valid.
+

+

+
<p>
+
The value of <code>op</code> must be one of the following constants:
+

+
<ul>
+

+
<li><b><a name="pdf-LUA_OPEQ"><code>LUA_OPEQ</code></a>: </b> compares for equality (<code>==</code>)</li>
+
<li><b><a name="pdf-LUA_OPLT"><code>LUA_OPLT</code></a>: </b> compares for less than (<code>&lt;</code>)</li>
+
<li><b><a name="pdf-LUA_OPLE"><code>LUA_OPLE</code></a>: </b> compares for less or equal (<code>&lt;=</code>)</li>
+

+
</ul>
+

+

+

+

+
<hr><h3><a name="lua_concat"><code>lua_concat</code></a></h3><p>
+
<span class="apii">[-n, +1, <em>e</em>]</span>
+
<pre>void lua_concat (lua_State *L, int n);</pre>
+

+
<p>
+
Concatenates the <code>n</code> values at the top of the stack,
+
pops them, and leaves the result at the top.
+
If <code>n</code>&nbsp;is&nbsp;1, the result is the single value on the stack
+
(that is, the function does nothing);
+
if <code>n</code> is 0, the result is the empty string.
+
Concatenation is performed following the usual semantics of Lua
+
(see <a href="#3.4.6">&sect;3.4.6</a>).
+

+

+

+

+

+
<hr><h3><a name="lua_copy"><code>lua_copy</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void lua_copy (lua_State *L, int fromidx, int toidx);</pre>
+

+
<p>
+
Copies the element at index <code>fromidx</code>
+
into the valid index <code>toidx</code>,
+
replacing the value at that position.
+
Values at other positions are not affected.
+

+

+

+

+

+
<hr><h3><a name="lua_createtable"><code>lua_createtable</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>void lua_createtable (lua_State *L, int narr, int nrec);</pre>
+

+
<p>
+
Creates a new empty table and pushes it onto the stack.
+
Parameter <code>narr</code> is a hint for how many elements the table
+
will have as a sequence;
+
parameter <code>nrec</code> is a hint for how many other elements
+
the table will have.
+
Lua may use these hints to preallocate memory for the new table.
+
This preallocation is useful for performance when you know in advance
+
how many elements the table will have.
+
Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</code></a>.
+

+

+

+

+

+
<hr><h3><a name="lua_dump"><code>lua_dump</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_dump (lua_State *L,
+
                        lua_Writer writer,
+
                        void *data,
+
                        int strip);</pre>
+

+
<p>
+
Dumps a function as a binary chunk.
+
Receives a Lua function on the top of the stack
+
and produces a binary chunk that,
+
if loaded again,
+
results in a function equivalent to the one dumped.
+
As it produces parts of the chunk,
+
<a href="#lua_dump"><code>lua_dump</code></a> calls function <code>writer</code> (see <a href="#lua_Writer"><code>lua_Writer</code></a>)
+
with the given <code>data</code>
+
to write them.
+

+

+
<p>
+
If <code>strip</code> is true,
+
the binary representation may not include all debug information
+
about the function,
+
to save space.
+

+

+
<p>
+
The value returned is the error code returned by the last
+
call to the writer;
+
0&nbsp;means no errors.
+

+

+
<p>
+
This function does not pop the Lua function from the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_error"><code>lua_error</code></a></h3><p>
+
<span class="apii">[-1, +0, <em>v</em>]</span>
+
<pre>int lua_error (lua_State *L);</pre>
+

+
<p>
+
Generates a Lua error,
+
using the value at the top of the stack as the error object.
+
This function does a long jump,
+
and therefore never returns
+
(see <a href="#luaL_error"><code>luaL_error</code></a>).
+

+

+

+

+

+
<hr><h3><a name="lua_gc"><code>lua_gc</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>m</em>]</span>
+
<pre>int lua_gc (lua_State *L, int what, int data);</pre>
+

+
<p>
+
Controls the garbage collector.
+

+

+
<p>
+
This function performs several tasks,
+
according to the value of the parameter <code>what</code>:
+

+
<ul>
+

+
<li><b><code>LUA_GCSTOP</code>: </b>
+
stops the garbage collector.
+
</li>
+

+
<li><b><code>LUA_GCRESTART</code>: </b>
+
restarts the garbage collector.
+
</li>
+

+
<li><b><code>LUA_GCCOLLECT</code>: </b>
+
performs a full garbage-collection cycle.
+
</li>
+

+
<li><b><code>LUA_GCCOUNT</code>: </b>
+
returns the current amount of memory (in Kbytes) in use by Lua.
+
</li>
+

+
<li><b><code>LUA_GCCOUNTB</code>: </b>
+
returns the remainder of dividing the current amount of bytes of
+
memory in use by Lua by 1024.
+
</li>
+

+
<li><b><code>LUA_GCSTEP</code>: </b>
+
performs an incremental step of garbage collection.
+
</li>
+

+
<li><b><code>LUA_GCSETPAUSE</code>: </b>
+
sets <code>data</code> as the new value
+
for the <em>pause</em> of the collector (see <a href="#2.5">&sect;2.5</a>)
+
and returns the previous value of the pause.
+
</li>
+

+
<li><b><code>LUA_GCSETSTEPMUL</code>: </b>
+
sets <code>data</code> as the new value for the <em>step multiplier</em> of
+
the collector (see <a href="#2.5">&sect;2.5</a>)
+
and returns the previous value of the step multiplier.
+
</li>
+

+
<li><b><code>LUA_GCISRUNNING</code>: </b>
+
returns a boolean that tells whether the collector is running
+
(i.e., not stopped).
+
</li>
+

+
</ul>
+

+
<p>
+
For more details about these options,
+
see <a href="#pdf-collectgarbage"><code>collectgarbage</code></a>.
+

+

+

+

+

+
<hr><h3><a name="lua_getallocf"><code>lua_getallocf</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_Alloc lua_getallocf (lua_State *L, void **ud);</pre>
+

+
<p>
+
Returns the memory-allocation function of a given state.
+
If <code>ud</code> is not <code>NULL</code>, Lua stores in <code>*ud</code> the
+
opaque pointer given when the memory-allocator function was set.
+

+

+

+

+

+
<hr><h3><a name="lua_getfield"><code>lua_getfield</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>e</em>]</span>
+
<pre>int lua_getfield (lua_State *L, int index, const char *k);</pre>
+

+
<p>
+
Pushes onto the stack the value <code>t[k]</code>,
+
where <code>t</code> is the value at the given index.
+
As in Lua, this function may trigger a metamethod
+
for the "index" event (see <a href="#2.4">&sect;2.4</a>).
+

+

+
<p>
+
Returns the type of the pushed value.
+

+

+

+

+

+
<hr><h3><a name="lua_getextraspace"><code>lua_getextraspace</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void *lua_getextraspace (lua_State *L);</pre>
+

+
<p>
+
Returns a pointer to a raw memory area associated with the
+
given Lua state.
+
The application can use this area for any purpose;
+
Lua does not use it for anything.
+

+

+
<p>
+
Each new thread has this area initialized with a copy
+
of the area of the main thread.
+

+

+
<p>
+
By default, this area has the size of a pointer to void,
+
but you can recompile Lua with a different size for this area.
+
(See <code>LUA_EXTRASPACE</code> in <code>luaconf.h</code>.)
+

+

+

+

+

+
<hr><h3><a name="lua_getglobal"><code>lua_getglobal</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>e</em>]</span>
+
<pre>int lua_getglobal (lua_State *L, const char *name);</pre>
+

+
<p>
+
Pushes onto the stack the value of the global <code>name</code>.
+
Returns the type of that value.
+

+

+

+

+

+
<hr><h3><a name="lua_geti"><code>lua_geti</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>e</em>]</span>
+
<pre>int lua_geti (lua_State *L, int index, lua_Integer i);</pre>
+

+
<p>
+
Pushes onto the stack the value <code>t[i]</code>,
+
where <code>t</code> is the value at the given index.
+
As in Lua, this function may trigger a metamethod
+
for the "index" event (see <a href="#2.4">&sect;2.4</a>).
+

+

+
<p>
+
Returns the type of the pushed value.
+

+

+

+

+

+
<hr><h3><a name="lua_getmetatable"><code>lua_getmetatable</code></a></h3><p>
+
<span class="apii">[-0, +(0|1), &ndash;]</span>
+
<pre>int lua_getmetatable (lua_State *L, int index);</pre>
+

+
<p>
+
If the value at the given index has a metatable,
+
the function pushes that metatable onto the stack and returns&nbsp;1.
+
Otherwise,
+
the function returns&nbsp;0 and pushes nothing on the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_gettable"><code>lua_gettable</code></a></h3><p>
+
<span class="apii">[-1, +1, <em>e</em>]</span>
+
<pre>int lua_gettable (lua_State *L, int index);</pre>
+

+
<p>
+
Pushes onto the stack the value <code>t[k]</code>,
+
where <code>t</code> is the value at the given index
+
and <code>k</code> is the value at the top of the stack.
+

+

+
<p>
+
This function pops the key from the stack,
+
pushing the resulting value in its place.
+
As in Lua, this function may trigger a metamethod
+
for the "index" event (see <a href="#2.4">&sect;2.4</a>).
+

+

+
<p>
+
Returns the type of the pushed value.
+

+

+

+

+

+
<hr><h3><a name="lua_gettop"><code>lua_gettop</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_gettop (lua_State *L);</pre>
+

+
<p>
+
Returns the index of the top element in the stack.
+
Because indices start at&nbsp;1,
+
this result is equal to the number of elements in the stack;
+
in particular, 0&nbsp;means an empty stack.
+

+

+

+

+

+
<hr><h3><a name="lua_getuservalue"><code>lua_getuservalue</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>int lua_getuservalue (lua_State *L, int index);</pre>
+

+
<p>
+
Pushes onto the stack the Lua value associated with the full userdata
+
at the given index.
+

+

+
<p>
+
Returns the type of the pushed value.
+

+

+

+

+

+
<hr><h3><a name="lua_insert"><code>lua_insert</code></a></h3><p>
+
<span class="apii">[-1, +1, &ndash;]</span>
+
<pre>void lua_insert (lua_State *L, int index);</pre>
+

+
<p>
+
Moves the top element into the given valid index,
+
shifting up the elements above this index to open space.
+
This function cannot be called with a pseudo-index,
+
because a pseudo-index is not an actual stack position.
+

+

+

+

+

+
<hr><h3><a name="lua_Integer"><code>lua_Integer</code></a></h3>
+
<pre>typedef ... lua_Integer;</pre>
+

+
<p>
+
The type of integers in Lua.
+

+

+
<p>
+
By default this type is <code>long long</code>,
+
(usually a 64-bit two-complement integer),
+
but that can be changed to <code>long</code> or <code>int</code>
+
(usually a 32-bit two-complement integer).
+
(See <code>LUA_INT_TYPE</code> in <code>luaconf.h</code>.)
+

+

+
<p>
+
Lua also defines the constants
+
<a name="pdf-LUA_MININTEGER"><code>LUA_MININTEGER</code></a> and <a name="pdf-LUA_MAXINTEGER"><code>LUA_MAXINTEGER</code></a>,
+
with the minimum and the maximum values that fit in this type.
+

+

+

+

+

+
<hr><h3><a name="lua_isboolean"><code>lua_isboolean</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isboolean (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is a boolean,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_iscfunction"><code>lua_iscfunction</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_iscfunction (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is a C&nbsp;function,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isfunction"><code>lua_isfunction</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isfunction (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is a function
+
(either C or Lua), and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isinteger"><code>lua_isinteger</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isinteger (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is an integer
+
(that is, the value is a number and is represented as an integer),
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_islightuserdata"><code>lua_islightuserdata</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_islightuserdata (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is a light userdata,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isnil"><code>lua_isnil</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isnil (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is <b>nil</b>,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isnone"><code>lua_isnone</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isnone (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the given index is not valid,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isnoneornil"><code>lua_isnoneornil</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isnoneornil (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the given index is not valid
+
or if the value at this index is <b>nil</b>,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isnumber"><code>lua_isnumber</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isnumber (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is a number
+
or a string convertible to a number,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isstring"><code>lua_isstring</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isstring (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is a string
+
or a number (which is always convertible to a string),
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_istable"><code>lua_istable</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_istable (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is a table,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isthread"><code>lua_isthread</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isthread (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is a thread,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isuserdata"><code>lua_isuserdata</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isuserdata (lua_State *L, int index);</pre>
+

+
<p>
+
Returns 1 if the value at the given index is a userdata
+
(either full or light), and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_isyieldable"><code>lua_isyieldable</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_isyieldable (lua_State *L);</pre>
+

+
<p>
+
Returns 1 if the given coroutine can yield,
+
and 0&nbsp;otherwise.
+

+

+

+

+

+
<hr><h3><a name="lua_KContext"><code>lua_KContext</code></a></h3>
+
<pre>typedef ... lua_KContext;</pre>
+

+
<p>
+
The type for continuation-function contexts.
+
It must be a numeric type.
+
This type is defined as <code>intptr_t</code>
+
when <code>intptr_t</code> is available,
+
so that it can store pointers too.
+
Otherwise, it is defined as <code>ptrdiff_t</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_KFunction"><code>lua_KFunction</code></a></h3>
+
<pre>typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);</pre>
+

+
<p>
+
Type for continuation functions (see <a href="#4.7">&sect;4.7</a>).
+

+

+

+

+

+
<hr><h3><a name="lua_len"><code>lua_len</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>e</em>]</span>
+
<pre>void lua_len (lua_State *L, int index);</pre>
+

+
<p>
+
Returns the length of the value at the given index.
+
It is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.7">&sect;3.4.7</a>) and
+
may trigger a metamethod for the "length" event (see <a href="#2.4">&sect;2.4</a>).
+
The result is pushed on the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_load"><code>lua_load</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>int lua_load (lua_State *L,
+
              lua_Reader reader,
+
              void *data,
+
              const char *chunkname,
+
              const char *mode);</pre>
+

+
<p>
+
Loads a Lua chunk without running it.
+
If there are no errors,
+
<code>lua_load</code> pushes the compiled chunk as a Lua
+
function on top of the stack.
+
Otherwise, it pushes an error message.
+

+

+
<p>
+
The return values of <code>lua_load</code> are:
+

+
<ul>
+

+
<li><b><a href="#pdf-LUA_OK"><code>LUA_OK</code></a>: </b> no errors;</li>
+

+
<li><b><a name="pdf-LUA_ERRSYNTAX"><code>LUA_ERRSYNTAX</code></a>: </b>
+
syntax error during precompilation;</li>
+

+
<li><b><a href="#pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>: </b>
+
memory allocation (out-of-memory) error;</li>
+

+
<li><b><a href="#pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>: </b>
+
error while running a <code>__gc</code> metamethod.
+
(This error has no relation with the chunk being loaded.
+
It is generated by the garbage collector.)
+
</li>
+

+
</ul>
+

+
<p>
+
The <code>lua_load</code> function uses a user-supplied <code>reader</code> function
+
to read the chunk (see <a href="#lua_Reader"><code>lua_Reader</code></a>).
+
The <code>data</code> argument is an opaque value passed to the reader function.
+

+

+
<p>
+
The <code>chunkname</code> argument gives a name to the chunk,
+
which is used for error messages and in debug information (see <a href="#4.9">&sect;4.9</a>).
+

+

+
<p>
+
<code>lua_load</code> automatically detects whether the chunk is text or binary
+
and loads it accordingly (see program <code>luac</code>).
+
The string <code>mode</code> works as in function <a href="#pdf-load"><code>load</code></a>,
+
with the addition that
+
a <code>NULL</code> value is equivalent to the string "<code>bt</code>".
+

+

+
<p>
+
<code>lua_load</code> uses the stack internally,
+
so the reader function must always leave the stack
+
unmodified when returning.
+

+

+
<p>
+
If the resulting function has upvalues,
+
its first upvalue is set to the value of the global environment
+
stored at index <code>LUA_RIDX_GLOBALS</code> in the registry (see <a href="#4.5">&sect;4.5</a>).
+
When loading main chunks,
+
this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).
+
Other upvalues are initialized with <b>nil</b>.
+

+

+

+

+

+
<hr><h3><a name="lua_newstate"><code>lua_newstate</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_State *lua_newstate (lua_Alloc f, void *ud);</pre>
+

+
<p>
+
Creates a new thread running in a new, independent state.
+
Returns <code>NULL</code> if it cannot create the thread or the state
+
(due to lack of memory).
+
The argument <code>f</code> is the allocator function;
+
Lua does all memory allocation for this state
+
through this function (see <a href="#lua_Alloc"><code>lua_Alloc</code></a>).
+
The second argument, <code>ud</code>, is an opaque pointer that Lua
+
passes to the allocator in every call.
+

+

+

+

+

+
<hr><h3><a name="lua_newtable"><code>lua_newtable</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>void lua_newtable (lua_State *L);</pre>
+

+
<p>
+
Creates a new empty table and pushes it onto the stack.
+
It is equivalent to <code>lua_createtable(L, 0, 0)</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_newthread"><code>lua_newthread</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>lua_State *lua_newthread (lua_State *L);</pre>
+

+
<p>
+
Creates a new thread, pushes it on the stack,
+
and returns a pointer to a <a href="#lua_State"><code>lua_State</code></a> that represents this new thread.
+
The new thread returned by this function shares with the original thread
+
its global environment,
+
but has an independent execution stack.
+

+

+
<p>
+
There is no explicit function to close or to destroy a thread.
+
Threads are subject to garbage collection,
+
like any Lua object.
+

+

+

+

+

+
<hr><h3><a name="lua_newuserdata"><code>lua_newuserdata</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>void *lua_newuserdata (lua_State *L, size_t size);</pre>
+

+
<p>
+
This function allocates a new block of memory with the given size,
+
pushes onto the stack a new full userdata with the block address,
+
and returns this address.
+
The host program can freely use this memory.
+

+

+

+

+

+
<hr><h3><a name="lua_next"><code>lua_next</code></a></h3><p>
+
<span class="apii">[-1, +(2|0), <em>e</em>]</span>
+
<pre>int lua_next (lua_State *L, int index);</pre>
+

+
<p>
+
Pops a key from the stack,
+
and pushes a key&ndash;value pair from the table at the given index
+
(the "next" pair after the given key).
+
If there are no more elements in the table,
+
then <a href="#lua_next"><code>lua_next</code></a> returns 0 (and pushes nothing).
+

+

+
<p>
+
A typical traversal looks like this:
+

+
<pre>
+
     /* table is in the stack at index 't' */
+
     lua_pushnil(L);  /* first key */
+
     while (lua_next(L, t) != 0) {
+
       /* uses 'key' (at index -2) and 'value' (at index -1) */
+
       printf("%s - %s\n",
+
              lua_typename(L, lua_type(L, -2)),
+
              lua_typename(L, lua_type(L, -1)));
+
       /* removes 'value'; keeps 'key' for next iteration */
+
       lua_pop(L, 1);
+
     }
+
</pre>
+

+
<p>
+
While traversing a table,
+
do not call <a href="#lua_tolstring"><code>lua_tolstring</code></a> directly on a key,
+
unless you know that the key is actually a string.
+
Recall that <a href="#lua_tolstring"><code>lua_tolstring</code></a> may change
+
the value at the given index;
+
this confuses the next call to <a href="#lua_next"><code>lua_next</code></a>.
+

+

+
<p>
+
See function <a href="#pdf-next"><code>next</code></a> for the caveats of modifying
+
the table during its traversal.
+

+

+

+

+

+
<hr><h3><a name="lua_Number"><code>lua_Number</code></a></h3>
+
<pre>typedef ... lua_Number;</pre>
+

+
<p>
+
The type of floats in Lua.
+

+

+
<p>
+
By default this type is double,
+
but that can be changed to a single float or a long double.
+
(See <code>LUA_FLOAT_TYPE</code> in <code>luaconf.h</code>.)
+

+

+

+

+

+
<hr><h3><a name="lua_numbertointeger"><code>lua_numbertointeger</code></a></h3>
+
<pre>int lua_numbertointeger (lua_Number n, lua_Integer *p);</pre>
+

+
<p>
+
Converts a Lua float to a Lua integer.
+
This macro assumes that <code>n</code> has an integral value.
+
If that value is within the range of Lua integers,
+
it is converted to an integer and assigned to <code>*p</code>.
+
The macro results in a boolean indicating whether the
+
conversion was successful.
+
(Note that this range test can be tricky to do
+
correctly without this macro,
+
due to roundings.)
+

+

+
<p>
+
This macro may evaluate its arguments more than once.
+

+

+

+

+

+
<hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p>
+
<span class="apii">[-(nargs + 1), +(nresults|1), &ndash;]</span>
+
<pre>int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);</pre>
+

+
<p>
+
Calls a function in protected mode.
+

+

+
<p>
+
Both <code>nargs</code> and <code>nresults</code> have the same meaning as
+
in <a href="#lua_call"><code>lua_call</code></a>.
+
If there are no errors during the call,
+
<a href="#lua_pcall"><code>lua_pcall</code></a> behaves exactly like <a href="#lua_call"><code>lua_call</code></a>.
+
However, if there is any error,
+
<a href="#lua_pcall"><code>lua_pcall</code></a> catches it,
+
pushes a single value on the stack (the error object),
+
and returns an error code.
+
Like <a href="#lua_call"><code>lua_call</code></a>,
+
<a href="#lua_pcall"><code>lua_pcall</code></a> always removes the function
+
and its arguments from the stack.
+

+

+
<p>
+
If <code>msgh</code> is 0,
+
then the error object returned on the stack
+
is exactly the original error object.
+
Otherwise, <code>msgh</code> is the stack index of a
+
<em>message handler</em>.
+
(This index cannot be a pseudo-index.)
+
In case of runtime errors,
+
this function will be called with the error object
+
and its return value will be the object
+
returned on the stack by <a href="#lua_pcall"><code>lua_pcall</code></a>.
+

+

+
<p>
+
Typically, the message handler is used to add more debug
+
information to the error object, such as a stack traceback.
+
Such information cannot be gathered after the return of <a href="#lua_pcall"><code>lua_pcall</code></a>,
+
since by then the stack has unwound.
+

+

+
<p>
+
The <a href="#lua_pcall"><code>lua_pcall</code></a> function returns one of the following constants
+
(defined in <code>lua.h</code>):
+

+
<ul>
+

+
<li><b><a name="pdf-LUA_OK"><code>LUA_OK</code></a> (0): </b>
+
success.</li>
+

+
<li><b><a name="pdf-LUA_ERRRUN"><code>LUA_ERRRUN</code></a>: </b>
+
a runtime error.
+
</li>
+

+
<li><b><a name="pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>: </b>
+
memory allocation error.
+
For such errors, Lua does not call the message handler.
+
</li>
+

+
<li><b><a name="pdf-LUA_ERRERR"><code>LUA_ERRERR</code></a>: </b>
+
error while running the message handler.
+
</li>
+

+
<li><b><a name="pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>: </b>
+
error while running a <code>__gc</code> metamethod.
+
For such errors, Lua does not call the message handler
+
(as this kind of error typically has no relation
+
with the function being called).
+
</li>
+

+
</ul>
+

+

+

+

+
<hr><h3><a name="lua_pcallk"><code>lua_pcallk</code></a></h3><p>
+
<span class="apii">[-(nargs + 1), +(nresults|1), &ndash;]</span>
+
<pre>int lua_pcallk (lua_State *L,
+
                int nargs,
+
                int nresults,
+
                int msgh,
+
                lua_KContext ctx,
+
                lua_KFunction k);</pre>
+

+
<p>
+
This function behaves exactly like <a href="#lua_pcall"><code>lua_pcall</code></a>,
+
but allows the called function to yield (see <a href="#4.7">&sect;4.7</a>).
+

+

+

+

+

+
<hr><h3><a name="lua_pop"><code>lua_pop</code></a></h3><p>
+
<span class="apii">[-n, +0, &ndash;]</span>
+
<pre>void lua_pop (lua_State *L, int n);</pre>
+

+
<p>
+
Pops <code>n</code> elements from the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_pushboolean"><code>lua_pushboolean</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>void lua_pushboolean (lua_State *L, int b);</pre>
+

+
<p>
+
Pushes a boolean value with value <code>b</code> onto the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_pushcclosure"><code>lua_pushcclosure</code></a></h3><p>
+
<span class="apii">[-n, +1, <em>m</em>]</span>
+
<pre>void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);</pre>
+

+
<p>
+
Pushes a new C&nbsp;closure onto the stack.
+

+

+
<p>
+
When a C&nbsp;function is created,
+
it is possible to associate some values with it,
+
thus creating a C&nbsp;closure (see <a href="#4.4">&sect;4.4</a>);
+
these values are then accessible to the function whenever it is called.
+
To associate values with a C&nbsp;function,
+
first these values must be pushed onto the stack
+
(when there are multiple values, the first value is pushed first).
+
Then <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>
+
is called to create and push the C&nbsp;function onto the stack,
+
with the argument <code>n</code> telling how many values will be
+
associated with the function.
+
<a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a> also pops these values from the stack.
+

+

+
<p>
+
The maximum value for <code>n</code> is 255.
+

+

+
<p>
+
When <code>n</code> is zero,
+
this function creates a <em>light C&nbsp;function</em>,
+
which is just a pointer to the C&nbsp;function.
+
In that case, it never raises a memory error.
+

+

+

+

+

+
<hr><h3><a name="lua_pushcfunction"><code>lua_pushcfunction</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre>
+

+
<p>
+
Pushes a C&nbsp;function onto the stack.
+
This function receives a pointer to a C&nbsp;function
+
and pushes onto the stack a Lua value of type <code>function</code> that,
+
when called, invokes the corresponding C&nbsp;function.
+

+

+
<p>
+
Any function to be callable by Lua must
+
follow the correct protocol to receive its parameters
+
and return its results (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
+

+

+

+

+

+
<hr><h3><a name="lua_pushfstring"><code>lua_pushfstring</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>e</em>]</span>
+
<pre>const char *lua_pushfstring (lua_State *L, const char *fmt, ...);</pre>
+

+
<p>
+
Pushes onto the stack a formatted string
+
and returns a pointer to this string.
+
It is similar to the ISO&nbsp;C function <code>sprintf</code>,
+
but has some important differences:
+

+
<ul>
+

+
<li>
+
You do not have to allocate space for the result:
+
the result is a Lua string and Lua takes care of memory allocation
+
(and deallocation, through garbage collection).
+
</li>
+

+
<li>
+
The conversion specifiers are quite restricted.
+
There are no flags, widths, or precisions.
+
The conversion specifiers can only be
+
'<code>%%</code>' (inserts the character '<code>%</code>'),
+
'<code>%s</code>' (inserts a zero-terminated string, with no size restrictions),
+
'<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>),
+
'<code>%I</code>' (inserts a <a href="#lua_Integer"><code>lua_Integer</code></a>),
+
'<code>%p</code>' (inserts a pointer as a hexadecimal numeral),
+
'<code>%d</code>' (inserts an <code>int</code>),
+
'<code>%c</code>' (inserts an <code>int</code> as a one-byte character), and
+
'<code>%U</code>' (inserts a <code>long int</code> as a UTF-8 byte sequence).
+
</li>
+

+
</ul>
+

+
<p>
+
Unlike other push functions,
+
this function checks for the stack space it needs,
+
including the slot for its result.
+

+

+

+

+

+
<hr><h3><a name="lua_pushglobaltable"><code>lua_pushglobaltable</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>void lua_pushglobaltable (lua_State *L);</pre>
+

+
<p>
+
Pushes the global environment onto the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_pushinteger"><code>lua_pushinteger</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>void lua_pushinteger (lua_State *L, lua_Integer n);</pre>
+

+
<p>
+
Pushes an integer with value <code>n</code> onto the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_pushlightuserdata"><code>lua_pushlightuserdata</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>void lua_pushlightuserdata (lua_State *L, void *p);</pre>
+

+
<p>
+
Pushes a light userdata onto the stack.
+

+

+
<p>
+
Userdata represent C&nbsp;values in Lua.
+
A <em>light userdata</em> represents a pointer, a <code>void*</code>.
+
It is a value (like a number):
+
you do not create it, it has no individual metatable,
+
and it is not collected (as it was never created).
+
A light userdata is equal to "any"
+
light userdata with the same C&nbsp;address.
+

+

+

+

+

+
<hr><h3><a name="lua_pushliteral"><code>lua_pushliteral</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>const char *lua_pushliteral (lua_State *L, const char *s);</pre>
+

+
<p>
+
This macro is equivalent to <a href="#lua_pushstring"><code>lua_pushstring</code></a>,
+
but should be used only when <code>s</code> is a literal string.
+

+

+

+

+

+
<hr><h3><a name="lua_pushlstring"><code>lua_pushlstring</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>const char *lua_pushlstring (lua_State *L, const char *s, size_t len);</pre>
+

+
<p>
+
Pushes the string pointed to by <code>s</code> with size <code>len</code>
+
onto the stack.
+
Lua makes (or reuses) an internal copy of the given string,
+
so the memory at <code>s</code> can be freed or reused immediately after
+
the function returns.
+
The string can contain any binary data,
+
including embedded zeros.
+

+

+
<p>
+
Returns a pointer to the internal copy of the string.
+

+

+

+

+

+
<hr><h3><a name="lua_pushnil"><code>lua_pushnil</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>void lua_pushnil (lua_State *L);</pre>
+

+
<p>
+
Pushes a nil value onto the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_pushnumber"><code>lua_pushnumber</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre>
+

+
<p>
+
Pushes a float with value <code>n</code> onto the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_pushstring"><code>lua_pushstring</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>const char *lua_pushstring (lua_State *L, const char *s);</pre>
+

+
<p>
+
Pushes the zero-terminated string pointed to by <code>s</code>
+
onto the stack.
+
Lua makes (or reuses) an internal copy of the given string,
+
so the memory at <code>s</code> can be freed or reused immediately after
+
the function returns.
+

+

+
<p>
+
Returns a pointer to the internal copy of the string.
+

+

+
<p>
+
If <code>s</code> is <code>NULL</code>, pushes <b>nil</b> and returns <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_pushthread"><code>lua_pushthread</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>int lua_pushthread (lua_State *L);</pre>
+

+
<p>
+
Pushes the thread represented by <code>L</code> onto the stack.
+
Returns 1 if this thread is the main thread of its state.
+

+

+

+

+

+
<hr><h3><a name="lua_pushvalue"><code>lua_pushvalue</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>void lua_pushvalue (lua_State *L, int index);</pre>
+

+
<p>
+
Pushes a copy of the element at the given index
+
onto the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_pushvfstring"><code>lua_pushvfstring</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>const char *lua_pushvfstring (lua_State *L,
+
                              const char *fmt,
+
                              va_list argp);</pre>
+

+
<p>
+
Equivalent to <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>, except that it receives a <code>va_list</code>
+
instead of a variable number of arguments.
+

+

+

+

+

+
<hr><h3><a name="lua_rawequal"><code>lua_rawequal</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_rawequal (lua_State *L, int index1, int index2);</pre>
+

+
<p>
+
Returns 1 if the two values in indices <code>index1</code> and
+
<code>index2</code> are primitively equal
+
(that is, without calling the <code>__eq</code> metamethod).
+
Otherwise returns&nbsp;0.
+
Also returns&nbsp;0 if any of the indices are not valid.
+

+

+

+

+

+
<hr><h3><a name="lua_rawget"><code>lua_rawget</code></a></h3><p>
+
<span class="apii">[-1, +1, &ndash;]</span>
+
<pre>int lua_rawget (lua_State *L, int index);</pre>
+

+
<p>
+
Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw access
+
(i.e., without metamethods).
+

+

+

+

+

+
<hr><h3><a name="lua_rawgeti"><code>lua_rawgeti</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>int lua_rawgeti (lua_State *L, int index, lua_Integer n);</pre>
+

+
<p>
+
Pushes onto the stack the value <code>t[n]</code>,
+
where <code>t</code> is the table at the given index.
+
The access is raw,
+
that is, it does not invoke the <code>__index</code> metamethod.
+

+

+
<p>
+
Returns the type of the pushed value.
+

+

+

+

+

+
<hr><h3><a name="lua_rawgetp"><code>lua_rawgetp</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>int lua_rawgetp (lua_State *L, int index, const void *p);</pre>
+

+
<p>
+
Pushes onto the stack the value <code>t[k]</code>,
+
where <code>t</code> is the table at the given index and
+
<code>k</code> is the pointer <code>p</code> represented as a light userdata.
+
The access is raw;
+
that is, it does not invoke the <code>__index</code> metamethod.
+

+

+
<p>
+
Returns the type of the pushed value.
+

+

+

+

+

+
<hr><h3><a name="lua_rawlen"><code>lua_rawlen</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>size_t lua_rawlen (lua_State *L, int index);</pre>
+

+
<p>
+
Returns the raw "length" of the value at the given index:
+
for strings, this is the string length;
+
for tables, this is the result of the length operator ('<code>#</code>')
+
with no metamethods;
+
for userdata, this is the size of the block of memory allocated
+
for the userdata;
+
for other values, it is&nbsp;0.
+

+

+

+

+

+
<hr><h3><a name="lua_rawset"><code>lua_rawset</code></a></h3><p>
+
<span class="apii">[-2, +0, <em>m</em>]</span>
+
<pre>void lua_rawset (lua_State *L, int index);</pre>
+

+
<p>
+
Similar to <a href="#lua_settable"><code>lua_settable</code></a>, but does a raw assignment
+
(i.e., without metamethods).
+

+

+

+

+

+
<hr><h3><a name="lua_rawseti"><code>lua_rawseti</code></a></h3><p>
+
<span class="apii">[-1, +0, <em>m</em>]</span>
+
<pre>void lua_rawseti (lua_State *L, int index, lua_Integer i);</pre>
+

+
<p>
+
Does the equivalent of <code>t[i] = v</code>,
+
where <code>t</code> is the table at the given index
+
and <code>v</code> is the value at the top of the stack.
+

+

+
<p>
+
This function pops the value from the stack.
+
The assignment is raw,
+
that is, it does not invoke the <code>__newindex</code> metamethod.
+

+

+

+

+

+
<hr><h3><a name="lua_rawsetp"><code>lua_rawsetp</code></a></h3><p>
+
<span class="apii">[-1, +0, <em>m</em>]</span>
+
<pre>void lua_rawsetp (lua_State *L, int index, const void *p);</pre>
+

+
<p>
+
Does the equivalent of <code>t[p] = v</code>,
+
where <code>t</code> is the table at the given index,
+
<code>p</code> is encoded as a light userdata,
+
and <code>v</code> is the value at the top of the stack.
+

+

+
<p>
+
This function pops the value from the stack.
+
The assignment is raw,
+
that is, it does not invoke <code>__newindex</code> metamethod.
+

+

+

+

+

+
<hr><h3><a name="lua_Reader"><code>lua_Reader</code></a></h3>
+
<pre>typedef const char * (*lua_Reader) (lua_State *L,
+
                                    void *data,
+
                                    size_t *size);</pre>
+

+
<p>
+
The reader function used by <a href="#lua_load"><code>lua_load</code></a>.
+
Every time it needs another piece of the chunk,
+
<a href="#lua_load"><code>lua_load</code></a> calls the reader,
+
passing along its <code>data</code> parameter.
+
The reader must return a pointer to a block of memory
+
with a new piece of the chunk
+
and set <code>size</code> to the block size.
+
The block must exist until the reader function is called again.
+
To signal the end of the chunk,
+
the reader must return <code>NULL</code> or set <code>size</code> to zero.
+
The reader function may return pieces of any size greater than zero.
+

+

+

+

+

+
<hr><h3><a name="lua_register"><code>lua_register</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>e</em>]</span>
+
<pre>void lua_register (lua_State *L, const char *name, lua_CFunction f);</pre>
+

+
<p>
+
Sets the C&nbsp;function <code>f</code> as the new value of global <code>name</code>.
+
It is defined as a macro:
+

+
<pre>
+
     #define lua_register(L,n,f) \
+
            (lua_pushcfunction(L, f), lua_setglobal(L, n))
+
</pre>
+

+

+

+

+
<hr><h3><a name="lua_remove"><code>lua_remove</code></a></h3><p>
+
<span class="apii">[-1, +0, &ndash;]</span>
+
<pre>void lua_remove (lua_State *L, int index);</pre>
+

+
<p>
+
Removes the element at the given valid index,
+
shifting down the elements above this index to fill the gap.
+
This function cannot be called with a pseudo-index,
+
because a pseudo-index is not an actual stack position.
+

+

+

+

+

+
<hr><h3><a name="lua_replace"><code>lua_replace</code></a></h3><p>
+
<span class="apii">[-1, +0, &ndash;]</span>
+
<pre>void lua_replace (lua_State *L, int index);</pre>
+

+
<p>
+
Moves the top element into the given valid index
+
without shifting any element
+
(therefore replacing the value at that given index),
+
and then pops the top element.
+

+

+

+

+

+
<hr><h3><a name="lua_resume"><code>lua_resume</code></a></h3><p>
+
<span class="apii">[-?, +?, &ndash;]</span>
+
<pre>int lua_resume (lua_State *L, lua_State *from, int nargs);</pre>
+

+
<p>
+
Starts and resumes a coroutine in the given thread <code>L</code>.
+

+

+
<p>
+
To start a coroutine,
+
you push onto the thread stack the main function plus any arguments;
+
then you call <a href="#lua_resume"><code>lua_resume</code></a>,
+
with <code>nargs</code> being the number of arguments.
+
This call returns when the coroutine suspends or finishes its execution.
+
When it returns, the stack contains all values passed to <a href="#lua_yield"><code>lua_yield</code></a>,
+
or all values returned by the body function.
+
<a href="#lua_resume"><code>lua_resume</code></a> returns
+
<a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the coroutine yields,
+
<a href="#pdf-LUA_OK"><code>LUA_OK</code></a> if the coroutine finishes its execution
+
without errors,
+
or an error code in case of errors (see <a href="#lua_pcall"><code>lua_pcall</code></a>).
+

+

+
<p>
+
In case of errors,
+
the stack is not unwound,
+
so you can use the debug API over it.
+
The error object is on the top of the stack.
+

+

+
<p>
+
To resume a coroutine,
+
you remove any results from the last <a href="#lua_yield"><code>lua_yield</code></a>,
+
put on its stack only the values to
+
be passed as results from <code>yield</code>,
+
and then call <a href="#lua_resume"><code>lua_resume</code></a>.
+

+

+
<p>
+
The parameter <code>from</code> represents the coroutine that is resuming <code>L</code>.
+
If there is no such coroutine,
+
this parameter can be <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_rotate"><code>lua_rotate</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void lua_rotate (lua_State *L, int idx, int n);</pre>
+

+
<p>
+
Rotates the stack elements between the valid index <code>idx</code>
+
and the top of the stack.
+
The elements are rotated <code>n</code> positions in the direction of the top,
+
for a positive <code>n</code>,
+
or <code>-n</code> positions in the direction of the bottom,
+
for a negative <code>n</code>.
+
The absolute value of <code>n</code> must not be greater than the size
+
of the slice being rotated.
+
This function cannot be called with a pseudo-index,
+
because a pseudo-index is not an actual stack position.
+

+

+

+

+

+
<hr><h3><a name="lua_setallocf"><code>lua_setallocf</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);</pre>
+

+
<p>
+
Changes the allocator function of a given state to <code>f</code>
+
with user data <code>ud</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_setfield"><code>lua_setfield</code></a></h3><p>
+
<span class="apii">[-1, +0, <em>e</em>]</span>
+
<pre>void lua_setfield (lua_State *L, int index, const char *k);</pre>
+

+
<p>
+
Does the equivalent to <code>t[k] = v</code>,
+
where <code>t</code> is the value at the given index
+
and <code>v</code> is the value at the top of the stack.
+

+

+
<p>
+
This function pops the value from the stack.
+
As in Lua, this function may trigger a metamethod
+
for the "newindex" event (see <a href="#2.4">&sect;2.4</a>).
+

+

+

+

+

+
<hr><h3><a name="lua_setglobal"><code>lua_setglobal</code></a></h3><p>
+
<span class="apii">[-1, +0, <em>e</em>]</span>
+
<pre>void lua_setglobal (lua_State *L, const char *name);</pre>
+

+
<p>
+
Pops a value from the stack and
+
sets it as the new value of global <code>name</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_seti"><code>lua_seti</code></a></h3><p>
+
<span class="apii">[-1, +0, <em>e</em>]</span>
+
<pre>void lua_seti (lua_State *L, int index, lua_Integer n);</pre>
+

+
<p>
+
Does the equivalent to <code>t[n] = v</code>,
+
where <code>t</code> is the value at the given index
+
and <code>v</code> is the value at the top of the stack.
+

+

+
<p>
+
This function pops the value from the stack.
+
As in Lua, this function may trigger a metamethod
+
for the "newindex" event (see <a href="#2.4">&sect;2.4</a>).
+

+

+

+

+

+
<hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p>
+
<span class="apii">[-1, +0, &ndash;]</span>
+
<pre>void lua_setmetatable (lua_State *L, int index);</pre>
+

+
<p>
+
Pops a table from the stack and
+
sets it as the new metatable for the value at the given index.
+

+

+

+

+

+
<hr><h3><a name="lua_settable"><code>lua_settable</code></a></h3><p>
+
<span class="apii">[-2, +0, <em>e</em>]</span>
+
<pre>void lua_settable (lua_State *L, int index);</pre>
+

+
<p>
+
Does the equivalent to <code>t[k] = v</code>,
+
where <code>t</code> is the value at the given index,
+
<code>v</code> is the value at the top of the stack,
+
and <code>k</code> is the value just below the top.
+

+

+
<p>
+
This function pops both the key and the value from the stack.
+
As in Lua, this function may trigger a metamethod
+
for the "newindex" event (see <a href="#2.4">&sect;2.4</a>).
+

+

+

+

+

+
<hr><h3><a name="lua_settop"><code>lua_settop</code></a></h3><p>
+
<span class="apii">[-?, +?, &ndash;]</span>
+
<pre>void lua_settop (lua_State *L, int index);</pre>
+

+
<p>
+
Accepts any index, or&nbsp;0,
+
and sets the stack top to this index.
+
If the new top is larger than the old one,
+
then the new elements are filled with <b>nil</b>.
+
If <code>index</code> is&nbsp;0, then all stack elements are removed.
+

+

+

+

+

+
<hr><h3><a name="lua_setuservalue"><code>lua_setuservalue</code></a></h3><p>
+
<span class="apii">[-1, +0, &ndash;]</span>
+
<pre>void lua_setuservalue (lua_State *L, int index);</pre>
+

+
<p>
+
Pops a value from the stack and sets it as
+
the new value associated to the full userdata at the given index.
+

+

+

+

+

+
<hr><h3><a name="lua_State"><code>lua_State</code></a></h3>
+
<pre>typedef struct lua_State lua_State;</pre>
+

+
<p>
+
An opaque structure that points to a thread and indirectly
+
(through the thread) to the whole state of a Lua interpreter.
+
The Lua library is fully reentrant:
+
it has no global variables.
+
All information about a state is accessible through this structure.
+

+

+
<p>
+
A pointer to this structure must be passed as the first argument to
+
every function in the library, except to <a href="#lua_newstate"><code>lua_newstate</code></a>,
+
which creates a Lua state from scratch.
+

+

+

+

+

+
<hr><h3><a name="lua_status"><code>lua_status</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_status (lua_State *L);</pre>
+

+
<p>
+
Returns the status of the thread <code>L</code>.
+

+

+
<p>
+
The status can be 0 (<a href="#pdf-LUA_OK"><code>LUA_OK</code></a>) for a normal thread,
+
an error code if the thread finished the execution
+
of a <a href="#lua_resume"><code>lua_resume</code></a> with an error,
+
or <a name="pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the thread is suspended.
+

+

+
<p>
+
You can only call functions in threads with status <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>.
+
You can resume threads with status <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>
+
(to start a new coroutine) or <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a>
+
(to resume a coroutine).
+

+

+

+

+

+
<hr><h3><a name="lua_stringtonumber"><code>lua_stringtonumber</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>size_t lua_stringtonumber (lua_State *L, const char *s);</pre>
+

+
<p>
+
Converts the zero-terminated string <code>s</code> to a number,
+
pushes that number into the stack,
+
and returns the total size of the string,
+
that is, its length plus one.
+
The conversion can result in an integer or a float,
+
according to the lexical conventions of Lua (see <a href="#3.1">&sect;3.1</a>).
+
The string may have leading and trailing spaces and a sign.
+
If the string is not a valid numeral,
+
returns 0 and pushes nothing.
+
(Note that the result can be used as a boolean,
+
true if the conversion succeeds.)
+

+

+

+

+

+
<hr><h3><a name="lua_toboolean"><code>lua_toboolean</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_toboolean (lua_State *L, int index);</pre>
+

+
<p>
+
Converts the Lua value at the given index to a C&nbsp;boolean
+
value (0&nbsp;or&nbsp;1).
+
Like all tests in Lua,
+
<a href="#lua_toboolean"><code>lua_toboolean</code></a> returns true for any Lua value
+
different from <b>false</b> and <b>nil</b>;
+
otherwise it returns false.
+
(If you want to accept only actual boolean values,
+
use <a href="#lua_isboolean"><code>lua_isboolean</code></a> to test the value's type.)
+

+

+

+

+

+
<hr><h3><a name="lua_tocfunction"><code>lua_tocfunction</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_CFunction lua_tocfunction (lua_State *L, int index);</pre>
+

+
<p>
+
Converts a value at the given index to a C&nbsp;function.
+
That value must be a C&nbsp;function;
+
otherwise, returns <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_tointeger"><code>lua_tointeger</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_Integer lua_tointeger (lua_State *L, int index);</pre>
+

+
<p>
+
Equivalent to <a href="#lua_tointegerx"><code>lua_tointegerx</code></a> with <code>isnum</code> equal to <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_tointegerx"><code>lua_tointegerx</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);</pre>
+

+
<p>
+
Converts the Lua value at the given index
+
to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>.
+
The Lua value must be an integer,
+
or a number or string convertible to an integer (see <a href="#3.4.3">&sect;3.4.3</a>);
+
otherwise, <code>lua_tointegerx</code> returns&nbsp;0.
+

+

+
<p>
+
If <code>isnum</code> is not <code>NULL</code>,
+
its referent is assigned a boolean value that
+
indicates whether the operation succeeded.
+

+

+

+

+

+
<hr><h3><a name="lua_tolstring"><code>lua_tolstring</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>m</em>]</span>
+
<pre>const char *lua_tolstring (lua_State *L, int index, size_t *len);</pre>
+

+
<p>
+
Converts the Lua value at the given index to a C&nbsp;string.
+
If <code>len</code> is not <code>NULL</code>,
+
it sets <code>*len</code> with the string length.
+
The Lua value must be a string or a number;
+
otherwise, the function returns <code>NULL</code>.
+
If the value is a number,
+
then <code>lua_tolstring</code> also
+
<em>changes the actual value in the stack to a string</em>.
+
(This change confuses <a href="#lua_next"><code>lua_next</code></a>
+
when <code>lua_tolstring</code> is applied to keys during a table traversal.)
+

+

+
<p>
+
<code>lua_tolstring</code> returns a pointer
+
to a string inside the Lua state.
+
This string always has a zero ('<code>\0</code>')
+
after its last character (as in&nbsp;C),
+
but can contain other zeros in its body.
+

+

+
<p>
+
Because Lua has garbage collection,
+
there is no guarantee that the pointer returned by <code>lua_tolstring</code>
+
will be valid after the corresponding Lua value is removed from the stack.
+

+

+

+

+

+
<hr><h3><a name="lua_tonumber"><code>lua_tonumber</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_Number lua_tonumber (lua_State *L, int index);</pre>
+

+
<p>
+
Equivalent to <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> with <code>isnum</code> equal to <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_tonumberx"><code>lua_tonumberx</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);</pre>
+

+
<p>
+
Converts the Lua value at the given index
+
to the C&nbsp;type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>).
+
The Lua value must be a number or a string convertible to a number
+
(see <a href="#3.4.3">&sect;3.4.3</a>);
+
otherwise, <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> returns&nbsp;0.
+

+

+
<p>
+
If <code>isnum</code> is not <code>NULL</code>,
+
its referent is assigned a boolean value that
+
indicates whether the operation succeeded.
+

+

+

+

+

+
<hr><h3><a name="lua_topointer"><code>lua_topointer</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>const void *lua_topointer (lua_State *L, int index);</pre>
+

+
<p>
+
Converts the value at the given index to a generic
+
C&nbsp;pointer (<code>void*</code>).
+
The value can be a userdata, a table, a thread, or a function;
+
otherwise, <code>lua_topointer</code> returns <code>NULL</code>.
+
Different objects will give different pointers.
+
There is no way to convert the pointer back to its original value.
+

+

+
<p>
+
Typically this function is used only for hashing and debug information.
+

+

+

+

+

+
<hr><h3><a name="lua_tostring"><code>lua_tostring</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>m</em>]</span>
+
<pre>const char *lua_tostring (lua_State *L, int index);</pre>
+

+
<p>
+
Equivalent to <a href="#lua_tolstring"><code>lua_tolstring</code></a> with <code>len</code> equal to <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_tothread"><code>lua_tothread</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_State *lua_tothread (lua_State *L, int index);</pre>
+

+
<p>
+
Converts the value at the given index to a Lua thread
+
(represented as <code>lua_State*</code>).
+
This value must be a thread;
+
otherwise, the function returns <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_touserdata"><code>lua_touserdata</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void *lua_touserdata (lua_State *L, int index);</pre>
+

+
<p>
+
If the value at the given index is a full userdata,
+
returns its block address.
+
If the value is a light userdata,
+
returns its pointer.
+
Otherwise, returns <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_type"><code>lua_type</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_type (lua_State *L, int index);</pre>
+

+
<p>
+
Returns the type of the value in the given valid index,
+
or <code>LUA_TNONE</code> for a non-valid (but acceptable) index.
+
The types returned by <a href="#lua_type"><code>lua_type</code></a> are coded by the following constants
+
defined in <code>lua.h</code>:
+
<a name="pdf-LUA_TNIL"><code>LUA_TNIL</code></a> (0),
+
<a name="pdf-LUA_TNUMBER"><code>LUA_TNUMBER</code></a>,
+
<a name="pdf-LUA_TBOOLEAN"><code>LUA_TBOOLEAN</code></a>,
+
<a name="pdf-LUA_TSTRING"><code>LUA_TSTRING</code></a>,
+
<a name="pdf-LUA_TTABLE"><code>LUA_TTABLE</code></a>,
+
<a name="pdf-LUA_TFUNCTION"><code>LUA_TFUNCTION</code></a>,
+
<a name="pdf-LUA_TUSERDATA"><code>LUA_TUSERDATA</code></a>,
+
<a name="pdf-LUA_TTHREAD"><code>LUA_TTHREAD</code></a>,
+
and
+
<a name="pdf-LUA_TLIGHTUSERDATA"><code>LUA_TLIGHTUSERDATA</code></a>.
+

+

+

+

+

+
<hr><h3><a name="lua_typename"><code>lua_typename</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>const char *lua_typename (lua_State *L, int tp);</pre>
+

+
<p>
+
Returns the name of the type encoded by the value <code>tp</code>,
+
which must be one the values returned by <a href="#lua_type"><code>lua_type</code></a>.
+

+

+

+

+

+
<hr><h3><a name="lua_Unsigned"><code>lua_Unsigned</code></a></h3>
+
<pre>typedef ... lua_Unsigned;</pre>
+

+
<p>
+
The unsigned version of <a href="#lua_Integer"><code>lua_Integer</code></a>.
+

+

+

+

+

+
<hr><h3><a name="lua_upvalueindex"><code>lua_upvalueindex</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_upvalueindex (int i);</pre>
+

+
<p>
+
Returns the pseudo-index that represents the <code>i</code>-th upvalue of
+
the running function (see <a href="#4.4">&sect;4.4</a>).
+

+

+

+

+

+
<hr><h3><a name="lua_version"><code>lua_version</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>const lua_Number *lua_version (lua_State *L);</pre>
+

+
<p>
+
Returns the address of the version number
+
(a C static variable)
+
stored in the Lua core.
+
When called with a valid <a href="#lua_State"><code>lua_State</code></a>,
+
returns the address of the version used to create that state.
+
When called with <code>NULL</code>,
+
returns the address of the version running the call.
+

+

+

+

+

+
<hr><h3><a name="lua_Writer"><code>lua_Writer</code></a></h3>
+
<pre>typedef int (*lua_Writer) (lua_State *L,
+
                           const void* p,
+
                           size_t sz,
+
                           void* ud);</pre>
+

+
<p>
+
The type of the writer function used by <a href="#lua_dump"><code>lua_dump</code></a>.
+
Every time it produces another piece of chunk,
+
<a href="#lua_dump"><code>lua_dump</code></a> calls the writer,
+
passing along the buffer to be written (<code>p</code>),
+
its size (<code>sz</code>),
+
and the <code>data</code> parameter supplied to <a href="#lua_dump"><code>lua_dump</code></a>.
+

+

+
<p>
+
The writer returns an error code:
+
0&nbsp;means no errors;
+
any other value means an error and stops <a href="#lua_dump"><code>lua_dump</code></a> from
+
calling the writer again.
+

+

+

+

+

+
<hr><h3><a name="lua_xmove"><code>lua_xmove</code></a></h3><p>
+
<span class="apii">[-?, +?, &ndash;]</span>
+
<pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre>
+

+
<p>
+
Exchange values between different threads of the same state.
+

+

+
<p>
+
This function pops <code>n</code> values from the stack <code>from</code>,
+
and pushes them onto the stack <code>to</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_yield"><code>lua_yield</code></a></h3><p>
+
<span class="apii">[-?, +?, <em>e</em>]</span>
+
<pre>int lua_yield (lua_State *L, int nresults);</pre>
+

+
<p>
+
This function is equivalent to <a href="#lua_yieldk"><code>lua_yieldk</code></a>,
+
but it has no continuation (see <a href="#4.7">&sect;4.7</a>).
+
Therefore, when the thread resumes,
+
it continues the function that called
+
the function calling <code>lua_yield</code>.
+

+

+

+

+

+
<hr><h3><a name="lua_yieldk"><code>lua_yieldk</code></a></h3><p>
+
<span class="apii">[-?, +?, <em>e</em>]</span>
+
<pre>int lua_yieldk (lua_State *L,
+
                int nresults,
+
                lua_KContext ctx,
+
                lua_KFunction k);</pre>
+

+
<p>
+
Yields a coroutine (thread).
+

+

+
<p>
+
When a C&nbsp;function calls <a href="#lua_yieldk"><code>lua_yieldk</code></a>,
+
the running coroutine suspends its execution,
+
and the call to <a href="#lua_resume"><code>lua_resume</code></a> that started this coroutine returns.
+
The parameter <code>nresults</code> is the number of values from the stack
+
that will be passed as results to <a href="#lua_resume"><code>lua_resume</code></a>.
+

+

+
<p>
+
When the coroutine is resumed again,
+
Lua calls the given continuation function <code>k</code> to continue
+
the execution of the C&nbsp;function that yielded (see <a href="#4.7">&sect;4.7</a>).
+
This continuation function receives the same stack
+
from the previous function,
+
with the <code>n</code> results removed and
+
replaced by the arguments passed to <a href="#lua_resume"><code>lua_resume</code></a>.
+
Moreover,
+
the continuation function receives the value <code>ctx</code>
+
that was passed to <a href="#lua_yieldk"><code>lua_yieldk</code></a>.
+

+

+
<p>
+
Usually, this function does not return;
+
when the coroutine eventually resumes,
+
it continues executing the continuation function.
+
However, there is one special case,
+
which is when this function is called
+
from inside a line or a count hook (see <a href="#4.9">&sect;4.9</a>).
+
In that case, <code>lua_yieldk</code> should be called with no continuation
+
(probably in the form of <a href="#lua_yield"><code>lua_yield</code></a>) and no results,
+
and the hook should return immediately after the call.
+
Lua will yield and,
+
when the coroutine resumes again,
+
it will continue the normal execution
+
of the (Lua) function that triggered the hook.
+

+

+
<p>
+
This function can raise an error if it is called from a thread
+
with a pending C call with no continuation function,
+
or it is called from a thread that is not running inside a resume
+
(e.g., the main thread).
+

+

+

+

+

+

+

+
<h2>4.9 &ndash; <a name="4.9">The Debug Interface</a></h2>
+

+
<p>
+
Lua has no built-in debugging facilities.
+
Instead, it offers a special interface
+
by means of functions and <em>hooks</em>.
+
This interface allows the construction of different
+
kinds of debuggers, profilers, and other tools
+
that need "inside information" from the interpreter.
+

+

+

+
<hr><h3><a name="lua_Debug"><code>lua_Debug</code></a></h3>
+
<pre>typedef struct lua_Debug {
+
  int event;
+
  const char *name;           /* (n) */
+
  const char *namewhat;       /* (n) */
+
  const char *what;           /* (S) */
+
  const char *source;         /* (S) */
+
  int currentline;            /* (l) */
+
  int linedefined;            /* (S) */
+
  int lastlinedefined;        /* (S) */
+
  unsigned char nups;         /* (u) number of upvalues */
+
  unsigned char nparams;      /* (u) number of parameters */
+
  char isvararg;              /* (u) */
+
  char istailcall;            /* (t) */
+
  char short_src[LUA_IDSIZE]; /* (S) */
+
  /* private part */
+
  <em>other fields</em>
+
} lua_Debug;</pre>
+

+
<p>
+
A structure used to carry different pieces of
+
information about a function or an activation record.
+
<a href="#lua_getstack"><code>lua_getstack</code></a> fills only the private part
+
of this structure, for later use.
+
To fill the other fields of <a href="#lua_Debug"><code>lua_Debug</code></a> with useful information,
+
call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
+

+

+
<p>
+
The fields of <a href="#lua_Debug"><code>lua_Debug</code></a> have the following meaning:
+

+
<ul>
+

+
<li><b><code>source</code>: </b>
+
the name of the chunk that created the function.
+
If <code>source</code> starts with a '<code>@</code>',
+
it means that the function was defined in a file where
+
the file name follows the '<code>@</code>'.
+
If <code>source</code> starts with a '<code>=</code>',
+
the remainder of its contents describe the source in a user-dependent manner.
+
Otherwise,
+
the function was defined in a string where
+
<code>source</code> is that string.
+
</li>
+

+
<li><b><code>short_src</code>: </b>
+
a "printable" version of <code>source</code>, to be used in error messages.
+
</li>
+

+
<li><b><code>linedefined</code>: </b>
+
the line number where the definition of the function starts.
+
</li>
+

+
<li><b><code>lastlinedefined</code>: </b>
+
the line number where the definition of the function ends.
+
</li>
+

+
<li><b><code>what</code>: </b>
+
the string <code>"Lua"</code> if the function is a Lua function,
+
<code>"C"</code> if it is a C&nbsp;function,
+
<code>"main"</code> if it is the main part of a chunk.
+
</li>
+

+
<li><b><code>currentline</code>: </b>
+
the current line where the given function is executing.
+
When no line information is available,
+
<code>currentline</code> is set to -1.
+
</li>
+

+
<li><b><code>name</code>: </b>
+
a reasonable name for the given function.
+
Because functions in Lua are first-class values,
+
they do not have a fixed name:
+
some functions can be the value of multiple global variables,
+
while others can be stored only in a table field.
+
The <code>lua_getinfo</code> function checks how the function was
+
called to find a suitable name.
+
If it cannot find a name,
+
then <code>name</code> is set to <code>NULL</code>.
+
</li>
+

+
<li><b><code>namewhat</code>: </b>
+
explains the <code>name</code> field.
+
The value of <code>namewhat</code> can be
+
<code>"global"</code>, <code>"local"</code>, <code>"method"</code>,
+
<code>"field"</code>, <code>"upvalue"</code>, or <code>""</code> (the empty string),
+
according to how the function was called.
+
(Lua uses the empty string when no other option seems to apply.)
+
</li>
+

+
<li><b><code>istailcall</code>: </b>
+
true if this function invocation was called by a tail call.
+
In this case, the caller of this level is not in the stack.
+
</li>
+

+
<li><b><code>nups</code>: </b>
+
the number of upvalues of the function.
+
</li>
+

+
<li><b><code>nparams</code>: </b>
+
the number of fixed parameters of the function
+
(always 0&nbsp;for C&nbsp;functions).
+
</li>
+

+
<li><b><code>isvararg</code>: </b>
+
true if the function is a vararg function
+
(always true for C&nbsp;functions).
+
</li>
+

+
</ul>
+

+

+

+

+
<hr><h3><a name="lua_gethook"><code>lua_gethook</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_Hook lua_gethook (lua_State *L);</pre>
+

+
<p>
+
Returns the current hook function.
+

+

+

+

+

+
<hr><h3><a name="lua_gethookcount"><code>lua_gethookcount</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_gethookcount (lua_State *L);</pre>
+

+
<p>
+
Returns the current hook count.
+

+

+

+

+

+
<hr><h3><a name="lua_gethookmask"><code>lua_gethookmask</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_gethookmask (lua_State *L);</pre>
+

+
<p>
+
Returns the current hook mask.
+

+

+

+

+

+
<hr><h3><a name="lua_getinfo"><code>lua_getinfo</code></a></h3><p>
+
<span class="apii">[-(0|1), +(0|1|2), <em>e</em>]</span>
+
<pre>int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);</pre>
+

+
<p>
+
Gets information about a specific function or function invocation.
+

+

+
<p>
+
To get information about a function invocation,
+
the parameter <code>ar</code> must be a valid activation record that was
+
filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or
+
given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>).
+

+

+
<p>
+
To get information about a function, you push it onto the stack
+
and start the <code>what</code> string with the character '<code>&gt;</code>'.
+
(In that case,
+
<code>lua_getinfo</code> pops the function from the top of the stack.)
+
For instance, to know in which line a function <code>f</code> was defined,
+
you can write the following code:
+

+
<pre>
+
     lua_Debug ar;
+
     lua_getglobal(L, "f");  /* get global 'f' */
+
     lua_getinfo(L, "&gt;S", &amp;ar);
+
     printf("%d\n", ar.linedefined);
+
</pre>
+

+
<p>
+
Each character in the string <code>what</code>
+
selects some fields of the structure <code>ar</code> to be filled or
+
a value to be pushed on the stack:
+

+
<ul>
+

+
<li><b>'<code>n</code>': </b> fills in the field <code>name</code> and <code>namewhat</code>;
+
</li>
+

+
<li><b>'<code>S</code>': </b>
+
fills in the fields <code>source</code>, <code>short_src</code>,
+
<code>linedefined</code>, <code>lastlinedefined</code>, and <code>what</code>;
+
</li>
+

+
<li><b>'<code>l</code>': </b> fills in the field <code>currentline</code>;
+
</li>
+

+
<li><b>'<code>t</code>': </b> fills in the field <code>istailcall</code>;
+
</li>
+

+
<li><b>'<code>u</code>': </b> fills in the fields
+
<code>nups</code>, <code>nparams</code>, and <code>isvararg</code>;
+
</li>
+

+
<li><b>'<code>f</code>': </b>
+
pushes onto the stack the function that is
+
running at the given level;
+
</li>
+

+
<li><b>'<code>L</code>': </b>
+
pushes onto the stack a table whose indices are the
+
numbers of the lines that are valid on the function.
+
(A <em>valid line</em> is a line with some associated code,
+
that is, a line where you can put a break point.
+
Non-valid lines include empty lines and comments.)
+

+

+
<p>
+
If this option is given together with option '<code>f</code>',
+
its table is pushed after the function.
+
</li>
+

+
</ul>
+

+
<p>
+
This function returns 0 on error
+
(for instance, an invalid option in <code>what</code>).
+

+

+

+

+

+
<hr><h3><a name="lua_getlocal"><code>lua_getlocal</code></a></h3><p>
+
<span class="apii">[-0, +(0|1), &ndash;]</span>
+
<pre>const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);</pre>
+

+
<p>
+
Gets information about a local variable of
+
a given activation record or a given function.
+

+

+
<p>
+
In the first case,
+
the parameter <code>ar</code> must be a valid activation record that was
+
filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or
+
given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>).
+
The index <code>n</code> selects which local variable to inspect;
+
see <a href="#pdf-debug.getlocal"><code>debug.getlocal</code></a> for details about variable indices
+
and names.
+

+

+
<p>
+
<a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack
+
and returns its name.
+

+

+
<p>
+
In the second case, <code>ar</code> must be <code>NULL</code> and the function
+
to be inspected must be at the top of the stack.
+
In this case, only parameters of Lua functions are visible
+
(as there is no information about what variables are active)
+
and no values are pushed onto the stack.
+

+

+
<p>
+
Returns <code>NULL</code> (and pushes nothing)
+
when the index is greater than
+
the number of active local variables.
+

+

+

+

+

+
<hr><h3><a name="lua_getstack"><code>lua_getstack</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>int lua_getstack (lua_State *L, int level, lua_Debug *ar);</pre>
+

+
<p>
+
Gets information about the interpreter runtime stack.
+

+

+
<p>
+
This function fills parts of a <a href="#lua_Debug"><code>lua_Debug</code></a> structure with
+
an identification of the <em>activation record</em>
+
of the function executing at a given level.
+
Level&nbsp;0 is the current running function,
+
whereas level <em>n+1</em> is the function that has called level <em>n</em>
+
(except for tail calls, which do not count on the stack).
+
When there are no errors, <a href="#lua_getstack"><code>lua_getstack</code></a> returns 1;
+
when called with a level greater than the stack depth,
+
it returns 0.
+

+

+

+

+

+
<hr><h3><a name="lua_getupvalue"><code>lua_getupvalue</code></a></h3><p>
+
<span class="apii">[-0, +(0|1), &ndash;]</span>
+
<pre>const char *lua_getupvalue (lua_State *L, int funcindex, int n);</pre>
+

+
<p>
+
Gets information about the <code>n</code>-th upvalue
+
of the closure at index <code>funcindex</code>.
+
It pushes the upvalue's value onto the stack
+
and returns its name.
+
Returns <code>NULL</code> (and pushes nothing)
+
when the index <code>n</code> is greater than the number of upvalues.
+

+

+
<p>
+
For C&nbsp;functions, this function uses the empty string <code>""</code>
+
as a name for all upvalues.
+
(For Lua functions,
+
upvalues are the external local variables that the function uses,
+
and that are consequently included in its closure.)
+

+

+
<p>
+
Upvalues have no particular order,
+
as they are active through the whole function.
+
They are numbered in an arbitrary order.
+

+

+

+

+

+
<hr><h3><a name="lua_Hook"><code>lua_Hook</code></a></h3>
+
<pre>typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);</pre>
+

+
<p>
+
Type for debugging hook functions.
+

+

+
<p>
+
Whenever a hook is called, its <code>ar</code> argument has its field
+
<code>event</code> set to the specific event that triggered the hook.
+
Lua identifies these events with the following constants:
+
<a name="pdf-LUA_HOOKCALL"><code>LUA_HOOKCALL</code></a>, <a name="pdf-LUA_HOOKRET"><code>LUA_HOOKRET</code></a>,
+
<a name="pdf-LUA_HOOKTAILCALL"><code>LUA_HOOKTAILCALL</code></a>, <a name="pdf-LUA_HOOKLINE"><code>LUA_HOOKLINE</code></a>,
+
and <a name="pdf-LUA_HOOKCOUNT"><code>LUA_HOOKCOUNT</code></a>.
+
Moreover, for line events, the field <code>currentline</code> is also set.
+
To get the value of any other field in <code>ar</code>,
+
the hook must call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
+

+

+
<p>
+
For call events, <code>event</code> can be <code>LUA_HOOKCALL</code>,
+
the normal value, or <code>LUA_HOOKTAILCALL</code>, for a tail call;
+
in this case, there will be no corresponding return event.
+

+

+
<p>
+
While Lua is running a hook, it disables other calls to hooks.
+
Therefore, if a hook calls back Lua to execute a function or a chunk,
+
this execution occurs without any calls to hooks.
+

+

+
<p>
+
Hook functions cannot have continuations,
+
that is, they cannot call <a href="#lua_yieldk"><code>lua_yieldk</code></a>,
+
<a href="#lua_pcallk"><code>lua_pcallk</code></a>, or <a href="#lua_callk"><code>lua_callk</code></a> with a non-null <code>k</code>.
+

+

+
<p>
+
Hook functions can yield under the following conditions:
+
Only count and line events can yield;
+
to yield, a hook function must finish its execution
+
calling <a href="#lua_yield"><code>lua_yield</code></a> with <code>nresults</code> equal to zero
+
(that is, with no values).
+

+

+

+

+

+
<hr><h3><a name="lua_sethook"><code>lua_sethook</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void lua_sethook (lua_State *L, lua_Hook f, int mask, int count);</pre>
+

+
<p>
+
Sets the debugging hook function.
+

+

+
<p>
+
Argument <code>f</code> is the hook function.
+
<code>mask</code> specifies on which events the hook will be called:
+
it is formed by a bitwise OR of the constants
+
<a name="pdf-LUA_MASKCALL"><code>LUA_MASKCALL</code></a>,
+
<a name="pdf-LUA_MASKRET"><code>LUA_MASKRET</code></a>,
+
<a name="pdf-LUA_MASKLINE"><code>LUA_MASKLINE</code></a>,
+
and <a name="pdf-LUA_MASKCOUNT"><code>LUA_MASKCOUNT</code></a>.
+
The <code>count</code> argument is only meaningful when the mask
+
includes <code>LUA_MASKCOUNT</code>.
+
For each event, the hook is called as explained below:
+

+
<ul>
+

+
<li><b>The call hook: </b> is called when the interpreter calls a function.
+
The hook is called just after Lua enters the new function,
+
before the function gets its arguments.
+
</li>
+

+
<li><b>The return hook: </b> is called when the interpreter returns from a function.
+
The hook is called just before Lua leaves the function.
+
There is no standard way to access the values
+
to be returned by the function.
+
</li>
+

+
<li><b>The line hook: </b> is called when the interpreter is about to
+
start the execution of a new line of code,
+
or when it jumps back in the code (even to the same line).
+
(This event only happens while Lua is executing a Lua function.)
+
</li>
+

+
<li><b>The count hook: </b> is called after the interpreter executes every
+
<code>count</code> instructions.
+
(This event only happens while Lua is executing a Lua function.)
+
</li>
+

+
</ul>
+

+
<p>
+
A hook is disabled by setting <code>mask</code> to zero.
+

+

+

+

+

+
<hr><h3><a name="lua_setlocal"><code>lua_setlocal</code></a></h3><p>
+
<span class="apii">[-(0|1), +0, &ndash;]</span>
+
<pre>const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);</pre>
+

+
<p>
+
Sets the value of a local variable of a given activation record.
+
It assigns the value at the top of the stack
+
to the variable and returns its name.
+
It also pops the value from the stack.
+

+

+
<p>
+
Returns <code>NULL</code> (and pops nothing)
+
when the index is greater than
+
the number of active local variables.
+

+

+
<p>
+
Parameters <code>ar</code> and <code>n</code> are as in function <a href="#lua_getlocal"><code>lua_getlocal</code></a>.
+

+

+

+

+

+
<hr><h3><a name="lua_setupvalue"><code>lua_setupvalue</code></a></h3><p>
+
<span class="apii">[-(0|1), +0, &ndash;]</span>
+
<pre>const char *lua_setupvalue (lua_State *L, int funcindex, int n);</pre>
+

+
<p>
+
Sets the value of a closure's upvalue.
+
It assigns the value at the top of the stack
+
to the upvalue and returns its name.
+
It also pops the value from the stack.
+

+

+
<p>
+
Returns <code>NULL</code> (and pops nothing)
+
when the index <code>n</code> is greater than the number of upvalues.
+

+

+
<p>
+
Parameters <code>funcindex</code> and <code>n</code> are as in function <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>.
+

+

+

+

+

+
<hr><h3><a name="lua_upvalueid"><code>lua_upvalueid</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void *lua_upvalueid (lua_State *L, int funcindex, int n);</pre>
+

+
<p>
+
Returns a unique identifier for the upvalue numbered <code>n</code>
+
from the closure at index <code>funcindex</code>.
+

+

+
<p>
+
These unique identifiers allow a program to check whether different
+
closures share upvalues.
+
Lua closures that share an upvalue
+
(that is, that access a same external local variable)
+
will return identical ids for those upvalue indices.
+

+

+
<p>
+
Parameters <code>funcindex</code> and <code>n</code> are as in function <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>,
+
but <code>n</code> cannot be greater than the number of upvalues.
+

+

+

+

+

+
<hr><h3><a name="lua_upvaluejoin"><code>lua_upvaluejoin</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
+
                                    int funcindex2, int n2);</pre>
+

+
<p>
+
Make the <code>n1</code>-th upvalue of the Lua closure at index <code>funcindex1</code>
+
refer to the <code>n2</code>-th upvalue of the Lua closure at index <code>funcindex2</code>.
+

+

+

+

+

+

+

+
<h1>5 &ndash; <a name="5">The Auxiliary Library</a></h1>
+

+
<p>
+

+
The <em>auxiliary library</em> provides several convenient functions
+
to interface C with Lua.
+
While the basic API provides the primitive functions for all
+
interactions between C and Lua,
+
the auxiliary library provides higher-level functions for some
+
common tasks.
+

+

+
<p>
+
All functions and types from the auxiliary library
+
are defined in header file <code>lauxlib.h</code> and
+
have a prefix <code>luaL_</code>.
+

+

+
<p>
+
All functions in the auxiliary library are built on
+
top of the basic API,
+
and so they provide nothing that cannot be done with that API.
+
Nevertheless, the use of the auxiliary library ensures
+
more consistency to your code.
+

+

+
<p>
+
Several functions in the auxiliary library use internally some
+
extra stack slots.
+
When a function in the auxiliary library uses less than five slots,
+
it does not check the stack size;
+
it simply assumes that there are enough slots.
+

+

+
<p>
+
Several functions in the auxiliary library are used to
+
check C&nbsp;function arguments.
+
Because the error message is formatted for arguments
+
(e.g., "<code>bad argument #1</code>"),
+
you should not use these functions for other stack values.
+

+

+
<p>
+
Functions called <code>luaL_check*</code>
+
always raise an error if the check is not satisfied.
+

+

+

+
<h2>5.1 &ndash; <a name="5.1">Functions and Types</a></h2>
+

+
<p>
+
Here we list all functions and types from the auxiliary library
+
in alphabetical order.
+

+

+

+
<hr><h3><a name="luaL_addchar"><code>luaL_addchar</code></a></h3><p>
+
<span class="apii">[-?, +?, <em>m</em>]</span>
+
<pre>void luaL_addchar (luaL_Buffer *B, char c);</pre>
+

+
<p>
+
Adds the byte <code>c</code> to the buffer <code>B</code>
+
(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+

+

+

+

+

+
<hr><h3><a name="luaL_addlstring"><code>luaL_addlstring</code></a></h3><p>
+
<span class="apii">[-?, +?, <em>m</em>]</span>
+
<pre>void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);</pre>
+

+
<p>
+
Adds the string pointed to by <code>s</code> with length <code>l</code> to
+
the buffer <code>B</code>
+
(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+
The string can contain embedded zeros.
+

+

+

+

+

+
<hr><h3><a name="luaL_addsize"><code>luaL_addsize</code></a></h3><p>
+
<span class="apii">[-?, +?, &ndash;]</span>
+
<pre>void luaL_addsize (luaL_Buffer *B, size_t n);</pre>
+

+
<p>
+
Adds to the buffer <code>B</code> (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>)
+
a string of length <code>n</code> previously copied to the
+
buffer area (see <a href="#luaL_prepbuffer"><code>luaL_prepbuffer</code></a>).
+

+

+

+

+

+
<hr><h3><a name="luaL_addstring"><code>luaL_addstring</code></a></h3><p>
+
<span class="apii">[-?, +?, <em>m</em>]</span>
+
<pre>void luaL_addstring (luaL_Buffer *B, const char *s);</pre>
+

+
<p>
+
Adds the zero-terminated string pointed to by <code>s</code>
+
to the buffer <code>B</code>
+
(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+

+

+

+

+

+
<hr><h3><a name="luaL_addvalue"><code>luaL_addvalue</code></a></h3><p>
+
<span class="apii">[-1, +?, <em>m</em>]</span>
+
<pre>void luaL_addvalue (luaL_Buffer *B);</pre>
+

+
<p>
+
Adds the value at the top of the stack
+
to the buffer <code>B</code>
+
(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+
Pops the value.
+

+

+
<p>
+
This is the only function on string buffers that can (and must)
+
be called with an extra element on the stack,
+
which is the value to be added to the buffer.
+

+

+

+

+

+
<hr><h3><a name="luaL_argcheck"><code>luaL_argcheck</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>void luaL_argcheck (lua_State *L,
+
                    int cond,
+
                    int arg,
+
                    const char *extramsg);</pre>
+

+
<p>
+
Checks whether <code>cond</code> is true.
+
If it is not, raises an error with a standard message (see <a href="#luaL_argerror"><code>luaL_argerror</code></a>).
+

+

+

+

+

+
<hr><h3><a name="luaL_argerror"><code>luaL_argerror</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>int luaL_argerror (lua_State *L, int arg, const char *extramsg);</pre>
+

+
<p>
+
Raises an error reporting a problem with argument <code>arg</code>
+
of the C&nbsp;function that called it,
+
using a standard message
+
that includes <code>extramsg</code> as a comment:
+

+
<pre>
+
     bad argument #<em>arg</em> to '<em>funcname</em>' (<em>extramsg</em>)
+
</pre><p>
+
This function never returns.
+

+

+

+

+

+
<hr><h3><a name="luaL_Buffer"><code>luaL_Buffer</code></a></h3>
+
<pre>typedef struct luaL_Buffer luaL_Buffer;</pre>
+

+
<p>
+
Type for a <em>string buffer</em>.
+

+

+
<p>
+
A string buffer allows C&nbsp;code to build Lua strings piecemeal.
+
Its pattern of use is as follows:
+

+
<ul>
+

+
<li>First declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
+

+
<li>Then initialize it with a call <code>luaL_buffinit(L, &amp;b)</code>.</li>
+

+
<li>
+
Then add string pieces to the buffer calling any of
+
the <code>luaL_add*</code> functions.
+
</li>
+

+
<li>
+
Finish by calling <code>luaL_pushresult(&amp;b)</code>.
+
This call leaves the final string on the top of the stack.
+
</li>
+

+
</ul>
+

+
<p>
+
If you know beforehand the total size of the resulting string,
+
you can use the buffer like this:
+

+
<ul>
+

+
<li>First declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
+

+
<li>Then initialize it and preallocate a space of
+
size <code>sz</code> with a call <code>luaL_buffinitsize(L, &amp;b, sz)</code>.</li>
+

+
<li>Then copy the string into that space.</li>
+

+
<li>
+
Finish by calling <code>luaL_pushresultsize(&amp;b, sz)</code>,
+
where <code>sz</code> is the total size of the resulting string
+
copied into that space.
+
</li>
+

+
</ul>
+

+
<p>
+
During its normal operation,
+
a string buffer uses a variable number of stack slots.
+
So, while using a buffer, you cannot assume that you know where
+
the top of the stack is.
+
You can use the stack between successive calls to buffer operations
+
as long as that use is balanced;
+
that is,
+
when you call a buffer operation,
+
the stack is at the same level
+
it was immediately after the previous buffer operation.
+
(The only exception to this rule is <a href="#luaL_addvalue"><code>luaL_addvalue</code></a>.)
+
After calling <a href="#luaL_pushresult"><code>luaL_pushresult</code></a> the stack is back to its
+
level when the buffer was initialized,
+
plus the final string on its top.
+

+

+

+

+

+
<hr><h3><a name="luaL_buffinit"><code>luaL_buffinit</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void luaL_buffinit (lua_State *L, luaL_Buffer *B);</pre>
+

+
<p>
+
Initializes a buffer <code>B</code>.
+
This function does not allocate any space;
+
the buffer must be declared as a variable
+
(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+

+

+

+

+

+
<hr><h3><a name="luaL_buffinitsize"><code>luaL_buffinitsize</code></a></h3><p>
+
<span class="apii">[-?, +?, <em>m</em>]</span>
+
<pre>char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz);</pre>
+

+
<p>
+
Equivalent to the sequence
+
<a href="#luaL_buffinit"><code>luaL_buffinit</code></a>, <a href="#luaL_prepbuffsize"><code>luaL_prepbuffsize</code></a>.
+

+

+

+

+

+
<hr><h3><a name="luaL_callmeta"><code>luaL_callmeta</code></a></h3><p>
+
<span class="apii">[-0, +(0|1), <em>e</em>]</span>
+
<pre>int luaL_callmeta (lua_State *L, int obj, const char *e);</pre>
+

+
<p>
+
Calls a metamethod.
+

+

+
<p>
+
If the object at index <code>obj</code> has a metatable and this
+
metatable has a field <code>e</code>,
+
this function calls this field passing the object as its only argument.
+
In this case this function returns true and pushes onto the
+
stack the value returned by the call.
+
If there is no metatable or no metamethod,
+
this function returns false (without pushing any value on the stack).
+

+

+

+

+

+
<hr><h3><a name="luaL_checkany"><code>luaL_checkany</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>void luaL_checkany (lua_State *L, int arg);</pre>
+

+
<p>
+
Checks whether the function has an argument
+
of any type (including <b>nil</b>) at position <code>arg</code>.
+

+

+

+

+

+
<hr><h3><a name="luaL_checkinteger"><code>luaL_checkinteger</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>lua_Integer luaL_checkinteger (lua_State *L, int arg);</pre>
+

+
<p>
+
Checks whether the function argument <code>arg</code> is an integer
+
(or can be converted to an integer)
+
and returns this integer cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>.
+

+

+

+

+

+
<hr><h3><a name="luaL_checklstring"><code>luaL_checklstring</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>const char *luaL_checklstring (lua_State *L, int arg, size_t *l);</pre>
+

+
<p>
+
Checks whether the function argument <code>arg</code> is a string
+
and returns this string;
+
if <code>l</code> is not <code>NULL</code> fills <code>*l</code>
+
with the string's length.
+

+

+
<p>
+
This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
+
so all conversions and caveats of that function apply here.
+

+

+

+

+

+
<hr><h3><a name="luaL_checknumber"><code>luaL_checknumber</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>lua_Number luaL_checknumber (lua_State *L, int arg);</pre>
+

+
<p>
+
Checks whether the function argument <code>arg</code> is a number
+
and returns this number.
+

+

+

+

+

+
<hr><h3><a name="luaL_checkoption"><code>luaL_checkoption</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>int luaL_checkoption (lua_State *L,
+
                      int arg,
+
                      const char *def,
+
                      const char *const lst[]);</pre>
+

+
<p>
+
Checks whether the function argument <code>arg</code> is a string and
+
searches for this string in the array <code>lst</code>
+
(which must be NULL-terminated).
+
Returns the index in the array where the string was found.
+
Raises an error if the argument is not a string or
+
if the string cannot be found.
+

+

+
<p>
+
If <code>def</code> is not <code>NULL</code>,
+
the function uses <code>def</code> as a default value when
+
there is no argument <code>arg</code> or when this argument is <b>nil</b>.
+

+

+
<p>
+
This is a useful function for mapping strings to C&nbsp;enums.
+
(The usual convention in Lua libraries is
+
to use strings instead of numbers to select options.)
+

+

+

+

+

+
<hr><h3><a name="luaL_checkstack"><code>luaL_checkstack</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>void luaL_checkstack (lua_State *L, int sz, const char *msg);</pre>
+

+
<p>
+
Grows the stack size to <code>top + sz</code> elements,
+
raising an error if the stack cannot grow to that size.
+
<code>msg</code> is an additional text to go into the error message
+
(or <code>NULL</code> for no additional text).
+

+

+

+

+

+
<hr><h3><a name="luaL_checkstring"><code>luaL_checkstring</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>const char *luaL_checkstring (lua_State *L, int arg);</pre>
+

+
<p>
+
Checks whether the function argument <code>arg</code> is a string
+
and returns this string.
+

+

+
<p>
+
This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
+
so all conversions and caveats of that function apply here.
+

+

+

+

+

+
<hr><h3><a name="luaL_checktype"><code>luaL_checktype</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>void luaL_checktype (lua_State *L, int arg, int t);</pre>
+

+
<p>
+
Checks whether the function argument <code>arg</code> has type <code>t</code>.
+
See <a href="#lua_type"><code>lua_type</code></a> for the encoding of types for <code>t</code>.
+

+

+

+

+

+
<hr><h3><a name="luaL_checkudata"><code>luaL_checkudata</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>void *luaL_checkudata (lua_State *L, int arg, const char *tname);</pre>
+

+
<p>
+
Checks whether the function argument <code>arg</code> is a userdata
+
of the type <code>tname</code> (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>) and
+
returns the userdata address (see <a href="#lua_touserdata"><code>lua_touserdata</code></a>).
+

+

+

+

+

+
<hr><h3><a name="luaL_checkversion"><code>luaL_checkversion</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>void luaL_checkversion (lua_State *L);</pre>
+

+
<p>
+
Checks whether the core running the call,
+
the core that created the Lua state,
+
and the code making the call are all using the same version of Lua.
+
Also checks whether the core running the call
+
and the core that created the Lua state
+
are using the same address space.
+

+

+

+

+

+
<hr><h3><a name="luaL_dofile"><code>luaL_dofile</code></a></h3><p>
+
<span class="apii">[-0, +?, <em>e</em>]</span>
+
<pre>int luaL_dofile (lua_State *L, const char *filename);</pre>
+

+
<p>
+
Loads and runs the given file.
+
It is defined as the following macro:
+

+
<pre>
+
     (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
</pre><p>
+
It returns false if there are no errors
+
or true in case of errors.
+

+

+

+

+

+
<hr><h3><a name="luaL_dostring"><code>luaL_dostring</code></a></h3><p>
+
<span class="apii">[-0, +?, &ndash;]</span>
+
<pre>int luaL_dostring (lua_State *L, const char *str);</pre>
+

+
<p>
+
Loads and runs the given string.
+
It is defined as the following macro:
+

+
<pre>
+
     (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
</pre><p>
+
It returns false if there are no errors
+
or true in case of errors.
+

+

+

+

+

+
<hr><h3><a name="luaL_error"><code>luaL_error</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>int luaL_error (lua_State *L, const char *fmt, ...);</pre>
+

+
<p>
+
Raises an error.
+
The error message format is given by <code>fmt</code>
+
plus any extra arguments,
+
following the same rules of <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>.
+
It also adds at the beginning of the message the file name and
+
the line number where the error occurred,
+
if this information is available.
+

+

+
<p>
+
This function never returns,
+
but it is an idiom to use it in C&nbsp;functions
+
as <code>return luaL_error(<em>args</em>)</code>.
+

+

+

+

+

+
<hr><h3><a name="luaL_execresult"><code>luaL_execresult</code></a></h3><p>
+
<span class="apii">[-0, +3, <em>m</em>]</span>
+
<pre>int luaL_execresult (lua_State *L, int stat);</pre>
+

+
<p>
+
This function produces the return values for
+
process-related functions in the standard library
+
(<a href="#pdf-os.execute"><code>os.execute</code></a> and <a href="#pdf-io.close"><code>io.close</code></a>).
+

+

+

+

+

+
<hr><h3><a name="luaL_fileresult"><code>luaL_fileresult</code></a></h3><p>
+
<span class="apii">[-0, +(1|3), <em>m</em>]</span>
+
<pre>int luaL_fileresult (lua_State *L, int stat, const char *fname);</pre>
+

+
<p>
+
This function produces the return values for
+
file-related functions in the standard library
+
(<a href="#pdf-io.open"><code>io.open</code></a>, <a href="#pdf-os.rename"><code>os.rename</code></a>, <a href="#pdf-file:seek"><code>file:seek</code></a>, etc.).
+

+

+

+

+

+
<hr><h3><a name="luaL_getmetafield"><code>luaL_getmetafield</code></a></h3><p>
+
<span class="apii">[-0, +(0|1), <em>m</em>]</span>
+
<pre>int luaL_getmetafield (lua_State *L, int obj, const char *e);</pre>
+

+
<p>
+
Pushes onto the stack the field <code>e</code> from the metatable
+
of the object at index <code>obj</code> and returns the type of the pushed value.
+
If the object does not have a metatable,
+
or if the metatable does not have this field,
+
pushes nothing and returns <code>LUA_TNIL</code>.
+

+

+

+

+

+
<hr><h3><a name="luaL_getmetatable"><code>luaL_getmetatable</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>int luaL_getmetatable (lua_State *L, const char *tname);</pre>
+

+
<p>
+
Pushes onto the stack the metatable associated with name <code>tname</code>
+
in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>)
+
(<b>nil</b> if there is no metatable associated with that name).
+
Returns the type of the pushed value.
+

+

+

+

+

+
<hr><h3><a name="luaL_getsubtable"><code>luaL_getsubtable</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>e</em>]</span>
+
<pre>int luaL_getsubtable (lua_State *L, int idx, const char *fname);</pre>
+

+
<p>
+
Ensures that the value <code>t[fname]</code>,
+
where <code>t</code> is the value at index <code>idx</code>,
+
is a table,
+
and pushes that table onto the stack.
+
Returns true if it finds a previous table there
+
and false if it creates a new table.
+

+

+

+

+

+
<hr><h3><a name="luaL_gsub"><code>luaL_gsub</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>const char *luaL_gsub (lua_State *L,
+
                       const char *s,
+
                       const char *p,
+
                       const char *r);</pre>
+

+
<p>
+
Creates a copy of string <code>s</code> by replacing
+
any occurrence of the string <code>p</code>
+
with the string <code>r</code>.
+
Pushes the resulting string on the stack and returns it.
+

+

+

+

+

+
<hr><h3><a name="luaL_len"><code>luaL_len</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>e</em>]</span>
+
<pre>lua_Integer luaL_len (lua_State *L, int index);</pre>
+

+
<p>
+
Returns the "length" of the value at the given index
+
as a number;
+
it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.7">&sect;3.4.7</a>).
+
Raises an error if the result of the operation is not an integer.
+
(This case only can happen through metamethods.)
+

+

+

+

+

+
<hr><h3><a name="luaL_loadbuffer"><code>luaL_loadbuffer</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>int luaL_loadbuffer (lua_State *L,
+
                     const char *buff,
+
                     size_t sz,
+
                     const char *name);</pre>
+

+
<p>
+
Equivalent to <a href="#luaL_loadbufferx"><code>luaL_loadbufferx</code></a> with <code>mode</code> equal to <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="luaL_loadbufferx"><code>luaL_loadbufferx</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>int luaL_loadbufferx (lua_State *L,
+
                      const char *buff,
+
                      size_t sz,
+
                      const char *name,
+
                      const char *mode);</pre>
+

+
<p>
+
Loads a buffer as a Lua chunk.
+
This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the
+
buffer pointed to by <code>buff</code> with size <code>sz</code>.
+

+

+
<p>
+
This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>.
+
<code>name</code> is the chunk name,
+
used for debug information and error messages.
+
The string <code>mode</code> works as in function <a href="#lua_load"><code>lua_load</code></a>.
+

+

+

+

+

+
<hr><h3><a name="luaL_loadfile"><code>luaL_loadfile</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>int luaL_loadfile (lua_State *L, const char *filename);</pre>
+

+
<p>
+
Equivalent to <a href="#luaL_loadfilex"><code>luaL_loadfilex</code></a> with <code>mode</code> equal to <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="luaL_loadfilex"><code>luaL_loadfilex</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>int luaL_loadfilex (lua_State *L, const char *filename,
+
                                            const char *mode);</pre>
+

+
<p>
+
Loads a file as a Lua chunk.
+
This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the file
+
named <code>filename</code>.
+
If <code>filename</code> is <code>NULL</code>,
+
then it loads from the standard input.
+
The first line in the file is ignored if it starts with a <code>#</code>.
+

+

+
<p>
+
The string <code>mode</code> works as in function <a href="#lua_load"><code>lua_load</code></a>.
+

+

+
<p>
+
This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>,
+
but it has an extra error code <a name="pdf-LUA_ERRFILE"><code>LUA_ERRFILE</code></a>
+
for file-related errors
+
(e.g., it cannot open or read the file).
+

+

+
<p>
+
As <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk;
+
it does not run it.
+

+

+

+

+

+
<hr><h3><a name="luaL_loadstring"><code>luaL_loadstring</code></a></h3><p>
+
<span class="apii">[-0, +1, &ndash;]</span>
+
<pre>int luaL_loadstring (lua_State *L, const char *s);</pre>
+

+
<p>
+
Loads a string as a Lua chunk.
+
This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in
+
the zero-terminated string <code>s</code>.
+

+

+
<p>
+
This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>.
+

+

+
<p>
+
Also as <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk;
+
it does not run it.
+

+

+

+

+

+
<hr><h3><a name="luaL_newlib"><code>luaL_newlib</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>void luaL_newlib (lua_State *L, const luaL_Reg l[]);</pre>
+

+
<p>
+
Creates a new table and registers there
+
the functions in list <code>l</code>.
+

+

+
<p>
+
It is implemented as the following macro:
+

+
<pre>
+
     (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
+
</pre><p>
+
The array <code>l</code> must be the actual array,
+
not a pointer to it.
+

+

+

+

+

+
<hr><h3><a name="luaL_newlibtable"><code>luaL_newlibtable</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);</pre>
+

+
<p>
+
Creates a new table with a size optimized
+
to store all entries in the array <code>l</code>
+
(but does not actually store them).
+
It is intended to be used in conjunction with <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a>
+
(see <a href="#luaL_newlib"><code>luaL_newlib</code></a>).
+

+

+
<p>
+
It is implemented as a macro.
+
The array <code>l</code> must be the actual array,
+
not a pointer to it.
+

+

+

+

+

+
<hr><h3><a name="luaL_newmetatable"><code>luaL_newmetatable</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>int luaL_newmetatable (lua_State *L, const char *tname);</pre>
+

+
<p>
+
If the registry already has the key <code>tname</code>,
+
returns 0.
+
Otherwise,
+
creates a new table to be used as a metatable for userdata,
+
adds to this new table the pair <code>__name = tname</code>,
+
adds to the registry the pair <code>[tname] = new table</code>,
+
and returns 1.
+
(The entry <code>__name</code> is used by some error-reporting functions.)
+

+

+
<p>
+
In both cases pushes onto the stack the final value associated
+
with <code>tname</code> in the registry.
+

+

+

+

+

+
<hr><h3><a name="luaL_newstate"><code>luaL_newstate</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>lua_State *luaL_newstate (void);</pre>
+

+
<p>
+
Creates a new Lua state.
+
It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with an
+
allocator based on the standard&nbsp;C <code>realloc</code> function
+
and then sets a panic function (see <a href="#4.6">&sect;4.6</a>) that prints
+
an error message to the standard error output in case of fatal
+
errors.
+

+

+
<p>
+
Returns the new state,
+
or <code>NULL</code> if there is a memory allocation error.
+

+

+

+

+

+
<hr><h3><a name="luaL_openlibs"><code>luaL_openlibs</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>e</em>]</span>
+
<pre>void luaL_openlibs (lua_State *L);</pre>
+

+
<p>
+
Opens all standard Lua libraries into the given state.
+

+

+

+

+

+
<hr><h3><a name="luaL_opt"><code>luaL_opt</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>e</em>]</span>
+
<pre>T luaL_opt (L, func, arg, dflt);</pre>
+

+
<p>
+
This macro is defined as follows:
+

+
<pre>
+
     (lua_isnoneornil(L,(arg)) ? (dflt) : func(L,(arg)))
+
</pre><p>
+
In words, if the argument <code>arg</code> is nil or absent,
+
the macro results in the default <code>dflt</code>.
+
Otherwise, it results in the result of calling <code>func</code>
+
with the state <code>L</code> and the argument index <code>arg</code> as
+
arguments.
+
Note that it evaluates the expression <code>dflt</code> only if needed.
+

+

+

+

+

+
<hr><h3><a name="luaL_optinteger"><code>luaL_optinteger</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>lua_Integer luaL_optinteger (lua_State *L,
+
                             int arg,
+
                             lua_Integer d);</pre>
+

+
<p>
+
If the function argument <code>arg</code> is an integer
+
(or convertible to an integer),
+
returns this integer.
+
If this argument is absent or is <b>nil</b>,
+
returns <code>d</code>.
+
Otherwise, raises an error.
+

+

+

+

+

+
<hr><h3><a name="luaL_optlstring"><code>luaL_optlstring</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>const char *luaL_optlstring (lua_State *L,
+
                             int arg,
+
                             const char *d,
+
                             size_t *l);</pre>
+

+
<p>
+
If the function argument <code>arg</code> is a string,
+
returns this string.
+
If this argument is absent or is <b>nil</b>,
+
returns <code>d</code>.
+
Otherwise, raises an error.
+

+

+
<p>
+
If <code>l</code> is not <code>NULL</code>,
+
fills the position <code>*l</code> with the result's length.
+
If the result is <code>NULL</code>
+
(only possible when returning <code>d</code> and <code>d == NULL</code>),
+
its length is considered zero.
+

+

+
<p>
+
This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
+
so all conversions and caveats of that function apply here.
+

+

+

+

+

+
<hr><h3><a name="luaL_optnumber"><code>luaL_optnumber</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number d);</pre>
+

+
<p>
+
If the function argument <code>arg</code> is a number,
+
returns this number.
+
If this argument is absent or is <b>nil</b>,
+
returns <code>d</code>.
+
Otherwise, raises an error.
+

+

+

+

+

+
<hr><h3><a name="luaL_optstring"><code>luaL_optstring</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>v</em>]</span>
+
<pre>const char *luaL_optstring (lua_State *L,
+
                            int arg,
+
                            const char *d);</pre>
+

+
<p>
+
If the function argument <code>arg</code> is a string,
+
returns this string.
+
If this argument is absent or is <b>nil</b>,
+
returns <code>d</code>.
+
Otherwise, raises an error.
+

+

+

+

+

+
<hr><h3><a name="luaL_prepbuffer"><code>luaL_prepbuffer</code></a></h3><p>
+
<span class="apii">[-?, +?, <em>m</em>]</span>
+
<pre>char *luaL_prepbuffer (luaL_Buffer *B);</pre>
+

+
<p>
+
Equivalent to <a href="#luaL_prepbuffsize"><code>luaL_prepbuffsize</code></a>
+
with the predefined size <a name="pdf-LUAL_BUFFERSIZE"><code>LUAL_BUFFERSIZE</code></a>.
+

+

+

+

+

+
<hr><h3><a name="luaL_prepbuffsize"><code>luaL_prepbuffsize</code></a></h3><p>
+
<span class="apii">[-?, +?, <em>m</em>]</span>
+
<pre>char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz);</pre>
+

+
<p>
+
Returns an address to a space of size <code>sz</code>
+
where you can copy a string to be added to buffer <code>B</code>
+
(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+
After copying the string into this space you must call
+
<a href="#luaL_addsize"><code>luaL_addsize</code></a> with the size of the string to actually add
+
it to the buffer.
+

+

+

+

+

+
<hr><h3><a name="luaL_pushresult"><code>luaL_pushresult</code></a></h3><p>
+
<span class="apii">[-?, +1, <em>m</em>]</span>
+
<pre>void luaL_pushresult (luaL_Buffer *B);</pre>
+

+
<p>
+
Finishes the use of buffer <code>B</code> leaving the final string on
+
the top of the stack.
+

+

+

+

+

+
<hr><h3><a name="luaL_pushresultsize"><code>luaL_pushresultsize</code></a></h3><p>
+
<span class="apii">[-?, +1, <em>m</em>]</span>
+
<pre>void luaL_pushresultsize (luaL_Buffer *B, size_t sz);</pre>
+

+
<p>
+
Equivalent to the sequence <a href="#luaL_addsize"><code>luaL_addsize</code></a>, <a href="#luaL_pushresult"><code>luaL_pushresult</code></a>.
+

+

+

+

+

+
<hr><h3><a name="luaL_ref"><code>luaL_ref</code></a></h3><p>
+
<span class="apii">[-1, +0, <em>m</em>]</span>
+
<pre>int luaL_ref (lua_State *L, int t);</pre>
+

+
<p>
+
Creates and returns a <em>reference</em>,
+
in the table at index <code>t</code>,
+
for the object at the top of the stack (and pops the object).
+

+

+
<p>
+
A reference is a unique integer key.
+
As long as you do not manually add integer keys into table <code>t</code>,
+
<a href="#luaL_ref"><code>luaL_ref</code></a> ensures the uniqueness of the key it returns.
+
You can retrieve an object referred by reference <code>r</code>
+
by calling <code>lua_rawgeti(L, t, r)</code>.
+
Function <a href="#luaL_unref"><code>luaL_unref</code></a> frees a reference and its associated object.
+

+

+
<p>
+
If the object at the top of the stack is <b>nil</b>,
+
<a href="#luaL_ref"><code>luaL_ref</code></a> returns the constant <a name="pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>.
+
The constant <a name="pdf-LUA_NOREF"><code>LUA_NOREF</code></a> is guaranteed to be different
+
from any reference returned by <a href="#luaL_ref"><code>luaL_ref</code></a>.
+

+

+

+

+

+
<hr><h3><a name="luaL_Reg"><code>luaL_Reg</code></a></h3>
+
<pre>typedef struct luaL_Reg {
+
  const char *name;
+
  lua_CFunction func;
+
} luaL_Reg;</pre>
+

+
<p>
+
Type for arrays of functions to be registered by
+
<a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a>.
+
<code>name</code> is the function name and <code>func</code> is a pointer to
+
the function.
+
Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with a sentinel entry
+
in which both <code>name</code> and <code>func</code> are <code>NULL</code>.
+

+

+

+

+

+
<hr><h3><a name="luaL_requiref"><code>luaL_requiref</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>e</em>]</span>
+
<pre>void luaL_requiref (lua_State *L, const char *modname,
+
                    lua_CFunction openf, int glb);</pre>
+

+
<p>
+
If <code>modname</code> is not already present in <a href="#pdf-package.loaded"><code>package.loaded</code></a>,
+
calls function <code>openf</code> with string <code>modname</code> as an argument
+
and sets the call result in <code>package.loaded[modname]</code>,
+
as if that function has been called through <a href="#pdf-require"><code>require</code></a>.
+

+

+
<p>
+
If <code>glb</code> is true,
+
also stores the module into global <code>modname</code>.
+

+

+
<p>
+
Leaves a copy of the module on the stack.
+

+

+

+

+

+
<hr><h3><a name="luaL_setfuncs"><code>luaL_setfuncs</code></a></h3><p>
+
<span class="apii">[-nup, +0, <em>m</em>]</span>
+
<pre>void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);</pre>
+

+
<p>
+
Registers all functions in the array <code>l</code>
+
(see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack
+
(below optional upvalues, see next).
+

+

+
<p>
+
When <code>nup</code> is not zero,
+
all functions are created sharing <code>nup</code> upvalues,
+
which must be previously pushed on the stack
+
on top of the library table.
+
These values are popped from the stack after the registration.
+

+

+

+

+

+
<hr><h3><a name="luaL_setmetatable"><code>luaL_setmetatable</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void luaL_setmetatable (lua_State *L, const char *tname);</pre>
+

+
<p>
+
Sets the metatable of the object at the top of the stack
+
as the metatable associated with name <code>tname</code>
+
in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>).
+

+

+

+

+

+
<hr><h3><a name="luaL_Stream"><code>luaL_Stream</code></a></h3>
+
<pre>typedef struct luaL_Stream {
+
  FILE *f;
+
  lua_CFunction closef;
+
} luaL_Stream;</pre>
+

+
<p>
+
The standard representation for file handles,
+
which is used by the standard I/O library.
+

+

+
<p>
+
A file handle is implemented as a full userdata,
+
with a metatable called <code>LUA_FILEHANDLE</code>
+
(where <code>LUA_FILEHANDLE</code> is a macro with the actual metatable's name).
+
The metatable is created by the I/O library
+
(see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>).
+

+

+
<p>
+
This userdata must start with the structure <code>luaL_Stream</code>;
+
it can contain other data after this initial structure.
+
Field <code>f</code> points to the corresponding C stream
+
(or it can be <code>NULL</code> to indicate an incompletely created handle).
+
Field <code>closef</code> points to a Lua function
+
that will be called to close the stream
+
when the handle is closed or collected;
+
this function receives the file handle as its sole argument and
+
must return either <b>true</b> (in case of success)
+
or <b>nil</b> plus an error message (in case of error).
+
Once Lua calls this field,
+
it changes the field value to <code>NULL</code>
+
to signal that the handle is closed.
+

+

+

+

+

+
<hr><h3><a name="luaL_testudata"><code>luaL_testudata</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>m</em>]</span>
+
<pre>void *luaL_testudata (lua_State *L, int arg, const char *tname);</pre>
+

+
<p>
+
This function works like <a href="#luaL_checkudata"><code>luaL_checkudata</code></a>,
+
except that, when the test fails,
+
it returns <code>NULL</code> instead of raising an error.
+

+

+

+

+

+
<hr><h3><a name="luaL_tolstring"><code>luaL_tolstring</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>e</em>]</span>
+
<pre>const char *luaL_tolstring (lua_State *L, int idx, size_t *len);</pre>
+

+
<p>
+
Converts any Lua value at the given index to a C&nbsp;string
+
in a reasonable format.
+
The resulting string is pushed onto the stack and also
+
returned by the function.
+
If <code>len</code> is not <code>NULL</code>,
+
the function also sets <code>*len</code> with the string length.
+

+

+
<p>
+
If the value has a metatable with a <code>__tostring</code> field,
+
then <code>luaL_tolstring</code> calls the corresponding metamethod
+
with the value as argument,
+
and uses the result of the call as its result.
+

+

+

+

+

+
<hr><h3><a name="luaL_traceback"><code>luaL_traceback</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
+
                     int level);</pre>
+

+
<p>
+
Creates and pushes a traceback of the stack <code>L1</code>.
+
If <code>msg</code> is not <code>NULL</code> it is appended
+
at the beginning of the traceback.
+
The <code>level</code> parameter tells at which level
+
to start the traceback.
+

+

+

+

+

+
<hr><h3><a name="luaL_typename"><code>luaL_typename</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>const char *luaL_typename (lua_State *L, int index);</pre>
+

+
<p>
+
Returns the name of the type of the value at the given index.
+

+

+

+

+

+
<hr><h3><a name="luaL_unref"><code>luaL_unref</code></a></h3><p>
+
<span class="apii">[-0, +0, &ndash;]</span>
+
<pre>void luaL_unref (lua_State *L, int t, int ref);</pre>
+

+
<p>
+
Releases reference <code>ref</code> from the table at index <code>t</code>
+
(see <a href="#luaL_ref"><code>luaL_ref</code></a>).
+
The entry is removed from the table,
+
so that the referred object can be collected.
+
The reference <code>ref</code> is also freed to be used again.
+

+

+
<p>
+
If <code>ref</code> is <a href="#pdf-LUA_NOREF"><code>LUA_NOREF</code></a> or <a href="#pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>,
+
<a href="#luaL_unref"><code>luaL_unref</code></a> does nothing.
+

+

+

+

+

+
<hr><h3><a name="luaL_where"><code>luaL_where</code></a></h3><p>
+
<span class="apii">[-0, +1, <em>m</em>]</span>
+
<pre>void luaL_where (lua_State *L, int lvl);</pre>
+

+
<p>
+
Pushes onto the stack a string identifying the current position
+
of the control at level <code>lvl</code> in the call stack.
+
Typically this string has the following format:
+

+
<pre>
+
     <em>chunkname</em>:<em>currentline</em>:
+
</pre><p>
+
Level&nbsp;0 is the running function,
+
level&nbsp;1 is the function that called the running function,
+
etc.
+

+

+
<p>
+
This function is used to build a prefix for error messages.
+

+

+

+

+

+

+

+
<h1>6 &ndash; <a name="6">Standard Libraries</a></h1>
+

+
<p>
+
The standard Lua libraries provide useful functions
+
that are implemented directly through the C&nbsp;API.
+
Some of these functions provide essential services to the language
+
(e.g., <a href="#pdf-type"><code>type</code></a> and <a href="#pdf-getmetatable"><code>getmetatable</code></a>);
+
others provide access to "outside" services (e.g., I/O);
+
and others could be implemented in Lua itself,
+
but are quite useful or have critical performance requirements that
+
deserve an implementation in C (e.g., <a href="#pdf-table.sort"><code>table.sort</code></a>).
+

+

+
<p>
+
All libraries are implemented through the official C&nbsp;API
+
and are provided as separate C&nbsp;modules.
+
Currently, Lua has the following standard libraries:
+

+
<ul>
+

+
<li>basic library (<a href="#6.1">&sect;6.1</a>);</li>
+

+
<li>coroutine library (<a href="#6.2">&sect;6.2</a>);</li>
+

+
<li>package library (<a href="#6.3">&sect;6.3</a>);</li>
+

+
<li>string manipulation (<a href="#6.4">&sect;6.4</a>);</li>
+

+
<li>basic UTF-8 support (<a href="#6.5">&sect;6.5</a>);</li>
+

+
<li>table manipulation (<a href="#6.6">&sect;6.6</a>);</li>
+

+
<li>mathematical functions (<a href="#6.7">&sect;6.7</a>) (sin, log, etc.);</li>
+

+
<li>input and output (<a href="#6.8">&sect;6.8</a>);</li>
+

+
<li>operating system facilities (<a href="#6.9">&sect;6.9</a>);</li>
+

+
<li>debug facilities (<a href="#6.10">&sect;6.10</a>).</li>
+

+
</ul><p>
+
Except for the basic and the package libraries,
+
each library provides all its functions as fields of a global table
+
or as methods of its objects.
+

+

+
<p>
+
To have access to these libraries,
+
the C&nbsp;host program should call the <a href="#luaL_openlibs"><code>luaL_openlibs</code></a> function,
+
which opens all standard libraries.
+
Alternatively,
+
the host program can open them individually by using
+
<a href="#luaL_requiref"><code>luaL_requiref</code></a> to call
+
<a name="pdf-luaopen_base"><code>luaopen_base</code></a> (for the basic library),
+
<a name="pdf-luaopen_package"><code>luaopen_package</code></a> (for the package library),
+
<a name="pdf-luaopen_coroutine"><code>luaopen_coroutine</code></a> (for the coroutine library),
+
<a name="pdf-luaopen_string"><code>luaopen_string</code></a> (for the string library),
+
<a name="pdf-luaopen_utf8"><code>luaopen_utf8</code></a> (for the UTF8 library),
+
<a name="pdf-luaopen_table"><code>luaopen_table</code></a> (for the table library),
+
<a name="pdf-luaopen_math"><code>luaopen_math</code></a> (for the mathematical library),
+
<a name="pdf-luaopen_io"><code>luaopen_io</code></a> (for the I/O library),
+
<a name="pdf-luaopen_os"><code>luaopen_os</code></a> (for the operating system library),
+
and <a name="pdf-luaopen_debug"><code>luaopen_debug</code></a> (for the debug library).
+
These functions are declared in <a name="pdf-lualib.h"><code>lualib.h</code></a>.
+

+

+

+
<h2>6.1 &ndash; <a name="6.1">Basic Functions</a></h2>
+

+
<p>
+
The basic library provides core functions to Lua.
+
If you do not include this library in your application,
+
you should check carefully whether you need to provide
+
implementations for some of its facilities.
+

+

+
<p>
+
<hr><h3><a name="pdf-assert"><code>assert (v [, message])</code></a></h3>
+

+

+
<p>
+
Calls <a href="#pdf-error"><code>error</code></a> if
+
the value of its argument <code>v</code> is false (i.e., <b>nil</b> or <b>false</b>);
+
otherwise, returns all its arguments.
+
In case of error,
+
<code>message</code> is the error object;
+
when absent, it defaults to "<code>assertion failed!</code>"
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-collectgarbage"><code>collectgarbage ([opt [, arg]])</code></a></h3>
+

+

+
<p>
+
This function is a generic interface to the garbage collector.
+
It performs different functions according to its first argument, <code>opt</code>:
+

+
<ul>
+

+
<li><b>"<code>collect</code>": </b>
+
performs a full garbage-collection cycle.
+
This is the default option.
+
</li>
+

+
<li><b>"<code>stop</code>": </b>
+
stops automatic execution of the garbage collector.
+
The collector will run only when explicitly invoked,
+
until a call to restart it.
+
</li>
+

+
<li><b>"<code>restart</code>": </b>
+
restarts automatic execution of the garbage collector.
+
</li>
+

+
<li><b>"<code>count</code>": </b>
+
returns the total memory in use by Lua in Kbytes.
+
The value has a fractional part,
+
so that it multiplied by 1024
+
gives the exact number of bytes in use by Lua
+
(except for overflows).
+
</li>
+

+
<li><b>"<code>step</code>": </b>
+
performs a garbage-collection step.
+
The step "size" is controlled by <code>arg</code>.
+
With a zero value,
+
the collector will perform one basic (indivisible) step.
+
For non-zero values,
+
the collector will perform as if that amount of memory
+
(in KBytes) had been allocated by Lua.
+
Returns <b>true</b> if the step finished a collection cycle.
+
</li>
+

+
<li><b>"<code>setpause</code>": </b>
+
sets <code>arg</code> as the new value for the <em>pause</em> of
+
the collector (see <a href="#2.5">&sect;2.5</a>).
+
Returns the previous value for <em>pause</em>.
+
</li>
+

+
<li><b>"<code>setstepmul</code>": </b>
+
sets <code>arg</code> as the new value for the <em>step multiplier</em> of
+
the collector (see <a href="#2.5">&sect;2.5</a>).
+
Returns the previous value for <em>step</em>.
+
</li>
+

+
<li><b>"<code>isrunning</code>": </b>
+
returns a boolean that tells whether the collector is running
+
(i.e., not stopped).
+
</li>
+

+
</ul>
+

+

+

+
<p>
+
<hr><h3><a name="pdf-dofile"><code>dofile ([filename])</code></a></h3>
+
Opens the named file and executes its contents as a Lua chunk.
+
When called without arguments,
+
<code>dofile</code> executes the contents of the standard input (<code>stdin</code>).
+
Returns all values returned by the chunk.
+
In case of errors, <code>dofile</code> propagates the error
+
to its caller (that is, <code>dofile</code> does not run in protected mode).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-error"><code>error (message [, level])</code></a></h3>
+
Terminates the last protected function called
+
and returns <code>message</code> as the error object.
+
Function <code>error</code> never returns.
+

+

+
<p>
+
Usually, <code>error</code> adds some information about the error position
+
at the beginning of the message, if the message is a string.
+
The <code>level</code> argument specifies how to get the error position.
+
With level&nbsp;1 (the default), the error position is where the
+
<code>error</code> function was called.
+
Level&nbsp;2 points the error to where the function
+
that called <code>error</code> was called; and so on.
+
Passing a level&nbsp;0 avoids the addition of error position information
+
to the message.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-_G"><code>_G</code></a></h3>
+
A global variable (not a function) that
+
holds the global environment (see <a href="#2.2">&sect;2.2</a>).
+
Lua itself does not use this variable;
+
changing its value does not affect any environment,
+
nor vice versa.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-getmetatable"><code>getmetatable (object)</code></a></h3>
+

+

+
<p>
+
If <code>object</code> does not have a metatable, returns <b>nil</b>.
+
Otherwise,
+
if the object's metatable has a <code>__metatable</code> field,
+
returns the associated value.
+
Otherwise, returns the metatable of the given object.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-ipairs"><code>ipairs (t)</code></a></h3>
+

+

+
<p>
+
Returns three values (an iterator function, the table <code>t</code>, and 0)
+
so that the construction
+

+
<pre>
+
     for i,v in ipairs(t) do <em>body</em> end
+
</pre><p>
+
will iterate over the key&ndash;value pairs
+
(<code>1,t[1]</code>), (<code>2,t[2]</code>), ...,
+
up to the first nil value.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-load"><code>load (chunk [, chunkname [, mode [, env]]])</code></a></h3>
+

+

+
<p>
+
Loads a chunk.
+

+

+
<p>
+
If <code>chunk</code> is a string, the chunk is this string.
+
If <code>chunk</code> is a function,
+
<code>load</code> calls it repeatedly to get the chunk pieces.
+
Each call to <code>chunk</code> must return a string that concatenates
+
with previous results.
+
A return of an empty string, <b>nil</b>, or no value signals the end of the chunk.
+

+

+
<p>
+
If there are no syntactic errors,
+
returns the compiled chunk as a function;
+
otherwise, returns <b>nil</b> plus the error message.
+

+

+
<p>
+
If the resulting function has upvalues,
+
the first upvalue is set to the value of <code>env</code>,
+
if that parameter is given,
+
or to the value of the global environment.
+
Other upvalues are initialized with <b>nil</b>.
+
(When you load a main chunk,
+
the resulting function will always have exactly one upvalue,
+
the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).
+
However,
+
when you load a binary chunk created from a function (see <a href="#pdf-string.dump"><code>string.dump</code></a>),
+
the resulting function can have an arbitrary number of upvalues.)
+
All upvalues are fresh, that is,
+
they are not shared with any other function.
+

+

+
<p>
+
<code>chunkname</code> is used as the name of the chunk for error messages
+
and debug information (see <a href="#4.9">&sect;4.9</a>).
+
When absent,
+
it defaults to <code>chunk</code>, if <code>chunk</code> is a string,
+
or to "<code>=(load)</code>" otherwise.
+

+

+
<p>
+
The string <code>mode</code> controls whether the chunk can be text or binary
+
(that is, a precompiled chunk).
+
It may be the string "<code>b</code>" (only binary chunks),
+
"<code>t</code>" (only text chunks),
+
or "<code>bt</code>" (both binary and text).
+
The default is "<code>bt</code>".
+

+

+
<p>
+
Lua does not check the consistency of binary chunks.
+
Maliciously crafted binary chunks can crash
+
the interpreter.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-loadfile"><code>loadfile ([filename [, mode [, env]]])</code></a></h3>
+

+

+
<p>
+
Similar to <a href="#pdf-load"><code>load</code></a>,
+
but gets the chunk from file <code>filename</code>
+
or from the standard input,
+
if no file name is given.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-next"><code>next (table [, index])</code></a></h3>
+

+

+
<p>
+
Allows a program to traverse all fields of a table.
+
Its first argument is a table and its second argument
+
is an index in this table.
+
<code>next</code> returns the next index of the table
+
and its associated value.
+
When called with <b>nil</b> as its second argument,
+
<code>next</code> returns an initial index
+
and its associated value.
+
When called with the last index,
+
or with <b>nil</b> in an empty table,
+
<code>next</code> returns <b>nil</b>.
+
If the second argument is absent, then it is interpreted as <b>nil</b>.
+
In particular,
+
you can use <code>next(t)</code> to check whether a table is empty.
+

+

+
<p>
+
The order in which the indices are enumerated is not specified,
+
<em>even for numeric indices</em>.
+
(To traverse a table in numerical order,
+
use a numerical <b>for</b>.)
+

+

+
<p>
+
The behavior of <code>next</code> is undefined if,
+
during the traversal,
+
you assign any value to a non-existent field in the table.
+
You may however modify existing fields.
+
In particular, you may clear existing fields.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-pairs"><code>pairs (t)</code></a></h3>
+

+

+
<p>
+
If <code>t</code> has a metamethod <code>__pairs</code>,
+
calls it with <code>t</code> as argument and returns the first three
+
results from the call.
+

+

+
<p>
+
Otherwise,
+
returns three values: the <a href="#pdf-next"><code>next</code></a> function, the table <code>t</code>, and <b>nil</b>,
+
so that the construction
+

+
<pre>
+
     for k,v in pairs(t) do <em>body</em> end
+
</pre><p>
+
will iterate over all key&ndash;value pairs of table <code>t</code>.
+

+

+
<p>
+
See function <a href="#pdf-next"><code>next</code></a> for the caveats of modifying
+
the table during its traversal.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-pcall"><code>pcall (f [, arg1, &middot;&middot;&middot;])</code></a></h3>
+

+

+
<p>
+
Calls function <code>f</code> with
+
the given arguments in <em>protected mode</em>.
+
This means that any error inside&nbsp;<code>f</code> is not propagated;
+
instead, <code>pcall</code> catches the error
+
and returns a status code.
+
Its first result is the status code (a boolean),
+
which is true if the call succeeds without errors.
+
In such case, <code>pcall</code> also returns all results from the call,
+
after this first result.
+
In case of any error, <code>pcall</code> returns <b>false</b> plus the error message.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-print"><code>print (&middot;&middot;&middot;)</code></a></h3>
+
Receives any number of arguments
+
and prints their values to <code>stdout</code>,
+
using the <a href="#pdf-tostring"><code>tostring</code></a> function to convert each argument to a string.
+
<code>print</code> is not intended for formatted output,
+
but only as a quick way to show a value,
+
for instance for debugging.
+
For complete control over the output,
+
use <a href="#pdf-string.format"><code>string.format</code></a> and <a href="#pdf-io.write"><code>io.write</code></a>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-rawequal"><code>rawequal (v1, v2)</code></a></h3>
+
Checks whether <code>v1</code> is equal to <code>v2</code>,
+
without invoking the <code>__eq</code> metamethod.
+
Returns a boolean.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-rawget"><code>rawget (table, index)</code></a></h3>
+
Gets the real value of <code>table[index]</code>,
+
without invoking the <code>__index</code> metamethod.
+
<code>table</code> must be a table;
+
<code>index</code> may be any value.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-rawlen"><code>rawlen (v)</code></a></h3>
+
Returns the length of the object <code>v</code>,
+
which must be a table or a string,
+
without invoking the <code>__len</code> metamethod.
+
Returns an integer.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-rawset"><code>rawset (table, index, value)</code></a></h3>
+
Sets the real value of <code>table[index]</code> to <code>value</code>,
+
without invoking the <code>__newindex</code> metamethod.
+
<code>table</code> must be a table,
+
<code>index</code> any value different from <b>nil</b> and NaN,
+
and <code>value</code> any Lua value.
+

+

+
<p>
+
This function returns <code>table</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-select"><code>select (index, &middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
If <code>index</code> is a number,
+
returns all arguments after argument number <code>index</code>;
+
a negative number indexes from the end (-1 is the last argument).
+
Otherwise, <code>index</code> must be the string <code>"#"</code>,
+
and <code>select</code> returns the total number of extra arguments it received.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-setmetatable"><code>setmetatable (table, metatable)</code></a></h3>
+

+

+
<p>
+
Sets the metatable for the given table.
+
(To change the metatable of other types from Lua code,
+
you must use the debug library (<a href="#6.10">&sect;6.10</a>).)
+
If <code>metatable</code> is <b>nil</b>,
+
removes the metatable of the given table.
+
If the original metatable has a <code>__metatable</code> field,
+
raises an error.
+

+

+
<p>
+
This function returns <code>table</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-tonumber"><code>tonumber (e [, base])</code></a></h3>
+

+

+
<p>
+
When called with no <code>base</code>,
+
<code>tonumber</code> tries to convert its argument to a number.
+
If the argument is already a number or
+
a string convertible to a number,
+
then <code>tonumber</code> returns this number;
+
otherwise, it returns <b>nil</b>.
+

+

+
<p>
+
The conversion of strings can result in integers or floats,
+
according to the lexical conventions of Lua (see <a href="#3.1">&sect;3.1</a>).
+
(The string may have leading and trailing spaces and a sign.)
+

+

+
<p>
+
When called with <code>base</code>,
+
then <code>e</code> must be a string to be interpreted as
+
an integer numeral in that base.
+
The base may be any integer between 2 and 36, inclusive.
+
In bases above&nbsp;10, the letter '<code>A</code>' (in either upper or lower case)
+
represents&nbsp;10, '<code>B</code>' represents&nbsp;11, and so forth,
+
with '<code>Z</code>' representing 35.
+
If the string <code>e</code> is not a valid numeral in the given base,
+
the function returns <b>nil</b>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-tostring"><code>tostring (v)</code></a></h3>
+
Receives a value of any type and
+
converts it to a string in a human-readable format.
+
(For complete control of how numbers are converted,
+
use <a href="#pdf-string.format"><code>string.format</code></a>.)
+

+

+
<p>
+
If the metatable of <code>v</code> has a <code>__tostring</code> field,
+
then <code>tostring</code> calls the corresponding value
+
with <code>v</code> as argument,
+
and uses the result of the call as its result.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-type"><code>type (v)</code></a></h3>
+
Returns the type of its only argument, coded as a string.
+
The possible results of this function are
+
"<code>nil</code>" (a string, not the value <b>nil</b>),
+
"<code>number</code>",
+
"<code>string</code>",
+
"<code>boolean</code>",
+
"<code>table</code>",
+
"<code>function</code>",
+
"<code>thread</code>",
+
and "<code>userdata</code>".
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-_VERSION"><code>_VERSION</code></a></h3>
+

+

+
<p>
+
A global variable (not a function) that
+
holds a string containing the running Lua version.
+
The current value of this variable is "<code>Lua 5.3</code>".
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-xpcall"><code>xpcall (f, msgh [, arg1, &middot;&middot;&middot;])</code></a></h3>
+

+

+
<p>
+
This function is similar to <a href="#pdf-pcall"><code>pcall</code></a>,
+
except that it sets a new message handler <code>msgh</code>.
+

+

+

+

+

+

+

+
<h2>6.2 &ndash; <a name="6.2">Coroutine Manipulation</a></h2>
+

+
<p>
+
This library comprises the operations to manipulate coroutines,
+
which come inside the table <a name="pdf-coroutine"><code>coroutine</code></a>.
+
See <a href="#2.6">&sect;2.6</a> for a general description of coroutines.
+

+

+
<p>
+
<hr><h3><a name="pdf-coroutine.create"><code>coroutine.create (f)</code></a></h3>
+

+

+
<p>
+
Creates a new coroutine, with body <code>f</code>.
+
<code>f</code> must be a function.
+
Returns this new coroutine,
+
an object with type <code>"thread"</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-coroutine.isyieldable"><code>coroutine.isyieldable ()</code></a></h3>
+

+

+
<p>
+
Returns true when the running coroutine can yield.
+

+

+
<p>
+
A running coroutine is yieldable if it is not the main thread and
+
it is not inside a non-yieldable C&nbsp;function.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-coroutine.resume"><code>coroutine.resume (co [, val1, &middot;&middot;&middot;])</code></a></h3>
+

+

+
<p>
+
Starts or continues the execution of coroutine <code>co</code>.
+
The first time you resume a coroutine,
+
it starts running its body.
+
The values <code>val1</code>, ... are passed
+
as the arguments to the body function.
+
If the coroutine has yielded,
+
<code>resume</code> restarts it;
+
the values <code>val1</code>, ... are passed
+
as the results from the yield.
+

+

+
<p>
+
If the coroutine runs without any errors,
+
<code>resume</code> returns <b>true</b> plus any values passed to <code>yield</code>
+
(when the coroutine yields) or any values returned by the body function
+
(when the coroutine terminates).
+
If there is any error,
+
<code>resume</code> returns <b>false</b> plus the error message.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-coroutine.running"><code>coroutine.running ()</code></a></h3>
+

+

+
<p>
+
Returns the running coroutine plus a boolean,
+
true when the running coroutine is the main one.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-coroutine.status"><code>coroutine.status (co)</code></a></h3>
+

+

+
<p>
+
Returns the status of coroutine <code>co</code>, as a string:
+
<code>"running"</code>,
+
if the coroutine is running (that is, it called <code>status</code>);
+
<code>"suspended"</code>, if the coroutine is suspended in a call to <code>yield</code>,
+
or if it has not started running yet;
+
<code>"normal"</code> if the coroutine is active but not running
+
(that is, it has resumed another coroutine);
+
and <code>"dead"</code> if the coroutine has finished its body function,
+
or if it has stopped with an error.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-coroutine.wrap"><code>coroutine.wrap (f)</code></a></h3>
+

+

+
<p>
+
Creates a new coroutine, with body <code>f</code>.
+
<code>f</code> must be a function.
+
Returns a function that resumes the coroutine each time it is called.
+
Any arguments passed to the function behave as the
+
extra arguments to <code>resume</code>.
+
Returns the same values returned by <code>resume</code>,
+
except the first boolean.
+
In case of error, propagates the error.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-coroutine.yield"><code>coroutine.yield (&middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Suspends the execution of the calling coroutine.
+
Any arguments to <code>yield</code> are passed as extra results to <code>resume</code>.
+

+

+

+

+

+

+

+
<h2>6.3 &ndash; <a name="6.3">Modules</a></h2>
+

+
<p>
+
The package library provides basic
+
facilities for loading modules in Lua.
+
It exports one function directly in the global environment:
+
<a href="#pdf-require"><code>require</code></a>.
+
Everything else is exported in a table <a name="pdf-package"><code>package</code></a>.
+

+

+
<p>
+
<hr><h3><a name="pdf-require"><code>require (modname)</code></a></h3>
+

+

+
<p>
+
Loads the given module.
+
The function starts by looking into the <a href="#pdf-package.loaded"><code>package.loaded</code></a> table
+
to determine whether <code>modname</code> is already loaded.
+
If it is, then <code>require</code> returns the value stored
+
at <code>package.loaded[modname]</code>.
+
Otherwise, it tries to find a <em>loader</em> for the module.
+

+

+
<p>
+
To find a loader,
+
<code>require</code> is guided by the <a href="#pdf-package.searchers"><code>package.searchers</code></a> sequence.
+
By changing this sequence,
+
we can change how <code>require</code> looks for a module.
+
The following explanation is based on the default configuration
+
for <a href="#pdf-package.searchers"><code>package.searchers</code></a>.
+

+

+
<p>
+
First <code>require</code> queries <code>package.preload[modname]</code>.
+
If it has a value,
+
this value (which must be a function) is the loader.
+
Otherwise <code>require</code> searches for a Lua loader using the
+
path stored in <a href="#pdf-package.path"><code>package.path</code></a>.
+
If that also fails, it searches for a C&nbsp;loader using the
+
path stored in <a href="#pdf-package.cpath"><code>package.cpath</code></a>.
+
If that also fails,
+
it tries an <em>all-in-one</em> loader (see <a href="#pdf-package.searchers"><code>package.searchers</code></a>).
+

+

+
<p>
+
Once a loader is found,
+
<code>require</code> calls the loader with two arguments:
+
<code>modname</code> and an extra value dependent on how it got the loader.
+
(If the loader came from a file,
+
this extra value is the file name.)
+
If the loader returns any non-nil value,
+
<code>require</code> assigns the returned value to <code>package.loaded[modname]</code>.
+
If the loader does not return a non-nil value and
+
has not assigned any value to <code>package.loaded[modname]</code>,
+
then <code>require</code> assigns <b>true</b> to this entry.
+
In any case, <code>require</code> returns the
+
final value of <code>package.loaded[modname]</code>.
+

+

+
<p>
+
If there is any error loading or running the module,
+
or if it cannot find any loader for the module,
+
then <code>require</code> raises an error.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-package.config"><code>package.config</code></a></h3>
+

+

+
<p>
+
A string describing some compile-time configurations for packages.
+
This string is a sequence of lines:
+

+
<ul>
+

+
<li>The first line is the directory separator string.
+
Default is '<code>\</code>' for Windows and '<code>/</code>' for all other systems.</li>
+

+
<li>The second line is the character that separates templates in a path.
+
Default is '<code>;</code>'.</li>
+

+
<li>The third line is the string that marks the
+
substitution points in a template.
+
Default is '<code>?</code>'.</li>
+

+
<li>The fourth line is a string that, in a path in Windows,
+
is replaced by the executable's directory.
+
Default is '<code>!</code>'.</li>
+

+
<li>The fifth line is a mark to ignore all text after it
+
when building the <code>luaopen_</code> function name.
+
Default is '<code>-</code>'.</li>
+

+
</ul>
+

+

+

+
<p>
+
<hr><h3><a name="pdf-package.cpath"><code>package.cpath</code></a></h3>
+

+

+
<p>
+
The path used by <a href="#pdf-require"><code>require</code></a> to search for a C&nbsp;loader.
+

+

+
<p>
+
Lua initializes the C&nbsp;path <a href="#pdf-package.cpath"><code>package.cpath</code></a> in the same way
+
it initializes the Lua path <a href="#pdf-package.path"><code>package.path</code></a>,
+
using the environment variable <a name="pdf-LUA_CPATH_5_3"><code>LUA_CPATH_5_3</code></a>,
+
or the environment variable <a name="pdf-LUA_CPATH"><code>LUA_CPATH</code></a>,
+
or a default path defined in <code>luaconf.h</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-package.loaded"><code>package.loaded</code></a></h3>
+

+

+
<p>
+
A table used by <a href="#pdf-require"><code>require</code></a> to control which
+
modules are already loaded.
+
When you require a module <code>modname</code> and
+
<code>package.loaded[modname]</code> is not false,
+
<a href="#pdf-require"><code>require</code></a> simply returns the value stored there.
+

+

+
<p>
+
This variable is only a reference to the real table;
+
assignments to this variable do not change the
+
table used by <a href="#pdf-require"><code>require</code></a>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-package.loadlib"><code>package.loadlib (libname, funcname)</code></a></h3>
+

+

+
<p>
+
Dynamically links the host program with the C&nbsp;library <code>libname</code>.
+

+

+
<p>
+
If <code>funcname</code> is "<code>*</code>",
+
then it only links with the library,
+
making the symbols exported by the library
+
available to other dynamically linked libraries.
+
Otherwise,
+
it looks for a function <code>funcname</code> inside the library
+
and returns this function as a C&nbsp;function.
+
So, <code>funcname</code> must follow the <a href="#lua_CFunction"><code>lua_CFunction</code></a> prototype
+
(see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
+

+

+
<p>
+
This is a low-level function.
+
It completely bypasses the package and module system.
+
Unlike <a href="#pdf-require"><code>require</code></a>,
+
it does not perform any path searching and
+
does not automatically adds extensions.
+
<code>libname</code> must be the complete file name of the C&nbsp;library,
+
including if necessary a path and an extension.
+
<code>funcname</code> must be the exact name exported by the C&nbsp;library
+
(which may depend on the C&nbsp;compiler and linker used).
+

+

+
<p>
+
This function is not supported by Standard&nbsp;C.
+
As such, it is only available on some platforms
+
(Windows, Linux, Mac OS X, Solaris, BSD,
+
plus other Unix systems that support the <code>dlfcn</code> standard).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-package.path"><code>package.path</code></a></h3>
+

+

+
<p>
+
The path used by <a href="#pdf-require"><code>require</code></a> to search for a Lua loader.
+

+

+
<p>
+
At start-up, Lua initializes this variable with
+
the value of the environment variable <a name="pdf-LUA_PATH_5_3"><code>LUA_PATH_5_3</code></a> or
+
the environment variable <a name="pdf-LUA_PATH"><code>LUA_PATH</code></a> or
+
with a default path defined in <code>luaconf.h</code>,
+
if those environment variables are not defined.
+
Any "<code>;;</code>" in the value of the environment variable
+
is replaced by the default path.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-package.preload"><code>package.preload</code></a></h3>
+

+

+
<p>
+
A table to store loaders for specific modules
+
(see <a href="#pdf-require"><code>require</code></a>).
+

+

+
<p>
+
This variable is only a reference to the real table;
+
assignments to this variable do not change the
+
table used by <a href="#pdf-require"><code>require</code></a>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-package.searchers"><code>package.searchers</code></a></h3>
+

+

+
<p>
+
A table used by <a href="#pdf-require"><code>require</code></a> to control how to load modules.
+

+

+
<p>
+
Each entry in this table is a <em>searcher function</em>.
+
When looking for a module,
+
<a href="#pdf-require"><code>require</code></a> calls each of these searchers in ascending order,
+
with the module name (the argument given to <a href="#pdf-require"><code>require</code></a>) as its
+
sole parameter.
+
The function can return another function (the module <em>loader</em>)
+
plus an extra value that will be passed to that loader,
+
or a string explaining why it did not find that module
+
(or <b>nil</b> if it has nothing to say).
+

+

+
<p>
+
Lua initializes this table with four searcher functions.
+

+

+
<p>
+
The first searcher simply looks for a loader in the
+
<a href="#pdf-package.preload"><code>package.preload</code></a> table.
+

+

+
<p>
+
The second searcher looks for a loader as a Lua library,
+
using the path stored at <a href="#pdf-package.path"><code>package.path</code></a>.
+
The search is done as described in function <a href="#pdf-package.searchpath"><code>package.searchpath</code></a>.
+

+

+
<p>
+
The third searcher looks for a loader as a C&nbsp;library,
+
using the path given by the variable <a href="#pdf-package.cpath"><code>package.cpath</code></a>.
+
Again,
+
the search is done as described in function <a href="#pdf-package.searchpath"><code>package.searchpath</code></a>.
+
For instance,
+
if the C&nbsp;path is the string
+

+
<pre>
+
     "./?.so;./?.dll;/usr/local/?/init.so"
+
</pre><p>
+
the searcher for module <code>foo</code>
+
will try to open the files <code>./foo.so</code>, <code>./foo.dll</code>,
+
and <code>/usr/local/foo/init.so</code>, in that order.
+
Once it finds a C&nbsp;library,
+
this searcher first uses a dynamic link facility to link the
+
application with the library.
+
Then it tries to find a C&nbsp;function inside the library to
+
be used as the loader.
+
The name of this C&nbsp;function is the string "<code>luaopen_</code>"
+
concatenated with a copy of the module name where each dot
+
is replaced by an underscore.
+
Moreover, if the module name has a hyphen,
+
its suffix after (and including) the first hyphen is removed.
+
For instance, if the module name is <code>a.b.c-v2.1</code>,
+
the function name will be <code>luaopen_a_b_c</code>.
+

+

+
<p>
+
The fourth searcher tries an <em>all-in-one loader</em>.
+
It searches the C&nbsp;path for a library for
+
the root name of the given module.
+
For instance, when requiring <code>a.b.c</code>,
+
it will search for a C&nbsp;library for <code>a</code>.
+
If found, it looks into it for an open function for
+
the submodule;
+
in our example, that would be <code>luaopen_a_b_c</code>.
+
With this facility, a package can pack several C&nbsp;submodules
+
into one single library,
+
with each submodule keeping its original open function.
+

+

+
<p>
+
All searchers except the first one (preload) return as the extra value
+
the file name where the module was found,
+
as returned by <a href="#pdf-package.searchpath"><code>package.searchpath</code></a>.
+
The first searcher returns no extra value.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-package.searchpath"><code>package.searchpath (name, path [, sep [, rep]])</code></a></h3>
+

+

+
<p>
+
Searches for the given <code>name</code> in the given <code>path</code>.
+

+

+
<p>
+
A path is a string containing a sequence of
+
<em>templates</em> separated by semicolons.
+
For each template,
+
the function replaces each interrogation mark (if any)
+
in the template with a copy of <code>name</code>
+
wherein all occurrences of <code>sep</code>
+
(a dot, by default)
+
were replaced by <code>rep</code>
+
(the system's directory separator, by default),
+
and then tries to open the resulting file name.
+

+

+
<p>
+
For instance, if the path is the string
+

+
<pre>
+
     "./?.lua;./?.lc;/usr/local/?/init.lua"
+
</pre><p>
+
the search for the name <code>foo.a</code>
+
will try to open the files
+
<code>./foo/a.lua</code>, <code>./foo/a.lc</code>, and
+
<code>/usr/local/foo/a/init.lua</code>, in that order.
+

+

+
<p>
+
Returns the resulting name of the first file that it can
+
open in read mode (after closing the file),
+
or <b>nil</b> plus an error message if none succeeds.
+
(This error message lists all file names it tried to open.)
+

+

+

+

+

+

+

+
<h2>6.4 &ndash; <a name="6.4">String Manipulation</a></h2>
+

+
<p>
+
This library provides generic functions for string manipulation,
+
such as finding and extracting substrings, and pattern matching.
+
When indexing a string in Lua, the first character is at position&nbsp;1
+
(not at&nbsp;0, as in C).
+
Indices are allowed to be negative and are interpreted as indexing backwards,
+
from the end of the string.
+
Thus, the last character is at position -1, and so on.
+

+

+
<p>
+
The string library provides all its functions inside the table
+
<a name="pdf-string"><code>string</code></a>.
+
It also sets a metatable for strings
+
where the <code>__index</code> field points to the <code>string</code> table.
+
Therefore, you can use the string functions in object-oriented style.
+
For instance, <code>string.byte(s,i)</code>
+
can be written as <code>s:byte(i)</code>.
+

+

+
<p>
+
The string library assumes one-byte character encodings.
+

+

+
<p>
+
<hr><h3><a name="pdf-string.byte"><code>string.byte (s [, i [, j]])</code></a></h3>
+
Returns the internal numeric codes of the characters <code>s[i]</code>,
+
<code>s[i+1]</code>, ..., <code>s[j]</code>.
+
The default value for <code>i</code> is&nbsp;1;
+
the default value for <code>j</code> is&nbsp;<code>i</code>.
+
These indices are corrected
+
following the same rules of function <a href="#pdf-string.sub"><code>string.sub</code></a>.
+

+

+
<p>
+
Numeric codes are not necessarily portable across platforms.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.char"><code>string.char (&middot;&middot;&middot;)</code></a></h3>
+
Receives zero or more integers.
+
Returns a string with length equal to the number of arguments,
+
in which each character has the internal numeric code equal
+
to its corresponding argument.
+

+

+
<p>
+
Numeric codes are not necessarily portable across platforms.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.dump"><code>string.dump (function [, strip])</code></a></h3>
+

+

+
<p>
+
Returns a string containing a binary representation
+
(a <em>binary chunk</em>)
+
of the given function,
+
so that a later <a href="#pdf-load"><code>load</code></a> on this string returns
+
a copy of the function (but with new upvalues).
+
If <code>strip</code> is a true value,
+
the binary representation may not include all debug information
+
about the function,
+
to save space.
+

+

+
<p>
+
Functions with upvalues have only their number of upvalues saved.
+
When (re)loaded,
+
those upvalues receive fresh instances containing <b>nil</b>.
+
(You can use the debug library to serialize
+
and reload the upvalues of a function
+
in a way adequate to your needs.)
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.find"><code>string.find (s, pattern [, init [, plain]])</code></a></h3>
+

+

+
<p>
+
Looks for the first match of
+
<code>pattern</code> (see <a href="#6.4.1">&sect;6.4.1</a>) in the string <code>s</code>.
+
If it finds a match, then <code>find</code> returns the indices of&nbsp;<code>s</code>
+
where this occurrence starts and ends;
+
otherwise, it returns <b>nil</b>.
+
A third, optional numeric argument <code>init</code> specifies
+
where to start the search;
+
its default value is&nbsp;1 and can be negative.
+
A value of <b>true</b> as a fourth, optional argument <code>plain</code>
+
turns off the pattern matching facilities,
+
so the function does a plain "find substring" operation,
+
with no characters in <code>pattern</code> being considered magic.
+
Note that if <code>plain</code> is given, then <code>init</code> must be given as well.
+

+

+
<p>
+
If the pattern has captures,
+
then in a successful match
+
the captured values are also returned,
+
after the two indices.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.format"><code>string.format (formatstring, &middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Returns a formatted version of its variable number of arguments
+
following the description given in its first argument (which must be a string).
+
The format string follows the same rules as the ISO&nbsp;C function <code>sprintf</code>.
+
The only differences are that the options/modifiers
+
<code>*</code>, <code>h</code>, <code>L</code>, <code>l</code>, <code>n</code>,
+
and <code>p</code> are not supported
+
and that there is an extra option, <code>q</code>.
+

+

+
<p>
+
The <code>q</code> option formats a string between double quotes,
+
using escape sequences when necessary to ensure that
+
it can safely be read back by the Lua interpreter.
+
For instance, the call
+

+
<pre>
+
     string.format('%q', 'a string with "quotes" and \n new line')
+
</pre><p>
+
may produce the string:
+

+
<pre>
+
     "a string with \"quotes\" and \
+
      new line"
+
</pre>
+

+
<p>
+
Options
+
<code>A</code>, <code>a</code>, <code>E</code>, <code>e</code>, <code>f</code>,
+
<code>G</code>, and <code>g</code> all expect a number as argument.
+
Options <code>c</code>, <code>d</code>,
+
<code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code>
+
expect an integer.
+
When Lua is compiled with a C89 compiler,
+
options <code>A</code> and <code>a</code> (hexadecimal floats)
+
do not support any modifier (flags, width, length).
+

+

+
<p>
+
Option <code>s</code> expects a string;
+
if its argument is not a string,
+
it is converted to one following the same rules of <a href="#pdf-tostring"><code>tostring</code></a>.
+
If the option has any modifier (flags, width, length),
+
the string argument should not contain embedded zeros.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.gmatch"><code>string.gmatch (s, pattern)</code></a></h3>
+
Returns an iterator function that,
+
each time it is called,
+
returns the next captures from <code>pattern</code> (see <a href="#6.4.1">&sect;6.4.1</a>)
+
over the string <code>s</code>.
+
If <code>pattern</code> specifies no captures,
+
then the whole match is produced in each call.
+

+

+
<p>
+
As an example, the following loop
+
will iterate over all the words from string <code>s</code>,
+
printing one per line:
+

+
<pre>
+
     s = "hello world from Lua"
+
     for w in string.gmatch(s, "%a+") do
+
       print(w)
+
     end
+
</pre><p>
+
The next example collects all pairs <code>key=value</code> from the
+
given string into a table:
+

+
<pre>
+
     t = {}
+
     s = "from=world, to=Lua"
+
     for k, v in string.gmatch(s, "(%w+)=(%w+)") do
+
       t[k] = v
+
     end
+
</pre>
+

+
<p>
+
For this function, a caret '<code>^</code>' at the start of a pattern does not
+
work as an anchor, as this would prevent the iteration.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.gsub"><code>string.gsub (s, pattern, repl [, n])</code></a></h3>
+
Returns a copy of <code>s</code>
+
in which all (or the first <code>n</code>, if given)
+
occurrences of the <code>pattern</code> (see <a href="#6.4.1">&sect;6.4.1</a>) have been
+
replaced by a replacement string specified by <code>repl</code>,
+
which can be a string, a table, or a function.
+
<code>gsub</code> also returns, as its second value,
+
the total number of matches that occurred.
+
The name <code>gsub</code> comes from <em>Global SUBstitution</em>.
+

+

+
<p>
+
If <code>repl</code> is a string, then its value is used for replacement.
+
The character&nbsp;<code>%</code> works as an escape character:
+
any sequence in <code>repl</code> of the form <code>%<em>d</em></code>,
+
with <em>d</em> between 1 and 9,
+
stands for the value of the <em>d</em>-th captured substring.
+
The sequence <code>%0</code> stands for the whole match.
+
The sequence <code>%%</code> stands for a single&nbsp;<code>%</code>.
+

+

+
<p>
+
If <code>repl</code> is a table, then the table is queried for every match,
+
using the first capture as the key.
+

+

+
<p>
+
If <code>repl</code> is a function, then this function is called every time a
+
match occurs, with all captured substrings passed as arguments,
+
in order.
+

+

+
<p>
+
In any case,
+
if the pattern specifies no captures,
+
then it behaves as if the whole pattern was inside a capture.
+

+

+
<p>
+
If the value returned by the table query or by the function call
+
is a string or a number,
+
then it is used as the replacement string;
+
otherwise, if it is <b>false</b> or <b>nil</b>,
+
then there is no replacement
+
(that is, the original match is kept in the string).
+

+

+
<p>
+
Here are some examples:
+

+
<pre>
+
     x = string.gsub("hello world", "(%w+)", "%1 %1")
+
     --&gt; x="hello hello world world"
+
     
+
     x = string.gsub("hello world", "%w+", "%0 %0", 1)
+
     --&gt; x="hello hello world"
+
     
+
     x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
+
     --&gt; x="world hello Lua from"
+
     
+
     x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
+
     --&gt; x="home = /home/roberto, user = roberto"
+
     
+
     x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
+
           return load(s)()
+
         end)
+
     --&gt; x="4+5 = 9"
+
     
+
     local t = {name="lua", version="5.3"}
+
     x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
+
     --&gt; x="lua-5.3.tar.gz"
+
</pre>
+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.len"><code>string.len (s)</code></a></h3>
+
Receives a string and returns its length.
+
The empty string <code>""</code> has length 0.
+
Embedded zeros are counted,
+
so <code>"a\000bc\000"</code> has length 5.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.lower"><code>string.lower (s)</code></a></h3>
+
Receives a string and returns a copy of this string with all
+
uppercase letters changed to lowercase.
+
All other characters are left unchanged.
+
The definition of what an uppercase letter is depends on the current locale.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.match"><code>string.match (s, pattern [, init])</code></a></h3>
+
Looks for the first <em>match</em> of
+
<code>pattern</code> (see <a href="#6.4.1">&sect;6.4.1</a>) in the string <code>s</code>.
+
If it finds one, then <code>match</code> returns
+
the captures from the pattern;
+
otherwise it returns <b>nil</b>.
+
If <code>pattern</code> specifies no captures,
+
then the whole match is returned.
+
A third, optional numeric argument <code>init</code> specifies
+
where to start the search;
+
its default value is&nbsp;1 and can be negative.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.pack"><code>string.pack (fmt, v1, v2, &middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Returns a binary string containing the values <code>v1</code>, <code>v2</code>, etc.
+
packed (that is, serialized in binary form)
+
according to the format string <code>fmt</code> (see <a href="#6.4.2">&sect;6.4.2</a>).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.packsize"><code>string.packsize (fmt)</code></a></h3>
+

+

+
<p>
+
Returns the size of a string resulting from <a href="#pdf-string.pack"><code>string.pack</code></a>
+
with the given format.
+
The format string cannot have the variable-length options
+
'<code>s</code>' or '<code>z</code>' (see <a href="#6.4.2">&sect;6.4.2</a>).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.rep"><code>string.rep (s, n [, sep])</code></a></h3>
+
Returns a string that is the concatenation of <code>n</code> copies of
+
the string <code>s</code> separated by the string <code>sep</code>.
+
The default value for <code>sep</code> is the empty string
+
(that is, no separator).
+
Returns the empty string if <code>n</code> is not positive.
+

+

+
<p>
+
(Note that it is very easy to exhaust the memory of your machine
+
with a single call to this function.)
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.reverse"><code>string.reverse (s)</code></a></h3>
+
Returns a string that is the string <code>s</code> reversed.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.sub"><code>string.sub (s, i [, j])</code></a></h3>
+
Returns the substring of <code>s</code> that
+
starts at <code>i</code>  and continues until <code>j</code>;
+
<code>i</code> and <code>j</code> can be negative.
+
If <code>j</code> is absent, then it is assumed to be equal to -1
+
(which is the same as the string length).
+
In particular,
+
the call <code>string.sub(s,1,j)</code> returns a prefix of <code>s</code>
+
with length <code>j</code>,
+
and <code>string.sub(s, -i)</code> (for a positive <code>i</code>)
+
returns a suffix of <code>s</code>
+
with length <code>i</code>.
+

+

+
<p>
+
If, after the translation of negative indices,
+
<code>i</code> is less than 1,
+
it is corrected to 1.
+
If <code>j</code> is greater than the string length,
+
it is corrected to that length.
+
If, after these corrections,
+
<code>i</code> is greater than <code>j</code>,
+
the function returns the empty string.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.unpack"><code>string.unpack (fmt, s [, pos])</code></a></h3>
+

+

+
<p>
+
Returns the values packed in string <code>s</code> (see <a href="#pdf-string.pack"><code>string.pack</code></a>)
+
according to the format string <code>fmt</code> (see <a href="#6.4.2">&sect;6.4.2</a>).
+
An optional <code>pos</code> marks where
+
to start reading in <code>s</code> (default is 1).
+
After the read values,
+
this function also returns the index of the first unread byte in <code>s</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-string.upper"><code>string.upper (s)</code></a></h3>
+
Receives a string and returns a copy of this string with all
+
lowercase letters changed to uppercase.
+
All other characters are left unchanged.
+
The definition of what a lowercase letter is depends on the current locale.
+

+

+

+

+

+
<h3>6.4.1 &ndash; <a name="6.4.1">Patterns</a></h3>
+

+
<p>
+
Patterns in Lua are described by regular strings,
+
which are interpreted as patterns by the pattern-matching functions
+
<a href="#pdf-string.find"><code>string.find</code></a>,
+
<a href="#pdf-string.gmatch"><code>string.gmatch</code></a>,
+
<a href="#pdf-string.gsub"><code>string.gsub</code></a>,
+
and <a href="#pdf-string.match"><code>string.match</code></a>.
+
This section describes the syntax and the meaning
+
(that is, what they match) of these strings.
+

+

+

+
<h4>Character Class:</h4><p>
+
A <em>character class</em> is used to represent a set of characters.
+
The following combinations are allowed in describing a character class:
+

+
<ul>
+

+
<li><b><em>x</em>: </b>
+
(where <em>x</em> is not one of the <em>magic characters</em>
+
<code>^$()%.[]*+-?</code>)
+
represents the character <em>x</em> itself.
+
</li>
+

+
<li><b><code>.</code>: </b> (a dot) represents all characters.</li>
+

+
<li><b><code>%a</code>: </b> represents all letters.</li>
+

+
<li><b><code>%c</code>: </b> represents all control characters.</li>
+

+
<li><b><code>%d</code>: </b> represents all digits.</li>
+

+
<li><b><code>%g</code>: </b> represents all printable characters except space.</li>
+

+
<li><b><code>%l</code>: </b> represents all lowercase letters.</li>
+

+
<li><b><code>%p</code>: </b> represents all punctuation characters.</li>
+

+
<li><b><code>%s</code>: </b> represents all space characters.</li>
+

+
<li><b><code>%u</code>: </b> represents all uppercase letters.</li>
+

+
<li><b><code>%w</code>: </b> represents all alphanumeric characters.</li>
+

+
<li><b><code>%x</code>: </b> represents all hexadecimal digits.</li>
+

+
<li><b><code>%<em>x</em></code>: </b> (where <em>x</em> is any non-alphanumeric character)
+
represents the character <em>x</em>.
+
This is the standard way to escape the magic characters.
+
Any non-alphanumeric character
+
(including all punctuation characters, even the non-magical)
+
can be preceded by a '<code>%</code>'
+
when used to represent itself in a pattern.
+
</li>
+

+
<li><b><code>[<em>set</em>]</code>: </b>
+
represents the class which is the union of all
+
characters in <em>set</em>.
+
A range of characters can be specified by
+
separating the end characters of the range,
+
in ascending order, with a '<code>-</code>'.
+
All classes <code>%</code><em>x</em> described above can also be used as
+
components in <em>set</em>.
+
All other characters in <em>set</em> represent themselves.
+
For example, <code>[%w_]</code> (or <code>[_%w]</code>)
+
represents all alphanumeric characters plus the underscore,
+
<code>[0-7]</code> represents the octal digits,
+
and <code>[0-7%l%-]</code> represents the octal digits plus
+
the lowercase letters plus the '<code>-</code>' character.
+

+

+
<p>
+
You can put a closing square bracket in a set
+
by positioning it as the first character in the set.
+
You can put a hyphen in a set
+
by positioning it as the first or the last character in the set.
+
(You can also use an escape for both cases.)
+

+

+
<p>
+
The interaction between ranges and classes is not defined.
+
Therefore, patterns like <code>[%a-z]</code> or <code>[a-%%]</code>
+
have no meaning.
+
</li>
+

+
<li><b><code>[^<em>set</em>]</code>: </b>
+
represents the complement of <em>set</em>,
+
where <em>set</em> is interpreted as above.
+
</li>
+

+
</ul><p>
+
For all classes represented by single letters (<code>%a</code>, <code>%c</code>, etc.),
+
the corresponding uppercase letter represents the complement of the class.
+
For instance, <code>%S</code> represents all non-space characters.
+

+

+
<p>
+
The definitions of letter, space, and other character groups
+
depend on the current locale.
+
In particular, the class <code>[a-z]</code> may not be equivalent to <code>%l</code>.
+

+

+

+

+

+
<h4>Pattern Item:</h4><p>
+
A <em>pattern item</em> can be
+

+
<ul>
+

+
<li>
+
a single character class,
+
which matches any single character in the class;
+
</li>
+

+
<li>
+
a single character class followed by '<code>*</code>',
+
which matches zero or more repetitions of characters in the class.
+
These repetition items will always match the longest possible sequence;
+
</li>
+

+
<li>
+
a single character class followed by '<code>+</code>',
+
which matches one or more repetitions of characters in the class.
+
These repetition items will always match the longest possible sequence;
+
</li>
+

+
<li>
+
a single character class followed by '<code>-</code>',
+
which also matches zero or more repetitions of characters in the class.
+
Unlike '<code>*</code>',
+
these repetition items will always match the shortest possible sequence;
+
</li>
+

+
<li>
+
a single character class followed by '<code>?</code>',
+
which matches zero or one occurrence of a character in the class.
+
It always matches one occurrence if possible;
+
</li>
+

+
<li>
+
<code>%<em>n</em></code>, for <em>n</em> between 1 and 9;
+
such item matches a substring equal to the <em>n</em>-th captured string
+
(see below);
+
</li>
+

+
<li>
+
<code>%b<em>xy</em></code>, where <em>x</em> and <em>y</em> are two distinct characters;
+
such item matches strings that start with&nbsp;<em>x</em>, end with&nbsp;<em>y</em>,
+
and where the <em>x</em> and <em>y</em> are <em>balanced</em>.
+
This means that, if one reads the string from left to right,
+
counting <em>+1</em> for an <em>x</em> and <em>-1</em> for a <em>y</em>,
+
the ending <em>y</em> is the first <em>y</em> where the count reaches 0.
+
For instance, the item <code>%b()</code> matches expressions with
+
balanced parentheses.
+
</li>
+

+
<li>
+
<code>%f[<em>set</em>]</code>, a <em>frontier pattern</em>;
+
such item matches an empty string at any position such that
+
the next character belongs to <em>set</em>
+
and the previous character does not belong to <em>set</em>.
+
The set <em>set</em> is interpreted as previously described.
+
The beginning and the end of the subject are handled as if
+
they were the character '<code>\0</code>'.
+
</li>
+

+
</ul>
+

+

+

+

+
<h4>Pattern:</h4><p>
+
A <em>pattern</em> is a sequence of pattern items.
+
A caret '<code>^</code>' at the beginning of a pattern anchors the match at the
+
beginning of the subject string.
+
A '<code>$</code>' at the end of a pattern anchors the match at the
+
end of the subject string.
+
At other positions,
+
'<code>^</code>' and '<code>$</code>' have no special meaning and represent themselves.
+

+

+

+

+

+
<h4>Captures:</h4><p>
+
A pattern can contain sub-patterns enclosed in parentheses;
+
they describe <em>captures</em>.
+
When a match succeeds, the substrings of the subject string
+
that match captures are stored (<em>captured</em>) for future use.
+
Captures are numbered according to their left parentheses.
+
For instance, in the pattern <code>"(a*(.)%w(%s*))"</code>,
+
the part of the string matching <code>"a*(.)%w(%s*)"</code> is
+
stored as the first capture (and therefore has number&nbsp;1);
+
the character matching "<code>.</code>" is captured with number&nbsp;2,
+
and the part matching "<code>%s*</code>" has number&nbsp;3.
+

+

+
<p>
+
As a special case, the empty capture <code>()</code> captures
+
the current string position (a number).
+
For instance, if we apply the pattern <code>"()aa()"</code> on the
+
string <code>"flaaap"</code>, there will be two captures: 3&nbsp;and&nbsp;5.
+

+

+

+

+

+

+

+
<h3>6.4.2 &ndash; <a name="6.4.2">Format Strings for Pack and Unpack</a></h3>
+

+
<p>
+
The first argument to <a href="#pdf-string.pack"><code>string.pack</code></a>,
+
<a href="#pdf-string.packsize"><code>string.packsize</code></a>, and <a href="#pdf-string.unpack"><code>string.unpack</code></a>
+
is a format string,
+
which describes the layout of the structure being created or read.
+

+

+
<p>
+
A format string is a sequence of conversion options.
+
The conversion options are as follows:
+

+
<ul>
+
<li><b><code>&lt;</code>: </b>sets little endian</li>
+
<li><b><code>&gt;</code>: </b>sets big endian</li>
+
<li><b><code>=</code>: </b>sets native endian</li>
+
<li><b><code>![<em>n</em>]</code>: </b>sets maximum alignment to <code>n</code>
+
(default is native alignment)</li>
+
<li><b><code>b</code>: </b>a signed byte (<code>char</code>)</li>
+
<li><b><code>B</code>: </b>an unsigned byte (<code>char</code>)</li>
+
<li><b><code>h</code>: </b>a signed <code>short</code> (native size)</li>
+
<li><b><code>H</code>: </b>an unsigned <code>short</code> (native size)</li>
+
<li><b><code>l</code>: </b>a signed <code>long</code> (native size)</li>
+
<li><b><code>L</code>: </b>an unsigned <code>long</code> (native size)</li>
+
<li><b><code>j</code>: </b>a <code>lua_Integer</code></li>
+
<li><b><code>J</code>: </b>a <code>lua_Unsigned</code></li>
+
<li><b><code>T</code>: </b>a <code>size_t</code> (native size)</li>
+
<li><b><code>i[<em>n</em>]</code>: </b>a signed <code>int</code> with <code>n</code> bytes
+
(default is native size)</li>
+
<li><b><code>I[<em>n</em>]</code>: </b>an unsigned <code>int</code> with <code>n</code> bytes
+
(default is native size)</li>
+
<li><b><code>f</code>: </b>a <code>float</code> (native size)</li>
+
<li><b><code>d</code>: </b>a <code>double</code> (native size)</li>
+
<li><b><code>n</code>: </b>a <code>lua_Number</code></li>
+
<li><b><code>c<em>n</em></code>: </b>a fixed-sized string with <code>n</code> bytes</li>
+
<li><b><code>z</code>: </b>a zero-terminated string</li>
+
<li><b><code>s[<em>n</em>]</code>: </b>a string preceded by its length
+
coded as an unsigned integer with <code>n</code> bytes
+
(default is a <code>size_t</code>)</li>
+
<li><b><code>x</code>: </b>one byte of padding</li>
+
<li><b><code>X<em>op</em></code>: </b>an empty item that aligns
+
according to option <code>op</code>
+
(which is otherwise ignored)</li>
+
<li><b>'<code> </code>': </b>(empty space) ignored</li>
+
</ul><p>
+
(A "<code>[<em>n</em>]</code>" means an optional integral numeral.)
+
Except for padding, spaces, and configurations
+
(options "<code>xX &lt;=&gt;!</code>"),
+
each option corresponds to an argument (in <a href="#pdf-string.pack"><code>string.pack</code></a>)
+
or a result (in <a href="#pdf-string.unpack"><code>string.unpack</code></a>).
+

+

+
<p>
+
For options "<code>!<em>n</em></code>", "<code>s<em>n</em></code>", "<code>i<em>n</em></code>", and "<code>I<em>n</em></code>",
+
<code>n</code> can be any integer between 1 and 16.
+
All integral options check overflows;
+
<a href="#pdf-string.pack"><code>string.pack</code></a> checks whether the given value fits in the given size;
+
<a href="#pdf-string.unpack"><code>string.unpack</code></a> checks whether the read value fits in a Lua integer.
+

+

+
<p>
+
Any format string starts as if prefixed by "<code>!1=</code>",
+
that is,
+
with maximum alignment of 1 (no alignment)
+
and native endianness.
+

+

+
<p>
+
Alignment works as follows:
+
For each option,
+
the format gets extra padding until the data starts
+
at an offset that is a multiple of the minimum between the
+
option size and the maximum alignment;
+
this minimum must be a power of 2.
+
Options "<code>c</code>" and "<code>z</code>" are not aligned;
+
option "<code>s</code>" follows the alignment of its starting integer.
+

+

+
<p>
+
All padding is filled with zeros by <a href="#pdf-string.pack"><code>string.pack</code></a>
+
(and ignored by <a href="#pdf-string.unpack"><code>string.unpack</code></a>).
+

+

+

+

+

+

+

+
<h2>6.5 &ndash; <a name="6.5">UTF-8 Support</a></h2>
+

+
<p>
+
This library provides basic support for UTF-8 encoding.
+
It provides all its functions inside the table <a name="pdf-utf8"><code>utf8</code></a>.
+
This library does not provide any support for Unicode other
+
than the handling of the encoding.
+
Any operation that needs the meaning of a character,
+
such as character classification, is outside its scope.
+

+

+
<p>
+
Unless stated otherwise,
+
all functions that expect a byte position as a parameter
+
assume that the given position is either the start of a byte sequence
+
or one plus the length of the subject string.
+
As in the string library,
+
negative indices count from the end of the string.
+

+

+
<p>
+
<hr><h3><a name="pdf-utf8.char"><code>utf8.char (&middot;&middot;&middot;)</code></a></h3>
+
Receives zero or more integers,
+
converts each one to its corresponding UTF-8 byte sequence
+
and returns a string with the concatenation of all these sequences.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-utf8.charpattern"><code>utf8.charpattern</code></a></h3>
+
The pattern (a string, not a function) "<code>[\0-\x7F\xC2-\xF4][\x80-\xBF]*</code>"
+
(see <a href="#6.4.1">&sect;6.4.1</a>),
+
which matches exactly one UTF-8 byte sequence,
+
assuming that the subject is a valid UTF-8 string.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-utf8.codes"><code>utf8.codes (s)</code></a></h3>
+

+

+
<p>
+
Returns values so that the construction
+

+
<pre>
+
     for p, c in utf8.codes(s) do <em>body</em> end
+
</pre><p>
+
will iterate over all characters in string <code>s</code>,
+
with <code>p</code> being the position (in bytes) and <code>c</code> the code point
+
of each character.
+
It raises an error if it meets any invalid byte sequence.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-utf8.codepoint"><code>utf8.codepoint (s [, i [, j]])</code></a></h3>
+
Returns the codepoints (as integers) from all characters in <code>s</code>
+
that start between byte position <code>i</code> and <code>j</code> (both included).
+
The default for <code>i</code> is 1 and for <code>j</code> is <code>i</code>.
+
It raises an error if it meets any invalid byte sequence.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-utf8.len"><code>utf8.len (s [, i [, j]])</code></a></h3>
+
Returns the number of UTF-8 characters in string <code>s</code>
+
that start between positions <code>i</code> and <code>j</code> (both inclusive).
+
The default for <code>i</code> is 1 and for <code>j</code> is -1.
+
If it finds any invalid byte sequence,
+
returns a false value plus the position of the first invalid byte.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-utf8.offset"><code>utf8.offset (s, n [, i])</code></a></h3>
+
Returns the position (in bytes) where the encoding of the
+
<code>n</code>-th character of <code>s</code>
+
(counting from position <code>i</code>) starts.
+
A negative <code>n</code> gets characters before position <code>i</code>.
+
The default for <code>i</code> is 1 when <code>n</code> is non-negative
+
and <code>#s + 1</code> otherwise,
+
so that <code>utf8.offset(s, -n)</code> gets the offset of the
+
<code>n</code>-th character from the end of the string.
+
If the specified character is neither in the subject
+
nor right after its end,
+
the function returns <b>nil</b>.
+

+

+
<p>
+
As a special case,
+
when <code>n</code> is 0 the function returns the start of the encoding
+
of the character that contains the <code>i</code>-th byte of <code>s</code>.
+

+

+
<p>
+
This function assumes that <code>s</code> is a valid UTF-8 string.
+

+

+

+

+

+

+

+
<h2>6.6 &ndash; <a name="6.6">Table Manipulation</a></h2>
+

+
<p>
+
This library provides generic functions for table manipulation.
+
It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>.
+

+

+
<p>
+
Remember that, whenever an operation needs the length of a table,
+
all caveats about the length operator apply (see <a href="#3.4.7">&sect;3.4.7</a>).
+
All functions ignore non-numeric keys
+
in the tables given as arguments.
+

+

+
<p>
+
<hr><h3><a name="pdf-table.concat"><code>table.concat (list [, sep [, i [, j]]])</code></a></h3>
+

+

+
<p>
+
Given a list where all elements are strings or numbers,
+
returns the string <code>list[i]..sep..list[i+1] &middot;&middot;&middot; sep..list[j]</code>.
+
The default value for <code>sep</code> is the empty string,
+
the default for <code>i</code> is 1,
+
and the default for <code>j</code> is <code>#list</code>.
+
If <code>i</code> is greater than <code>j</code>, returns the empty string.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-table.insert"><code>table.insert (list, [pos,] value)</code></a></h3>
+

+

+
<p>
+
Inserts element <code>value</code> at position <code>pos</code> in <code>list</code>,
+
shifting up the elements
+
<code>list[pos], list[pos+1], &middot;&middot;&middot;, list[#list]</code>.
+
The default value for <code>pos</code> is <code>#list+1</code>,
+
so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end
+
of list <code>t</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-table.move"><code>table.move (a1, f, e, t [,a2])</code></a></h3>
+

+

+
<p>
+
Moves elements from table <code>a1</code> to table <code>a2</code>,
+
performing the equivalent to the following
+
multiple assignment:
+
<code>a2[t],&middot;&middot;&middot; = a1[f],&middot;&middot;&middot;,a1[e]</code>.
+
The default for <code>a2</code> is <code>a1</code>.
+
The destination range can overlap with the source range.
+
The number of elements to be moved must fit in a Lua integer.
+

+

+
<p>
+
Returns the destination table <code>a2</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-table.pack"><code>table.pack (&middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Returns a new table with all arguments stored into keys 1, 2, etc.
+
and with a field "<code>n</code>" with the total number of arguments.
+
Note that the resulting table may not be a sequence.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-table.remove"><code>table.remove (list [, pos])</code></a></h3>
+

+

+
<p>
+
Removes from <code>list</code> the element at position <code>pos</code>,
+
returning the value of the removed element.
+
When <code>pos</code> is an integer between 1 and <code>#list</code>,
+
it shifts down the elements
+
<code>list[pos+1], list[pos+2], &middot;&middot;&middot;, list[#list]</code>
+
and erases element <code>list[#list]</code>;
+
The index <code>pos</code> can also be 0 when <code>#list</code> is 0,
+
or <code>#list + 1</code>;
+
in those cases, the function erases the element <code>list[pos]</code>.
+

+

+
<p>
+
The default value for <code>pos</code> is <code>#list</code>,
+
so that a call <code>table.remove(l)</code> removes the last element
+
of list <code>l</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-table.sort"><code>table.sort (list [, comp])</code></a></h3>
+

+

+
<p>
+
Sorts list elements in a given order, <em>in-place</em>,
+
from <code>list[1]</code> to <code>list[#list]</code>.
+
If <code>comp</code> is given,
+
then it must be a function that receives two list elements
+
and returns true when the first element must come
+
before the second in the final order
+
(so that, after the sort,
+
<code>i &lt; j</code> implies <code>not comp(list[j],list[i])</code>).
+
If <code>comp</code> is not given,
+
then the standard Lua operator <code>&lt;</code> is used instead.
+

+

+
<p>
+
Note that the <code>comp</code> function must define
+
a strict partial order over the elements in the list;
+
that is, it must be asymmetric and transitive.
+
Otherwise, no valid sort may be possible.
+

+

+
<p>
+
The sort algorithm is not stable:
+
elements considered equal by the given order
+
may have their relative positions changed by the sort.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-table.unpack"><code>table.unpack (list [, i [, j]])</code></a></h3>
+

+

+
<p>
+
Returns the elements from the given list.
+
This function is equivalent to
+

+
<pre>
+
     return list[i], list[i+1], &middot;&middot;&middot;, list[j]
+
</pre><p>
+
By default, <code>i</code> is&nbsp;1 and <code>j</code> is <code>#list</code>.
+

+

+

+

+

+

+

+
<h2>6.7 &ndash; <a name="6.7">Mathematical Functions</a></h2>
+

+
<p>
+
This library provides basic mathematical functions.
+
It provides all its functions and constants inside the table <a name="pdf-math"><code>math</code></a>.
+
Functions with the annotation "<code>integer/float</code>" give
+
integer results for integer arguments
+
and float results for float (or mixed) arguments.
+
Rounding functions
+
(<a href="#pdf-math.ceil"><code>math.ceil</code></a>, <a href="#pdf-math.floor"><code>math.floor</code></a>, and <a href="#pdf-math.modf"><code>math.modf</code></a>)
+
return an integer when the result fits in the range of an integer,
+
or a float otherwise.
+

+

+
<p>
+
<hr><h3><a name="pdf-math.abs"><code>math.abs (x)</code></a></h3>
+

+

+
<p>
+
Returns the absolute value of <code>x</code>. (integer/float)
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.acos"><code>math.acos (x)</code></a></h3>
+

+

+
<p>
+
Returns the arc cosine of <code>x</code> (in radians).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.asin"><code>math.asin (x)</code></a></h3>
+

+

+
<p>
+
Returns the arc sine of <code>x</code> (in radians).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.atan"><code>math.atan (y [, x])</code></a></h3>
+

+

+
<p>
+

+
Returns the arc tangent of <code>y/x</code> (in radians),
+
but uses the signs of both arguments to find the
+
quadrant of the result.
+
(It also handles correctly the case of <code>x</code> being zero.)
+

+

+
<p>
+
The default value for <code>x</code> is 1,
+
so that the call <code>math.atan(y)</code>
+
returns the arc tangent of <code>y</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.ceil"><code>math.ceil (x)</code></a></h3>
+

+

+
<p>
+
Returns the smallest integral value larger than or equal to <code>x</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.cos"><code>math.cos (x)</code></a></h3>
+

+

+
<p>
+
Returns the cosine of <code>x</code> (assumed to be in radians).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.deg"><code>math.deg (x)</code></a></h3>
+

+

+
<p>
+
Converts the angle <code>x</code> from radians to degrees.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.exp"><code>math.exp (x)</code></a></h3>
+

+

+
<p>
+
Returns the value <em>e<sup>x</sup></em>
+
(where <code>e</code> is the base of natural logarithms).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.floor"><code>math.floor (x)</code></a></h3>
+

+

+
<p>
+
Returns the largest integral value smaller than or equal to <code>x</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.fmod"><code>math.fmod (x, y)</code></a></h3>
+

+

+
<p>
+
Returns the remainder of the division of <code>x</code> by <code>y</code>
+
that rounds the quotient towards zero. (integer/float)
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.huge"><code>math.huge</code></a></h3>
+

+

+
<p>
+
The float value <code>HUGE_VAL</code>,
+
a value larger than any other numeric value.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.log"><code>math.log (x [, base])</code></a></h3>
+

+

+
<p>
+
Returns the logarithm of <code>x</code> in the given base.
+
The default for <code>base</code> is <em>e</em>
+
(so that the function returns the natural logarithm of <code>x</code>).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.max"><code>math.max (x, &middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Returns the argument with the maximum value,
+
according to the Lua operator <code>&lt;</code>. (integer/float)
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.maxinteger"><code>math.maxinteger</code></a></h3>
+
An integer with the maximum value for an integer.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.min"><code>math.min (x, &middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Returns the argument with the minimum value,
+
according to the Lua operator <code>&lt;</code>. (integer/float)
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.mininteger"><code>math.mininteger</code></a></h3>
+
An integer with the minimum value for an integer.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.modf"><code>math.modf (x)</code></a></h3>
+

+

+
<p>
+
Returns the integral part of <code>x</code> and the fractional part of <code>x</code>.
+
Its second result is always a float.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.pi"><code>math.pi</code></a></h3>
+

+

+
<p>
+
The value of <em>&pi;</em>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.rad"><code>math.rad (x)</code></a></h3>
+

+

+
<p>
+
Converts the angle <code>x</code> from degrees to radians.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.random"><code>math.random ([m [, n]])</code></a></h3>
+

+

+
<p>
+
When called without arguments,
+
returns a pseudo-random float with uniform distribution
+
in the range  <em>[0,1)</em>.  
+
When called with two integers <code>m</code> and <code>n</code>,
+
<code>math.random</code> returns a pseudo-random integer
+
with uniform distribution in the range <em>[m, n]</em>.
+
(The value <em>n-m</em> cannot be negative and must fit in a Lua integer.)
+
The call <code>math.random(n)</code> is equivalent to <code>math.random(1,n)</code>.
+

+

+
<p>
+
This function is an interface to the underling
+
pseudo-random generator function provided by C.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.randomseed"><code>math.randomseed (x)</code></a></h3>
+

+

+
<p>
+
Sets <code>x</code> as the "seed"
+
for the pseudo-random generator:
+
equal seeds produce equal sequences of numbers.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.sin"><code>math.sin (x)</code></a></h3>
+

+

+
<p>
+
Returns the sine of <code>x</code> (assumed to be in radians).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.sqrt"><code>math.sqrt (x)</code></a></h3>
+

+

+
<p>
+
Returns the square root of <code>x</code>.
+
(You can also use the expression <code>x^0.5</code> to compute this value.)
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.tan"><code>math.tan (x)</code></a></h3>
+

+

+
<p>
+
Returns the tangent of <code>x</code> (assumed to be in radians).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.tointeger"><code>math.tointeger (x)</code></a></h3>
+

+

+
<p>
+
If the value <code>x</code> is convertible to an integer,
+
returns that integer.
+
Otherwise, returns <b>nil</b>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.type"><code>math.type (x)</code></a></h3>
+

+

+
<p>
+
Returns "<code>integer</code>" if <code>x</code> is an integer,
+
"<code>float</code>" if it is a float,
+
or <b>nil</b> if <code>x</code> is not a number.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-math.ult"><code>math.ult (m, n)</code></a></h3>
+

+

+
<p>
+
Returns a boolean,
+
true if and only if integer <code>m</code> is below integer <code>n</code> when
+
they are compared as unsigned integers.
+

+

+

+

+

+

+

+
<h2>6.8 &ndash; <a name="6.8">Input and Output Facilities</a></h2>
+

+
<p>
+
The I/O library provides two different styles for file manipulation.
+
The first one uses implicit file handles;
+
that is, there are operations to set a default input file and a
+
default output file,
+
and all input/output operations are over these default files.
+
The second style uses explicit file handles.
+

+

+
<p>
+
When using implicit file handles,
+
all operations are supplied by table <a name="pdf-io"><code>io</code></a>.
+
When using explicit file handles,
+
the operation <a href="#pdf-io.open"><code>io.open</code></a> returns a file handle
+
and then all operations are supplied as methods of the file handle.
+

+

+
<p>
+
The table <code>io</code> also provides
+
three predefined file handles with their usual meanings from C:
+
<a name="pdf-io.stdin"><code>io.stdin</code></a>, <a name="pdf-io.stdout"><code>io.stdout</code></a>, and <a name="pdf-io.stderr"><code>io.stderr</code></a>.
+
The I/O library never closes these files.
+

+

+
<p>
+
Unless otherwise stated,
+
all I/O functions return <b>nil</b> on failure
+
(plus an error message as a second result and
+
a system-dependent error code as a third result)
+
and some value different from <b>nil</b> on success.
+
In non-POSIX systems,
+
the computation of the error message and error code
+
in case of errors
+
may be not thread safe,
+
because they rely on the global C variable <code>errno</code>.
+

+

+
<p>
+
<hr><h3><a name="pdf-io.close"><code>io.close ([file])</code></a></h3>
+

+

+
<p>
+
Equivalent to <code>file:close()</code>.
+
Without a <code>file</code>, closes the default output file.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.flush"><code>io.flush ()</code></a></h3>
+

+

+
<p>
+
Equivalent to <code>io.output():flush()</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.input"><code>io.input ([file])</code></a></h3>
+

+

+
<p>
+
When called with a file name, it opens the named file (in text mode),
+
and sets its handle as the default input file.
+
When called with a file handle,
+
it simply sets this file handle as the default input file.
+
When called without arguments,
+
it returns the current default input file.
+

+

+
<p>
+
In case of errors this function raises the error,
+
instead of returning an error code.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.lines"><code>io.lines ([filename, &middot;&middot;&middot;])</code></a></h3>
+

+

+
<p>
+
Opens the given file name in read mode
+
and returns an iterator function that
+
works like <code>file:lines(&middot;&middot;&middot;)</code> over the opened file.
+
When the iterator function detects the end of file,
+
it returns no values (to finish the loop) and automatically closes the file.
+

+

+
<p>
+
The call <code>io.lines()</code> (with no file name) is equivalent
+
to <code>io.input():lines("*l")</code>;
+
that is, it iterates over the lines of the default input file.
+
In this case, the iterator does not close the file when the loop ends.
+

+

+
<p>
+
In case of errors this function raises the error,
+
instead of returning an error code.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.open"><code>io.open (filename [, mode])</code></a></h3>
+

+

+
<p>
+
This function opens a file,
+
in the mode specified in the string <code>mode</code>.
+
In case of success,
+
it returns a new file handle.
+

+

+
<p>
+
The <code>mode</code> string can be any of the following:
+

+
<ul>
+
<li><b>"<code>r</code>": </b> read mode (the default);</li>
+
<li><b>"<code>w</code>": </b> write mode;</li>
+
<li><b>"<code>a</code>": </b> append mode;</li>
+
<li><b>"<code>r+</code>": </b> update mode, all previous data is preserved;</li>
+
<li><b>"<code>w+</code>": </b> update mode, all previous data is erased;</li>
+
<li><b>"<code>a+</code>": </b> append update mode, previous data is preserved,
+
  writing is only allowed at the end of file.</li>
+
</ul><p>
+
The <code>mode</code> string can also have a '<code>b</code>' at the end,
+
which is needed in some systems to open the file in binary mode.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.output"><code>io.output ([file])</code></a></h3>
+

+

+
<p>
+
Similar to <a href="#pdf-io.input"><code>io.input</code></a>, but operates over the default output file.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.popen"><code>io.popen (prog [, mode])</code></a></h3>
+

+

+
<p>
+
This function is system dependent and is not available
+
on all platforms.
+

+

+
<p>
+
Starts program <code>prog</code> in a separated process and returns
+
a file handle that you can use to read data from this program
+
(if <code>mode</code> is <code>"r"</code>, the default)
+
or to write data to this program
+
(if <code>mode</code> is <code>"w"</code>).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.read"><code>io.read (&middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Equivalent to <code>io.input():read(&middot;&middot;&middot;)</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.tmpfile"><code>io.tmpfile ()</code></a></h3>
+

+

+
<p>
+
In case of success,
+
returns a handle for a temporary file.
+
This file is opened in update mode
+
and it is automatically removed when the program ends.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.type"><code>io.type (obj)</code></a></h3>
+

+

+
<p>
+
Checks whether <code>obj</code> is a valid file handle.
+
Returns the string <code>"file"</code> if <code>obj</code> is an open file handle,
+
<code>"closed file"</code> if <code>obj</code> is a closed file handle,
+
or <b>nil</b> if <code>obj</code> is not a file handle.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-io.write"><code>io.write (&middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Equivalent to <code>io.output():write(&middot;&middot;&middot;)</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-file:close"><code>file:close ()</code></a></h3>
+

+

+
<p>
+
Closes <code>file</code>.
+
Note that files are automatically closed when
+
their handles are garbage collected,
+
but that takes an unpredictable amount of time to happen.
+

+

+
<p>
+
When closing a file handle created with <a href="#pdf-io.popen"><code>io.popen</code></a>,
+
<a href="#pdf-file:close"><code>file:close</code></a> returns the same values
+
returned by <a href="#pdf-os.execute"><code>os.execute</code></a>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-file:flush"><code>file:flush ()</code></a></h3>
+

+

+
<p>
+
Saves any written data to <code>file</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-file:lines"><code>file:lines (&middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Returns an iterator function that,
+
each time it is called,
+
reads the file according to the given formats.
+
When no format is given,
+
uses "<code>l</code>" as a default.
+
As an example, the construction
+

+
<pre>
+
     for c in file:lines(1) do <em>body</em> end
+
</pre><p>
+
will iterate over all characters of the file,
+
starting at the current position.
+
Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file
+
when the loop ends.
+

+

+
<p>
+
In case of errors this function raises the error,
+
instead of returning an error code.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-file:read"><code>file:read (&middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Reads the file <code>file</code>,
+
according to the given formats, which specify what to read.
+
For each format,
+
the function returns a string or a number with the characters read,
+
or <b>nil</b> if it cannot read data with the specified format.
+
(In this latter case,
+
the function does not read subsequent formats.)
+
When called without formats,
+
it uses a default format that reads the next line
+
(see below).
+

+

+
<p>
+
The available formats are
+

+
<ul>
+

+
<li><b>"<code>n</code>": </b>
+
reads a numeral and returns it as a float or an integer,
+
following the lexical conventions of Lua.
+
(The numeral may have leading spaces and a sign.)
+
This format always reads the longest input sequence that
+
is a valid prefix for a numeral;
+
if that prefix does not form a valid numeral
+
(e.g., an empty string, "<code>0x</code>", or "<code>3.4e-</code>"),
+
it is discarded and the function returns <b>nil</b>.
+
</li>
+

+
<li><b>"<code>a</code>": </b>
+
reads the whole file, starting at the current position.
+
On end of file, it returns the empty string.
+
</li>
+

+
<li><b>"<code>l</code>": </b>
+
reads the next line skipping the end of line,
+
returning <b>nil</b> on end of file.
+
This is the default format.
+
</li>
+

+
<li><b>"<code>L</code>": </b>
+
reads the next line keeping the end-of-line character (if present),
+
returning <b>nil</b> on end of file.
+
</li>
+

+
<li><b><em>number</em>: </b>
+
reads a string with up to this number of bytes,
+
returning <b>nil</b> on end of file.
+
If <code>number</code> is zero,
+
it reads nothing and returns an empty string,
+
or <b>nil</b> on end of file.
+
</li>
+

+
</ul><p>
+
The formats "<code>l</code>" and "<code>L</code>" should be used only for text files.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-file:seek"><code>file:seek ([whence [, offset]])</code></a></h3>
+

+

+
<p>
+
Sets and gets the file position,
+
measured from the beginning of the file,
+
to the position given by <code>offset</code> plus a base
+
specified by the string <code>whence</code>, as follows:
+

+
<ul>
+
<li><b>"<code>set</code>": </b> base is position 0 (beginning of the file);</li>
+
<li><b>"<code>cur</code>": </b> base is current position;</li>
+
<li><b>"<code>end</code>": </b> base is end of file;</li>
+
</ul><p>
+
In case of success, <code>seek</code> returns the final file position,
+
measured in bytes from the beginning of the file.
+
If <code>seek</code> fails, it returns <b>nil</b>,
+
plus a string describing the error.
+

+

+
<p>
+
The default value for <code>whence</code> is <code>"cur"</code>,
+
and for <code>offset</code> is 0.
+
Therefore, the call <code>file:seek()</code> returns the current
+
file position, without changing it;
+
the call <code>file:seek("set")</code> sets the position to the
+
beginning of the file (and returns 0);
+
and the call <code>file:seek("end")</code> sets the position to the
+
end of the file, and returns its size.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-file:setvbuf"><code>file:setvbuf (mode [, size])</code></a></h3>
+

+

+
<p>
+
Sets the buffering mode for an output file.
+
There are three available modes:
+

+
<ul>
+

+
<li><b>"<code>no</code>": </b>
+
no buffering; the result of any output operation appears immediately.
+
</li>
+

+
<li><b>"<code>full</code>": </b>
+
full buffering; output operation is performed only
+
when the buffer is full or when
+
you explicitly <code>flush</code> the file (see <a href="#pdf-io.flush"><code>io.flush</code></a>).
+
</li>
+

+
<li><b>"<code>line</code>": </b>
+
line buffering; output is buffered until a newline is output
+
or there is any input from some special files
+
(such as a terminal device).
+
</li>
+

+
</ul><p>
+
For the last two cases, <code>size</code>
+
specifies the size of the buffer, in bytes.
+
The default is an appropriate size.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-file:write"><code>file:write (&middot;&middot;&middot;)</code></a></h3>
+

+

+
<p>
+
Writes the value of each of its arguments to <code>file</code>.
+
The arguments must be strings or numbers.
+

+

+
<p>
+
In case of success, this function returns <code>file</code>.
+
Otherwise it returns <b>nil</b> plus a string describing the error.
+

+

+

+

+

+

+

+
<h2>6.9 &ndash; <a name="6.9">Operating System Facilities</a></h2>
+

+
<p>
+
This library is implemented through table <a name="pdf-os"><code>os</code></a>.
+

+

+
<p>
+
<hr><h3><a name="pdf-os.clock"><code>os.clock ()</code></a></h3>
+

+

+
<p>
+
Returns an approximation of the amount in seconds of CPU time
+
used by the program.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.date"><code>os.date ([format [, time]])</code></a></h3>
+

+

+
<p>
+
Returns a string or a table containing date and time,
+
formatted according to the given string <code>format</code>.
+

+

+
<p>
+
If the <code>time</code> argument is present,
+
this is the time to be formatted
+
(see the <a href="#pdf-os.time"><code>os.time</code></a> function for a description of this value).
+
Otherwise, <code>date</code> formats the current time.
+

+

+
<p>
+
If <code>format</code> starts with '<code>!</code>',
+
then the date is formatted in Coordinated Universal Time.
+
After this optional character,
+
if <code>format</code> is the string "<code>*t</code>",
+
then <code>date</code> returns a table with the following fields:
+
<code>year</code>, <code>month</code> (1&ndash;12), <code>day</code> (1&ndash;31),
+
<code>hour</code> (0&ndash;23), <code>min</code> (0&ndash;59), <code>sec</code> (0&ndash;61),
+
<code>wday</code> (weekday, 1&ndash;7, Sunday is&nbsp;1),
+
<code>yday</code> (day of the year, 1&ndash;366),
+
and <code>isdst</code> (daylight saving flag, a boolean).
+
This last field may be absent
+
if the information is not available.
+

+

+
<p>
+
If <code>format</code> is not "<code>*t</code>",
+
then <code>date</code> returns the date as a string,
+
formatted according to the same rules as the ISO&nbsp;C function <code>strftime</code>.
+

+

+
<p>
+
When called without arguments,
+
<code>date</code> returns a reasonable date and time representation that depends on
+
the host system and on the current locale.
+
(More specifically, <code>os.date()</code> is equivalent to <code>os.date("%c")</code>.)
+

+

+
<p>
+
In non-POSIX systems,
+
this function may be not thread safe
+
because of its reliance on C&nbsp;function <code>gmtime</code> and C&nbsp;function <code>localtime</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.difftime"><code>os.difftime (t2, t1)</code></a></h3>
+

+

+
<p>
+
Returns the difference, in seconds,
+
from time <code>t1</code> to time <code>t2</code>
+
(where the times are values returned by <a href="#pdf-os.time"><code>os.time</code></a>).
+
In POSIX, Windows, and some other systems,
+
this value is exactly <code>t2</code><em>-</em><code>t1</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.execute"><code>os.execute ([command])</code></a></h3>
+

+

+
<p>
+
This function is equivalent to the ISO&nbsp;C function <code>system</code>.
+
It passes <code>command</code> to be executed by an operating system shell.
+
Its first result is <b>true</b>
+
if the command terminated successfully,
+
or <b>nil</b> otherwise.
+
After this first result
+
the function returns a string plus a number,
+
as follows:
+

+
<ul>
+

+
<li><b>"<code>exit</code>": </b>
+
the command terminated normally;
+
the following number is the exit status of the command.
+
</li>
+

+
<li><b>"<code>signal</code>": </b>
+
the command was terminated by a signal;
+
the following number is the signal that terminated the command.
+
</li>
+

+
</ul>
+

+
<p>
+
When called without a <code>command</code>,
+
<code>os.execute</code> returns a boolean that is true if a shell is available.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.exit"><code>os.exit ([code [, close]])</code></a></h3>
+

+

+
<p>
+
Calls the ISO&nbsp;C function <code>exit</code> to terminate the host program.
+
If <code>code</code> is <b>true</b>,
+
the returned status is <code>EXIT_SUCCESS</code>;
+
if <code>code</code> is <b>false</b>,
+
the returned status is <code>EXIT_FAILURE</code>;
+
if <code>code</code> is a number,
+
the returned status is this number.
+
The default value for <code>code</code> is <b>true</b>.
+

+

+
<p>
+
If the optional second argument <code>close</code> is true,
+
closes the Lua state before exiting.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.getenv"><code>os.getenv (varname)</code></a></h3>
+

+

+
<p>
+
Returns the value of the process environment variable <code>varname</code>,
+
or <b>nil</b> if the variable is not defined.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.remove"><code>os.remove (filename)</code></a></h3>
+

+

+
<p>
+
Deletes the file (or empty directory, on POSIX systems)
+
with the given name.
+
If this function fails, it returns <b>nil</b>,
+
plus a string describing the error and the error code.
+
Otherwise, it returns true.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.rename"><code>os.rename (oldname, newname)</code></a></h3>
+

+

+
<p>
+
Renames the file or directory named <code>oldname</code> to <code>newname</code>.
+
If this function fails, it returns <b>nil</b>,
+
plus a string describing the error and the error code.
+
Otherwise, it returns true.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.setlocale"><code>os.setlocale (locale [, category])</code></a></h3>
+

+

+
<p>
+
Sets the current locale of the program.
+
<code>locale</code> is a system-dependent string specifying a locale;
+
<code>category</code> is an optional string describing which category to change:
+
<code>"all"</code>, <code>"collate"</code>, <code>"ctype"</code>,
+
<code>"monetary"</code>, <code>"numeric"</code>, or <code>"time"</code>;
+
the default category is <code>"all"</code>.
+
The function returns the name of the new locale,
+
or <b>nil</b> if the request cannot be honored.
+

+

+
<p>
+
If <code>locale</code> is the empty string,
+
the current locale is set to an implementation-defined native locale.
+
If <code>locale</code> is the string "<code>C</code>",
+
the current locale is set to the standard C locale.
+

+

+
<p>
+
When called with <b>nil</b> as the first argument,
+
this function only returns the name of the current locale
+
for the given category.
+

+

+
<p>
+
This function may be not thread safe
+
because of its reliance on C&nbsp;function <code>setlocale</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.time"><code>os.time ([table])</code></a></h3>
+

+

+
<p>
+
Returns the current time when called without arguments,
+
or a time representing the local date and time specified by the given table.
+
This table must have fields <code>year</code>, <code>month</code>, and <code>day</code>,
+
and may have fields
+
<code>hour</code> (default is 12),
+
<code>min</code> (default is 0),
+
<code>sec</code> (default is 0),
+
and <code>isdst</code> (default is <b>nil</b>).
+
Other fields are ignored.
+
For a description of these fields, see the <a href="#pdf-os.date"><code>os.date</code></a> function.
+

+

+
<p>
+
The values in these fields do not need to be inside their valid ranges.
+
For instance, if <code>sec</code> is -10,
+
it means -10 seconds from the time specified by the other fields;
+
if <code>hour</code> is 1000,
+
it means +1000 hours from the time specified by the other fields.
+

+

+
<p>
+
The returned value is a number, whose meaning depends on your system.
+
In POSIX, Windows, and some other systems,
+
this number counts the number
+
of seconds since some given start time (the "epoch").
+
In other systems, the meaning is not specified,
+
and the number returned by <code>time</code> can be used only as an argument to
+
<a href="#pdf-os.date"><code>os.date</code></a> and <a href="#pdf-os.difftime"><code>os.difftime</code></a>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-os.tmpname"><code>os.tmpname ()</code></a></h3>
+

+

+
<p>
+
Returns a string with a file name that can
+
be used for a temporary file.
+
The file must be explicitly opened before its use
+
and explicitly removed when no longer needed.
+

+

+
<p>
+
In POSIX systems,
+
this function also creates a file with that name,
+
to avoid security risks.
+
(Someone else might create the file with wrong permissions
+
in the time between getting the name and creating the file.)
+
You still have to open the file to use it
+
and to remove it (even if you do not use it).
+

+

+
<p>
+
When possible,
+
you may prefer to use <a href="#pdf-io.tmpfile"><code>io.tmpfile</code></a>,
+
which automatically removes the file when the program ends.
+

+

+

+

+

+

+

+
<h2>6.10 &ndash; <a name="6.10">The Debug Library</a></h2>
+

+
<p>
+
This library provides
+
the functionality of the debug interface (<a href="#4.9">&sect;4.9</a>) to Lua programs.
+
You should exert care when using this library.
+
Several of its functions
+
violate basic assumptions about Lua code
+
(e.g., that variables local to a function
+
cannot be accessed from outside;
+
that userdata metatables cannot be changed by Lua code;
+
that Lua programs do not crash)
+
and therefore can compromise otherwise secure code.
+
Moreover, some functions in this library may be slow.
+

+

+
<p>
+
All functions in this library are provided
+
inside the <a name="pdf-debug"><code>debug</code></a> table.
+
All functions that operate over a thread
+
have an optional first argument which is the
+
thread to operate over.
+
The default is always the current thread.
+

+

+
<p>
+
<hr><h3><a name="pdf-debug.debug"><code>debug.debug ()</code></a></h3>
+

+

+
<p>
+
Enters an interactive mode with the user,
+
running each string that the user enters.
+
Using simple commands and other debug facilities,
+
the user can inspect global and local variables,
+
change their values, evaluate expressions, and so on.
+
A line containing only the word <code>cont</code> finishes this function,
+
so that the caller continues its execution.
+

+

+
<p>
+
Note that commands for <code>debug.debug</code> are not lexically nested
+
within any function and so have no direct access to local variables.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.gethook"><code>debug.gethook ([thread])</code></a></h3>
+

+

+
<p>
+
Returns the current hook settings of the thread, as three values:
+
the current hook function, the current hook mask,
+
and the current hook count
+
(as set by the <a href="#pdf-debug.sethook"><code>debug.sethook</code></a> function).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.getinfo"><code>debug.getinfo ([thread,] f [, what])</code></a></h3>
+

+

+
<p>
+
Returns a table with information about a function.
+
You can give the function directly
+
or you can give a number as the value of <code>f</code>,
+
which means the function running at level <code>f</code> of the call stack
+
of the given thread:
+
level&nbsp;0 is the current function (<code>getinfo</code> itself);
+
level&nbsp;1 is the function that called <code>getinfo</code>
+
(except for tail calls, which do not count on the stack);
+
and so on.
+
If <code>f</code> is a number larger than the number of active functions,
+
then <code>getinfo</code> returns <b>nil</b>.
+

+

+
<p>
+
The returned table can contain all the fields returned by <a href="#lua_getinfo"><code>lua_getinfo</code></a>,
+
with the string <code>what</code> describing which fields to fill in.
+
The default for <code>what</code> is to get all information available,
+
except the table of valid lines.
+
If present,
+
the option '<code>f</code>'
+
adds a field named <code>func</code> with the function itself.
+
If present,
+
the option '<code>L</code>'
+
adds a field named <code>activelines</code> with the table of
+
valid lines.
+

+

+
<p>
+
For instance, the expression <code>debug.getinfo(1,"n").name</code> returns
+
a name for the current function,
+
if a reasonable name can be found,
+
and the expression <code>debug.getinfo(print)</code>
+
returns a table with all available information
+
about the <a href="#pdf-print"><code>print</code></a> function.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.getlocal"><code>debug.getlocal ([thread,] f, local)</code></a></h3>
+

+

+
<p>
+
This function returns the name and the value of the local variable
+
with index <code>local</code> of the function at level <code>f</code> of the stack.
+
This function accesses not only explicit local variables,
+
but also parameters, temporaries, etc.
+

+

+
<p>
+
The first parameter or local variable has index&nbsp;1, and so on,
+
following the order that they are declared in the code,
+
counting only the variables that are active
+
in the current scope of the function.
+
Negative indices refer to vararg arguments;
+
-1 is the first vararg argument.
+
The function returns <b>nil</b> if there is no variable with the given index,
+
and raises an error when called with a level out of range.
+
(You can call <a href="#pdf-debug.getinfo"><code>debug.getinfo</code></a> to check whether the level is valid.)
+

+

+
<p>
+
Variable names starting with '<code>(</code>' (open parenthesis) 
+
represent variables with no known names
+
(internal variables such as loop control variables,
+
and variables from chunks saved without debug information).
+

+

+
<p>
+
The parameter <code>f</code> may also be a function.
+
In that case, <code>getlocal</code> returns only the name of function parameters.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.getmetatable"><code>debug.getmetatable (value)</code></a></h3>
+

+

+
<p>
+
Returns the metatable of the given <code>value</code>
+
or <b>nil</b> if it does not have a metatable.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.getregistry"><code>debug.getregistry ()</code></a></h3>
+

+

+
<p>
+
Returns the registry table (see <a href="#4.5">&sect;4.5</a>).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.getupvalue"><code>debug.getupvalue (f, up)</code></a></h3>
+

+

+
<p>
+
This function returns the name and the value of the upvalue
+
with index <code>up</code> of the function <code>f</code>.
+
The function returns <b>nil</b> if there is no upvalue with the given index.
+

+

+
<p>
+
Variable names starting with '<code>(</code>' (open parenthesis) 
+
represent variables with no known names
+
(variables from chunks saved without debug information).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.getuservalue"><code>debug.getuservalue (u)</code></a></h3>
+

+

+
<p>
+
Returns the Lua value associated to <code>u</code>.
+
If <code>u</code> is not a full userdata,
+
returns <b>nil</b>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.sethook"><code>debug.sethook ([thread,] hook, mask [, count])</code></a></h3>
+

+

+
<p>
+
Sets the given function as a hook.
+
The string <code>mask</code> and the number <code>count</code> describe
+
when the hook will be called.
+
The string mask may have any combination of the following characters,
+
with the given meaning:
+

+
<ul>
+
<li><b>'<code>c</code>': </b> the hook is called every time Lua calls a function;</li>
+
<li><b>'<code>r</code>': </b> the hook is called every time Lua returns from a function;</li>
+
<li><b>'<code>l</code>': </b> the hook is called every time Lua enters a new line of code.</li>
+
</ul><p>
+
Moreover,
+
with a <code>count</code> different from zero,
+
the hook is called also after every <code>count</code> instructions.
+

+

+
<p>
+
When called without arguments,
+
<a href="#pdf-debug.sethook"><code>debug.sethook</code></a> turns off the hook.
+

+

+
<p>
+
When the hook is called, its first argument is a string
+
describing the event that has triggered its call:
+
<code>"call"</code> (or <code>"tail call"</code>),
+
<code>"return"</code>,
+
<code>"line"</code>, and <code>"count"</code>.
+
For line events,
+
the hook also gets the new line number as its second parameter.
+
Inside a hook,
+
you can call <code>getinfo</code> with level&nbsp;2 to get more information about
+
the running function
+
(level&nbsp;0 is the <code>getinfo</code> function,
+
and level&nbsp;1 is the hook function).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.setlocal"><code>debug.setlocal ([thread,] level, local, value)</code></a></h3>
+

+

+
<p>
+
This function assigns the value <code>value</code> to the local variable
+
with index <code>local</code> of the function at level <code>level</code> of the stack.
+
The function returns <b>nil</b> if there is no local
+
variable with the given index,
+
and raises an error when called with a <code>level</code> out of range.
+
(You can call <code>getinfo</code> to check whether the level is valid.)
+
Otherwise, it returns the name of the local variable.
+

+

+
<p>
+
See <a href="#pdf-debug.getlocal"><code>debug.getlocal</code></a> for more information about
+
variable indices and names.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.setmetatable"><code>debug.setmetatable (value, table)</code></a></h3>
+

+

+
<p>
+
Sets the metatable for the given <code>value</code> to the given <code>table</code>
+
(which can be <b>nil</b>).
+
Returns <code>value</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.setupvalue"><code>debug.setupvalue (f, up, value)</code></a></h3>
+

+

+
<p>
+
This function assigns the value <code>value</code> to the upvalue
+
with index <code>up</code> of the function <code>f</code>.
+
The function returns <b>nil</b> if there is no upvalue
+
with the given index.
+
Otherwise, it returns the name of the upvalue.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.setuservalue"><code>debug.setuservalue (udata, value)</code></a></h3>
+

+

+
<p>
+
Sets the given <code>value</code> as
+
the Lua value associated to the given <code>udata</code>.
+
<code>udata</code> must be a full userdata.
+

+

+
<p>
+
Returns <code>udata</code>.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.traceback"><code>debug.traceback ([thread,] [message [, level]])</code></a></h3>
+

+

+
<p>
+
If <code>message</code> is present but is neither a string nor <b>nil</b>,
+
this function returns <code>message</code> without further processing.
+
Otherwise,
+
it returns a string with a traceback of the call stack.
+
The optional <code>message</code> string is appended
+
at the beginning of the traceback.
+
An optional <code>level</code> number tells at which level
+
to start the traceback
+
(default is 1, the function calling <code>traceback</code>).
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.upvalueid"><code>debug.upvalueid (f, n)</code></a></h3>
+

+

+
<p>
+
Returns a unique identifier (as a light userdata)
+
for the upvalue numbered <code>n</code>
+
from the given function.
+

+

+
<p>
+
These unique identifiers allow a program to check whether different
+
closures share upvalues.
+
Lua closures that share an upvalue
+
(that is, that access a same external local variable)
+
will return identical ids for those upvalue indices.
+

+

+

+

+
<p>
+
<hr><h3><a name="pdf-debug.upvaluejoin"><code>debug.upvaluejoin (f1, n1, f2, n2)</code></a></h3>
+

+

+
<p>
+
Make the <code>n1</code>-th upvalue of the Lua closure <code>f1</code>
+
refer to the <code>n2</code>-th upvalue of the Lua closure <code>f2</code>.
+

+

+

+

+

+

+

+
<h1>7 &ndash; <a name="7">Lua Standalone</a></h1>
+

+
<p>
+
Although Lua has been designed as an extension language,
+
to be embedded in a host C&nbsp;program,
+
it is also frequently used as a standalone language.
+
An interpreter for Lua as a standalone language,
+
called simply <code>lua</code>,
+
is provided with the standard distribution.
+
The standalone interpreter includes
+
all standard libraries, including the debug library.
+
Its usage is:
+

+
<pre>
+
     lua [options] [script [args]]
+
</pre><p>
+
The options are:
+

+
<ul>
+
<li><b><code>-e <em>stat</em></code>: </b> executes string <em>stat</em>;</li>
+
<li><b><code>-l <em>mod</em></code>: </b> "requires" <em>mod</em> and assigns the
+
  result to global @<em>mod</em>;</li>
+
<li><b><code>-i</code>: </b> enters interactive mode after running <em>script</em>;</li>
+
<li><b><code>-v</code>: </b> prints version information;</li>
+
<li><b><code>-E</code>: </b> ignores environment variables;</li>
+
<li><b><code>--</code>: </b> stops handling options;</li>
+
<li><b><code>-</code>: </b> executes <code>stdin</code> as a file and stops handling options.</li>
+
</ul><p>
+
After handling its options, <code>lua</code> runs the given <em>script</em>.
+
When called without arguments,
+
<code>lua</code> behaves as <code>lua -v -i</code>
+
when the standard input (<code>stdin</code>) is a terminal,
+
and as <code>lua -</code> otherwise.
+

+

+
<p>
+
When called without option <code>-E</code>,
+
the interpreter checks for an environment variable <a name="pdf-LUA_INIT_5_3"><code>LUA_INIT_5_3</code></a>
+
(or <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a> if the versioned name is not defined)
+
before running any argument.
+
If the variable content has the format <code>@<em>filename</em></code>,
+
then <code>lua</code> executes the file.
+
Otherwise, <code>lua</code> executes the string itself.
+

+

+
<p>
+
When called with option <code>-E</code>,
+
besides ignoring <code>LUA_INIT</code>,
+
Lua also ignores
+
the values of <code>LUA_PATH</code> and <code>LUA_CPATH</code>,
+
setting the values of
+
<a href="#pdf-package.path"><code>package.path</code></a> and <a href="#pdf-package.cpath"><code>package.cpath</code></a>
+
with the default paths defined in <code>luaconf.h</code>.
+

+

+
<p>
+
All options are handled in order, except <code>-i</code> and <code>-E</code>.
+
For instance, an invocation like
+

+
<pre>
+
     $ lua -e'a=1' -e 'print(a)' script.lua
+
</pre><p>
+
will first set <code>a</code> to 1, then print the value of <code>a</code>,
+
and finally run the file <code>script.lua</code> with no arguments.
+
(Here <code>$</code> is the shell prompt. Your prompt may be different.)
+

+

+
<p>
+
Before running any code,
+
<code>lua</code> collects all command-line arguments
+
in a global table called <code>arg</code>.
+
The script name goes to index 0,
+
the first argument after the script name goes to index 1,
+
and so on.
+
Any arguments before the script name
+
(that is, the interpreter name plus its options)
+
go to negative indices.
+
For instance, in the call
+

+
<pre>
+
     $ lua -la b.lua t1 t2
+
</pre><p>
+
the table is like this:
+

+
<pre>
+
     arg = { [-2] = "lua", [-1] = "-la",
+
             [0] = "b.lua",
+
             [1] = "t1", [2] = "t2" }
+
</pre><p>
+
If there is no script in the call,
+
the interpreter name goes to index 0,
+
followed by the other arguments.
+
For instance, the call
+

+
<pre>
+
     $ lua -e "print(arg[1])"
+
</pre><p>
+
will print "<code>-e</code>".
+
If there is a script,
+
the script is called with arguments
+
<code>arg[1]</code>, &middot;&middot;&middot;, <code>arg[#arg]</code>.
+
(Like all chunks in Lua,
+
the script is compiled as a vararg function.)
+

+

+
<p>
+
In interactive mode,
+
Lua repeatedly prompts and waits for a line.
+
After reading a line,
+
Lua first try to interpret the line as an expression.
+
If it succeeds, it prints its value.
+
Otherwise, it interprets the line as a statement.
+
If you write an incomplete statement,
+
the interpreter waits for its completion
+
by issuing a different prompt.
+

+

+
<p>
+
If the global variable <a name="pdf-_PROMPT"><code>_PROMPT</code></a> contains a string,
+
then its value is used as the prompt.
+
Similarly, if the global variable <a name="pdf-_PROMPT2"><code>_PROMPT2</code></a> contains a string,
+
its value is used as the secondary prompt
+
(issued during incomplete statements).
+

+

+
<p>
+
In case of unprotected errors in the script,
+
the interpreter reports the error to the standard error stream.
+
If the error object is not a string but
+
has a metamethod <code>__tostring</code>,
+
the interpreter calls this metamethod to produce the final message.
+
Otherwise, the interpreter converts the error object to a string
+
and adds a stack traceback to it.
+

+

+
<p>
+
When finishing normally,
+
the interpreter closes its main Lua state
+
(see <a href="#lua_close"><code>lua_close</code></a>).
+
The script can avoid this step by
+
calling <a href="#pdf-os.exit"><code>os.exit</code></a> to terminate.
+

+

+
<p>
+
To allow the use of Lua as a
+
script interpreter in Unix systems,
+
the standalone interpreter skips
+
the first line of a chunk if it starts with <code>#</code>.
+
Therefore, Lua scripts can be made into executable programs
+
by using <code>chmod +x</code> and the&nbsp;<code>#!</code> form,
+
as in
+

+
<pre>
+
     #!/usr/local/bin/lua
+
</pre><p>
+
(Of course,
+
the location of the Lua interpreter may be different in your machine.
+
If <code>lua</code> is in your <code>PATH</code>,
+
then
+

+
<pre>
+
     #!/usr/bin/env lua
+
</pre><p>
+
is a more portable solution.)
+

+

+

+
<h1>8 &ndash; <a name="8">Incompatibilities with the Previous Version</a></h1>
+

+
<p>
+
Here we list the incompatibilities that you may find when moving a program
+
from Lua&nbsp;5.2 to Lua&nbsp;5.3.
+
You can avoid some incompatibilities by compiling Lua with
+
appropriate options (see file <code>luaconf.h</code>).
+
However,
+
all these compatibility options will be removed in the future.
+

+

+
<p>
+
Lua versions can always change the C API in ways that
+
do not imply source-code changes in a program,
+
such as the numeric values for constants
+
or the implementation of functions as macros.
+
Therefore,
+
you should not assume that binaries are compatible between
+
different Lua versions.
+
Always recompile clients of the Lua API when
+
using a new version.
+

+

+
<p>
+
Similarly, Lua versions can always change the internal representation
+
of precompiled chunks;
+
precompiled chunks are not compatible between different Lua versions.
+

+

+
<p>
+
The standard paths in the official distribution may
+
change between versions.
+

+

+

+
<h2>8.1 &ndash; <a name="8.1">Changes in the Language</a></h2>
+
<ul>
+

+
<li>
+
The main difference between Lua&nbsp;5.2 and Lua&nbsp;5.3 is the
+
introduction of an integer subtype for numbers.
+
Although this change should not affect "normal" computations,
+
some computations
+
(mainly those that involve some kind of overflow)
+
can give different results.
+

+

+
<p>
+
You can fix these differences by forcing a number to be a float
+
(in Lua&nbsp;5.2 all numbers were float),
+
in particular writing constants with an ending <code>.0</code>
+
or using <code>x = x + 0.0</code> to convert a variable.
+
(This recommendation is only for a quick fix
+
for an occasional incompatibility;
+
it is not a general guideline for good programming.
+
For good programming,
+
use floats where you need floats
+
and integers where you need integers.)
+
</li>
+

+
<li>
+
The conversion of a float to a string now adds a <code>.0</code> suffix
+
to the result if it looks like an integer.
+
(For instance, the float 2.0 will be printed as <code>2.0</code>,
+
not as <code>2</code>.)
+
You should always use an explicit format
+
when you need a specific format for numbers.
+

+

+
<p>
+
(Formally this is not an incompatibility,
+
because Lua does not specify how numbers are formatted as strings,
+
but some programs assumed a specific format.)
+
</li>
+

+
<li>
+
The generational mode for the garbage collector was removed.
+
(It was an experimental feature in Lua&nbsp;5.2.)
+
</li>
+

+
</ul>
+

+

+

+

+
<h2>8.2 &ndash; <a name="8.2">Changes in the Libraries</a></h2>
+
<ul>
+

+
<li>
+
The <code>bit32</code> library has been deprecated.
+
It is easy to require a compatible external library or,
+
better yet, to replace its functions with appropriate bitwise operations.
+
(Keep in mind that <code>bit32</code> operates on 32-bit integers,
+
while the bitwise operators in Lua&nbsp;5.3 operate on Lua integers,
+
which by default have 64&nbsp;bits.)
+
</li>
+

+
<li>
+
The Table library now respects metamethods
+
for setting and getting elements.
+
</li>
+

+
<li>
+
The <a href="#pdf-ipairs"><code>ipairs</code></a> iterator now respects metamethods and
+
its <code>__ipairs</code> metamethod has been deprecated.
+
</li>
+

+
<li>
+
Option names in <a href="#pdf-io.read"><code>io.read</code></a> do not have a starting '<code>*</code>' anymore.
+
For compatibility, Lua will continue to accept (and ignore) this character.
+
</li>
+

+
<li>
+
The following functions were deprecated in the mathematical library:
+
<code>atan2</code>, <code>cosh</code>, <code>sinh</code>, <code>tanh</code>, <code>pow</code>,
+
<code>frexp</code>, and <code>ldexp</code>.
+
You can replace <code>math.pow(x,y)</code> with <code>x^y</code>;
+
you can replace <code>math.atan2</code> with <code>math.atan</code>,
+
which now accepts one or two arguments;
+
you can replace <code>math.ldexp(x,exp)</code> with <code>x * 2.0^exp</code>.
+
For the other operations,
+
you can either use an external library or
+
implement them in Lua.
+
</li>
+

+
<li>
+
The searcher for C loaders used by <a href="#pdf-require"><code>require</code></a>
+
changed the way it handles versioned names.
+
Now, the version should come after the module name
+
(as is usual in most other tools).
+
For compatibility, that searcher still tries the old format
+
if it cannot find an open function according to the new style.
+
(Lua&nbsp;5.2 already worked that way,
+
but it did not document the change.)
+
</li>
+

+
<li>
+
The call <code>collectgarbage("count")</code> now returns only one result.
+
(You can compute that second result from the fractional part
+
of the first result.)
+
</li>
+

+
</ul>
+

+

+

+

+
<h2>8.3 &ndash; <a name="8.3">Changes in the API</a></h2>
+

+

+
<ul>
+

+
<li>
+
Continuation functions now receive as arguments what they needed
+
to get through <code>lua_getctx</code>,
+
so <code>lua_getctx</code> has been removed.
+
Adapt your code accordingly.
+
</li>
+

+
<li>
+
Function <a href="#lua_dump"><code>lua_dump</code></a> has an extra parameter, <code>strip</code>.
+
Use 0 as the value of this parameter to get the old behavior.
+
</li>
+

+
<li>
+
Functions to inject/project unsigned integers
+
(<code>lua_pushunsigned</code>, <code>lua_tounsigned</code>, <code>lua_tounsignedx</code>,
+
<code>luaL_checkunsigned</code>, <code>luaL_optunsigned</code>)
+
were deprecated.
+
Use their signed equivalents with a type cast.
+
</li>
+

+
<li>
+
Macros to project non-default integer types
+
(<code>luaL_checkint</code>, <code>luaL_optint</code>, <code>luaL_checklong</code>, <code>luaL_optlong</code>)
+
were deprecated.
+
Use their equivalent over <a href="#lua_Integer"><code>lua_Integer</code></a> with a type cast
+
(or, when possible, use <a href="#lua_Integer"><code>lua_Integer</code></a> in your code).
+
</li>
+

+
</ul>
+

+

+

+

+
<h1>9 &ndash; <a name="9">The Complete Syntax of Lua</a></h1>
+

+
<p>
+
Here is the complete syntax of Lua in extended BNF.
+
As usual in extended BNF,
+
{A} means 0 or more As,
+
and [A] means an optional A.
+
(For operator precedences, see <a href="#3.4.8">&sect;3.4.8</a>;
+
for a description of the terminals
+
Name, Numeral,
+
and LiteralString, see <a href="#3.1">&sect;3.1</a>.)
+

+

+

+

+
<pre>
+

+
	chunk ::= block
+

+
	block ::= {stat} [retstat]
+

+
	stat ::=  &lsquo;<b>;</b>&rsquo; | 
+
		 varlist &lsquo;<b>=</b>&rsquo; explist | 
+
		 functioncall | 
+
		 label | 
+
		 <b>break</b> | 
+
		 <b>goto</b> Name | 
+
		 <b>do</b> block <b>end</b> | 
+
		 <b>while</b> exp <b>do</b> block <b>end</b> | 
+
		 <b>repeat</b> block <b>until</b> exp | 
+
		 <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> | 
+
		 <b>for</b> Name &lsquo;<b>=</b>&rsquo; exp &lsquo;<b>,</b>&rsquo; exp [&lsquo;<b>,</b>&rsquo; exp] <b>do</b> block <b>end</b> | 
+
		 <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> | 
+
		 <b>function</b> funcname funcbody | 
+
		 <b>local</b> <b>function</b> Name funcbody | 
+
		 <b>local</b> namelist [&lsquo;<b>=</b>&rsquo; explist] 
+

+
	retstat ::= <b>return</b> [explist] [&lsquo;<b>;</b>&rsquo;]
+

+
	label ::= &lsquo;<b>::</b>&rsquo; Name &lsquo;<b>::</b>&rsquo;
+

+
	funcname ::= Name {&lsquo;<b>.</b>&rsquo; Name} [&lsquo;<b>:</b>&rsquo; Name]
+

+
	varlist ::= var {&lsquo;<b>,</b>&rsquo; var}
+

+
	var ::=  Name | prefixexp &lsquo;<b>[</b>&rsquo; exp &lsquo;<b>]</b>&rsquo; | prefixexp &lsquo;<b>.</b>&rsquo; Name 
+

+
	namelist ::= Name {&lsquo;<b>,</b>&rsquo; Name}
+

+
	explist ::= exp {&lsquo;<b>,</b>&rsquo; exp}
+

+
	exp ::=  <b>nil</b> | <b>false</b> | <b>true</b> | Numeral | LiteralString | &lsquo;<b>...</b>&rsquo; | functiondef | 
+
		 prefixexp | tableconstructor | exp binop exp | unop exp 
+

+
	prefixexp ::= var | functioncall | &lsquo;<b>(</b>&rsquo; exp &lsquo;<b>)</b>&rsquo;
+

+
	functioncall ::=  prefixexp args | prefixexp &lsquo;<b>:</b>&rsquo; Name args 
+

+
	args ::=  &lsquo;<b>(</b>&rsquo; [explist] &lsquo;<b>)</b>&rsquo; | tableconstructor | LiteralString 
+

+
	functiondef ::= <b>function</b> funcbody
+

+
	funcbody ::= &lsquo;<b>(</b>&rsquo; [parlist] &lsquo;<b>)</b>&rsquo; block <b>end</b>
+

+
	parlist ::= namelist [&lsquo;<b>,</b>&rsquo; &lsquo;<b>...</b>&rsquo;] | &lsquo;<b>...</b>&rsquo;
+

+
	tableconstructor ::= &lsquo;<b>{</b>&rsquo; [fieldlist] &lsquo;<b>}</b>&rsquo;
+

+
	fieldlist ::= field {fieldsep field} [fieldsep]
+

+
	field ::= &lsquo;<b>[</b>&rsquo; exp &lsquo;<b>]</b>&rsquo; &lsquo;<b>=</b>&rsquo; exp | Name &lsquo;<b>=</b>&rsquo; exp | exp
+

+
	fieldsep ::= &lsquo;<b>,</b>&rsquo; | &lsquo;<b>;</b>&rsquo;
+

+
	binop ::=  &lsquo;<b>+</b>&rsquo; | &lsquo;<b>-</b>&rsquo; | &lsquo;<b>*</b>&rsquo; | &lsquo;<b>/</b>&rsquo; | &lsquo;<b>//</b>&rsquo; | &lsquo;<b>^</b>&rsquo; | &lsquo;<b>%</b>&rsquo; | 
+
		 &lsquo;<b>&amp;</b>&rsquo; | &lsquo;<b>~</b>&rsquo; | &lsquo;<b>|</b>&rsquo; | &lsquo;<b>&gt;&gt;</b>&rsquo; | &lsquo;<b>&lt;&lt;</b>&rsquo; | &lsquo;<b>..</b>&rsquo; | 
+
		 &lsquo;<b>&lt;</b>&rsquo; | &lsquo;<b>&lt;=</b>&rsquo; | &lsquo;<b>&gt;</b>&rsquo; | &lsquo;<b>&gt;=</b>&rsquo; | &lsquo;<b>==</b>&rsquo; | &lsquo;<b>~=</b>&rsquo; | 
+
		 <b>and</b> | <b>or</b>
+

+
	unop ::= &lsquo;<b>-</b>&rsquo; | <b>not</b> | &lsquo;<b>#</b>&rsquo; | &lsquo;<b>~</b>&rsquo;
+

+
</pre>
+

+
<p>
+

+

+

+

+

+

+

+

+
<P CLASS="footer">
+
Last update:
+
Tue Jun 26 13:16:37 -03 2018
+
</P>
+
<!--
+
Last change: revised for Lua 5.3.5
+
-->
+

+
</body></html>
+

added external/lua/doc/osi-certified-72x60.png
added external/lua/doc/readme.html
@@ -0,0 +1,365 @@
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
<HTML>
+
<HEAD>
+
<TITLE>Lua 5.3 readme</TITLE>
+
<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
+
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
+
<STYLE TYPE="text/css">
+
blockquote, .display {
+
	border: solid #a0a0a0 2px ;
+
	border-radius: 8px ;
+
	padding: 1em ;
+
	margin: 0px ;
+
}
+

+
.display {
+
	word-spacing: 0.25em ;
+
}
+

+
dl.display dd {
+
	padding-bottom: 0.2em ;
+
}
+

+
tt, kbd, code {
+
	font-size: 12pt ;
+
}
+
</STYLE>
+
</HEAD>
+

+
<BODY>
+

+
<H1>
+
<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
+
Welcome to Lua 5.3
+
</H1>
+

+
<DIV CLASS="menubar">
+
<A HREF="#about">about</A>
+
&middot;
+
<A HREF="#install">installation</A>
+
&middot;
+
<A HREF="#changes">changes</A>
+
&middot;
+
<A HREF="#license">license</A>
+
&middot;
+
<A HREF="contents.html">reference manual</A>
+
</DIV>
+

+
<H2><A NAME="about">About Lua</A></H2>
+
<P>
+
Lua is a powerful, fast, lightweight, embeddable scripting language
+
developed by a
+
<A HREF="http://www.lua.org/authors.html">team</A>
+
at
+
<A HREF="http://www.puc-rio.br/">PUC-Rio</A>,
+
the Pontifical Catholic University of Rio de Janeiro in Brazil.
+
Lua is
+
<A HREF="#license">free software</A>
+
used in many products and projects around the world.
+

+
<P>
+
Lua's
+
<A HREF="http://www.lua.org/">official web site</A>
+
provides complete information
+
about Lua,
+
including
+
an
+
<A HREF="http://www.lua.org/about.html">executive summary</A>
+
and
+
updated
+
<A HREF="http://www.lua.org/docs.html">documentation</A>,
+
especially the
+
<A HREF="http://www.lua.org/manual/5.3/">reference manual</A>,
+
which may differ slightly from the
+
<A HREF="contents.html">local copy</A>
+
distributed in this package.
+

+
<H2><A NAME="install">Installing Lua</A></H2>
+
<P>
+
Lua is distributed in
+
<A HREF="http://www.lua.org/ftp/">source</A>
+
form.
+
You need to build it before using it.
+
Building Lua should be straightforward
+
because
+
Lua is implemented in pure ANSI C and compiles unmodified in all known
+
platforms that have an ANSI C compiler.
+
Lua also compiles unmodified as C++.
+
The instructions given below for building Lua are for Unix-like platforms.
+
See also
+
<A HREF="#other">instructions for other systems</A>
+
and
+
<A HREF="#customization">customization options</A>.
+

+
<P>
+
If you don't have the time or the inclination to compile Lua yourself,
+
get a binary from
+
<A HREF="http://lua-users.org/wiki/LuaBinaries">LuaBinaries</A>.
+
Try also
+
<A HREF="http://luadist.org/">LuaDist</A>,
+
a multi-platform distribution of Lua that includes batteries.
+

+
<H3>Building Lua</H3>
+
<P>
+
In most Unix-like platforms, simply do "<KBD>make</KBD>" with a suitable target.
+
Here are the details.
+

+
<OL>
+
<LI>
+
Open a terminal window and move to
+
the top-level directory, which is named <TT>lua-5.3.5</TT>.
+
The <TT>Makefile</TT> there controls both the build process and the installation process.
+
<P>
+
<LI>
+
  Do "<KBD>make</KBD>" and see if your platform is listed.
+
  The platforms currently supported are:
+
<P>
+
<P CLASS="display">
+
   aix bsd c89 freebsd generic linux macosx mingw posix solaris
+
</P>
+
<P>
+
  If your platform is listed, just do "<KBD>make xxx</KBD>", where xxx
+
  is your platform name.
+
<P>
+
  If your platform is not listed, try the closest one or posix, generic,
+
  c89, in this order.
+
<P>
+
<LI>
+
The compilation takes only a few moments
+
and produces three files in the <TT>src</TT> directory:
+
lua (the interpreter),
+
luac (the compiler),
+
and liblua.a (the library).
+
<P>
+
<LI>
+
  To check that Lua has been built correctly, do "<KBD>make test</KBD>"
+
  after building Lua. This will run the interpreter and print its version.
+
</OL>
+
<P>
+
If you're running Linux and get compilation errors,
+
make sure you have installed the <TT>readline</TT> development package
+
(which is probably named <TT>libreadline-dev</TT> or <TT>readline-devel</TT>).
+
If you get link errors after that,
+
then try "<KBD>make linux MYLIBS=-ltermcap</KBD>".
+

+
<H3>Installing Lua</H3>
+
<P>
+
  Once you have built Lua, you may want to install it in an official
+
  place in your system. In this case, do "<KBD>make install</KBD>". The official
+
  place and the way to install files are defined in the <TT>Makefile</TT>. You'll
+
  probably need the right permissions to install files.
+

+
<P>
+
  To build and install Lua in one step, do "<KBD>make xxx install</KBD>",
+
  where xxx is your platform name.
+

+
<P>
+
  To install Lua locally, do "<KBD>make local</KBD>".
+
  This will create a directory <TT>install</TT> with subdirectories
+
  <TT>bin</TT>, <TT>include</TT>, <TT>lib</TT>, <TT>man</TT>, <TT>share</TT>,
+
  and install Lua as listed below.
+

+
  To install Lua locally, but in some other directory, do
+
  "<KBD>make install INSTALL_TOP=xxx</KBD>", where xxx is your chosen directory.
+
  The installation starts in the <TT>src</TT> and <TT>doc</TT> directories,
+
  so take care if <TT>INSTALL_TOP</TT> is not an absolute path.
+

+
<DL CLASS="display">
+
<DT>
+
    bin:
+
<DD>
+
    lua luac
+
<DT>
+
    include:
+
<DD>
+
    lua.h luaconf.h lualib.h lauxlib.h lua.hpp
+
<DT>
+
    lib:
+
<DD>
+
    liblua.a
+
<DT>
+
    man/man1:
+
<DD>
+
    lua.1 luac.1
+
</DL>
+

+
<P>
+
  These are the only directories you need for development.
+
  If you only want to run Lua programs,
+
  you only need the files in <TT>bin</TT> and <TT>man</TT>.
+
  The files in <TT>include</TT> and <TT>lib</TT> are needed for
+
  embedding Lua in C or C++ programs.
+

+
<H3><A NAME="customization">Customization</A></H3>
+
<P>
+
  Three kinds of things can be customized by editing a file:
+
<UL>
+
    <LI> Where and how to install Lua &mdash; edit <TT>Makefile</TT>.
+
    <LI> How to build Lua &mdash; edit <TT>src/Makefile</TT>.
+
    <LI> Lua features &mdash; edit <TT>src/luaconf.h</TT>.
+
</UL>
+

+
<P>
+
  You don't actually need to edit the Makefiles because you may set the
+
  relevant variables in the command line when invoking make.
+
  Nevertheless, it's probably best to edit and save the Makefiles to
+
  record the changes you've made.
+

+
<P>
+
  On the other hand, if you need to customize some Lua features, you'll need
+
  to edit <TT>src/luaconf.h</TT> before building and installing Lua.
+
  The edited file will be the one installed, and
+
  it will be used by any Lua clients that you build, to ensure consistency.
+
  Further customization is available to experts by editing the Lua sources.
+

+
<H3><A NAME="other">Building Lua on other systems</A></H3>
+
<P>
+
  If you're not using the usual Unix tools, then the instructions for
+
  building Lua depend on the compiler you use. You'll need to create
+
  projects (or whatever your compiler uses) for building the library,
+
  the interpreter, and the compiler, as follows:
+

+
<DL CLASS="display">
+
<DT>
+
library:
+
<DD>
+
lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c
+
lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c
+
ltm.c lundump.c lvm.c lzio.c
+
lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c
+
lmathlib.c loslib.c lstrlib.c ltablib.c lutf8lib.c loadlib.c linit.c
+
<DT>
+
interpreter:
+
<DD>
+
  library, lua.c
+
<DT>
+
compiler:
+
<DD>
+
  library, luac.c
+
</DL>
+

+
<P>
+
  To use Lua as a library in your own programs you'll need to know how to
+
  create and use libraries with your compiler. Moreover, to dynamically load
+
  C libraries for Lua you'll need to know how to create dynamic libraries
+
  and you'll need to make sure that the Lua API functions are accessible to
+
  those dynamic libraries &mdash; but <EM>don't</EM> link the Lua library
+
  into each dynamic library. For Unix, we recommend that the Lua library
+
  be linked statically into the host program and its symbols exported for
+
  dynamic linking; <TT>src/Makefile</TT> does this for the Lua interpreter.
+
  For Windows, we recommend that the Lua library be a DLL.
+
  In all cases, the compiler luac should be linked statically.
+

+
<P>
+
  As mentioned above, you may edit <TT>src/luaconf.h</TT> to customize
+
  some features before building Lua.
+

+
<H2><A NAME="changes">Changes since Lua 5.2</A></H2>
+
<P>
+
Here are the main changes introduced in Lua 5.3.
+
The
+
<A HREF="contents.html">reference manual</A>
+
lists the
+
<A HREF="manual.html#8">incompatibilities</A> that had to be introduced.
+

+
<H3>Main changes</H3>
+
<UL>
+
<LI> integers (64-bit by default)
+
<LI> official support for 32-bit numbers
+
<LI> bitwise operators
+
<LI> basic utf-8 support
+
<LI> functions for packing and unpacking values
+

+
</UL>
+

+
Here are the other changes introduced in Lua 5.3:
+
<H3>Language</H3>
+
<UL>
+
<LI> userdata can have any Lua value as uservalue
+
<LI> floor division
+
<LI> more flexible rules for some metamethods
+
</UL>
+

+
<H3>Libraries</H3>
+
<UL>
+
<LI> <CODE>ipairs</CODE> and the table library respect metamethods
+
<LI> strip option in <CODE>string.dump</CODE>
+
<LI> table library respects metamethods
+
<LI> new function <CODE>table.move</CODE>
+
<LI> new function <CODE>string.pack</CODE>
+
<LI> new function <CODE>string.unpack</CODE>
+
<LI> new function <CODE>string.packsize</CODE>
+
</UL>
+

+
<H3>C API</H3>
+
<UL>
+
<LI> simpler API for continuation functions in C
+
<LI> <CODE>lua_gettable</CODE> and similar functions return type of resulted value
+
<LI> strip option in <CODE>lua_dump</CODE>
+
<LI> new function: <CODE>lua_geti</CODE>
+
<LI> new function: <CODE>lua_seti</CODE>
+
<LI> new function: <CODE>lua_isyieldable</CODE>
+
<LI> new function: <CODE>lua_numbertointeger</CODE>
+
<LI> new function: <CODE>lua_rotate</CODE>
+
<LI> new function: <CODE>lua_stringtonumber</CODE>
+
</UL>
+

+
<H3>Lua standalone interpreter</H3>
+
<UL>
+
<LI> can be used as calculator; no need to prefix with '='
+
<LI> <CODE>arg</CODE> table available to all code
+
</UL>
+

+
<H2><A NAME="license">License</A></H2>
+
<P>
+
<A HREF="http://www.opensource.org/docs/definition.php">
+
<IMG SRC="osi-certified-72x60.png" ALIGN="right" ALT="[osi certified]" STYLE="padding-left: 30px ;">
+
</A>
+
Lua is free software distributed under the terms of the
+
<A HREF="http://www.opensource.org/licenses/mit-license.html">MIT license</A>
+
reproduced below;
+
it may be used for any purpose, including commercial purposes,
+
at absolutely no cost without having to ask us.
+

+
The only requirement is that if you do use Lua,
+
then you should give us credit by including the appropriate copyright notice somewhere in your product or its documentation.
+

+
For details, see
+
<A HREF="http://www.lua.org/license.html">this</A>.
+

+
<BLOCKQUOTE STYLE="padding-bottom: 0em">
+
Copyright &copy; 1994&ndash;2017 Lua.org, PUC-Rio.
+

+
<P>
+
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:
+

+
<P>
+
The above copyright notice and this permission notice shall be included in
+
all copies or substantial portions of the Software.
+

+
<P>
+
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.
+
</BLOCKQUOTE>
+
<P>
+

+
<P CLASS="footer">
+
Last update:
+
Mon Jun 18 22:57:33 -03 2018
+
</P>
+
<!--
+
Last change: revised for Lua 5.3.5
+
-->
+

+
</BODY>
+
</HTML>
added external/lua/src/Makefile
@@ -0,0 +1,197 @@
+
# Makefile for building Lua
+
# See ../doc/readme.html for installation and customization instructions.
+

+
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
+

+
# Your platform. See PLATS for possible values.
+
PLAT= none
+

+
CC= gcc -std=gnu99
+
CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS)
+
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
+
LIBS= -lm $(SYSLIBS) $(MYLIBS)
+

+
AR= ar rcu
+
RANLIB= ranlib
+
RM= rm -f
+

+
SYSCFLAGS=
+
SYSLDFLAGS=
+
SYSLIBS=
+

+
MYCFLAGS=
+
MYLDFLAGS=
+
MYLIBS=
+
MYOBJS=
+

+
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
+

+
PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
+

+
LUA_A=	liblua.a
+
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
+

+
ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
+
ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
+
ALL_A= $(LUA_A)
+

+
# Targets start here.
+
default: $(PLAT)
+

+
all:	$(ALL_T)
+

+
o:	$(ALL_O)
+

+
a:	$(ALL_A)
+

+
$(LUA_A): $(BASE_O)
+
	$(AR) $@ $(BASE_O)
+
	$(RANLIB) $@
+

+
$(LUA_T): $(LUA_O) $(LUA_A)
+
	$(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
+

+
$(LUAC_T): $(LUAC_O) $(LUA_A)
+
	$(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
+

+
clean:
+
	$(RM) $(ALL_T) $(ALL_O)
+

+
depend:
+
	@$(CC) $(CFLAGS) -MM l*.c
+

+
echo:
+
	@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 do 'make PLATFORM' where PLATFORM is one of these:"
+
	@echo "   $(PLATS)"
+

+
aix:
+
	$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
+

+
bsd:
+
	$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
+

+
c89:
+
	$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89"
+
	@echo ''
+
	@echo '*** C89 does not guarantee 64-bit integers for Lua.'
+
	@echo ''
+

+

+
freebsd:
+
	$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE -I/usr/include/edit" SYSLIBS="-Wl,-E -ledit" CC="cc"
+

+
generic: $(ALL)
+

+
linux:
+
	$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
+

+
macosx:
+
	$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
+

+
mingw:
+
	$(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \
+
	"AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
+
	"SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
+
	$(MAKE) "LUAC_T=luac.exe" luac.exe
+

+
posix:
+
	$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
+

+
solaris:
+
	$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -D_REENTRANT" SYSLIBS="-ldl"
+

+
# list targets that do not create files (but not all makes understand .PHONY)
+
.PHONY: all $(PLATS) default o a clean depend echo none
+

+
# DO NOT DELETE
+

+
lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
+
 lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
+
 ltable.h lundump.h lvm.h
+
lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
+
lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
+
 llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
+
 ldo.h lgc.h lstring.h ltable.h lvm.h
+
lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h
+
ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
+
 lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
+
 ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
+
ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
+
 lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
+
 lparser.h lstring.h ltable.h lundump.h lvm.h
+
ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
+
 ltm.h lzio.h lmem.h lundump.h
+
lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
+
 lgc.h lstate.h ltm.h lzio.h lmem.h
+
lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
+
 llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
+
linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
+
liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
+
 lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \
+
 lstring.h ltable.h
+
lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
+
 llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
+
loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
+
 ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
+
 lvm.h
+
lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h
+
loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
+
 llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
+
 ldo.h lfunc.h lstring.h lgc.h ltable.h
+
lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
+
 lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
+
 lstring.h ltable.h
+
lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
+
 lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
+
lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
+
 llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
+
ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
+
 llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
+
lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \
+
 lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
+
lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
+
 lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
+
 lundump.h
+
lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
+
 llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
+
 ltable.h lvm.h
+
lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
+
 lobject.h ltm.h lzio.h
+

+
# (end of Makefile)
added external/lua/src/lapi.c
@@ -0,0 +1,1299 @@
+
/*
+
** $Id: lapi.c,v 2.259.1.2 2017/12/06 18:35:12 roberto Exp $
+
** Lua API
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lapi_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <stdarg.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lapi.h"
+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lfunc.h"
+
#include "lgc.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "ltm.h"
+
#include "lundump.h"
+
#include "lvm.h"
+

+

+

+
const char lua_ident[] =
+
  "$LuaVersion: " LUA_COPYRIGHT " $"
+
  "$LuaAuthors: " LUA_AUTHORS " $";
+

+

+
/* value at a non-valid index */
+
#define NONVALIDVALUE		cast(TValue *, luaO_nilobject)
+

+
/* corresponding test */
+
#define isvalid(o)	((o) != luaO_nilobject)
+

+
/* test for pseudo index */
+
#define ispseudo(i)		((i) <= LUA_REGISTRYINDEX)
+

+
/* test for upvalue */
+
#define isupvalue(i)		((i) < LUA_REGISTRYINDEX)
+

+
/* test for valid but not pseudo index */
+
#define isstackindex(i, o)	(isvalid(o) && !ispseudo(i))
+

+
#define api_checkvalidindex(l,o)  api_check(l, isvalid(o), "invalid index")
+

+
#define api_checkstackindex(l, i, o)  \
+
	api_check(l, isstackindex(i, o), "index not in the stack")
+

+

+
static TValue *index2addr (lua_State *L, int idx) {
+
  CallInfo *ci = L->ci;
+
  if (idx > 0) {
+
    TValue *o = ci->func + idx;
+
    api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
+
    if (o >= L->top) return NONVALIDVALUE;
+
    else return o;
+
  }
+
  else if (!ispseudo(idx)) {  /* negative index */
+
    api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
+
    return L->top + idx;
+
  }
+
  else if (idx == LUA_REGISTRYINDEX)
+
    return &G(L)->l_registry;
+
  else {  /* upvalues */
+
    idx = LUA_REGISTRYINDEX - idx;
+
    api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
+
    if (ttislcf(ci->func))  /* light C function? */
+
      return NONVALIDVALUE;  /* it has no upvalues */
+
    else {
+
      CClosure *func = clCvalue(ci->func);
+
      return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
+
    }
+
  }
+
}
+

+

+
/*
+
** to be called by 'lua_checkstack' in protected mode, to grow stack
+
** capturing memory errors
+
*/
+
static void growstack (lua_State *L, void *ud) {
+
  int size = *(int *)ud;
+
  luaD_growstack(L, size);
+
}
+

+

+
LUA_API int lua_checkstack (lua_State *L, int n) {
+
  int res;
+
  CallInfo *ci = L->ci;
+
  lua_lock(L);
+
  api_check(L, n >= 0, "negative 'n'");
+
  if (L->stack_last - L->top > n)  /* stack large enough? */
+
    res = 1;  /* yes; check is OK */
+
  else {  /* no; need to grow stack */
+
    int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
+
    if (inuse > LUAI_MAXSTACK - n)  /* can grow without overflow? */
+
      res = 0;  /* no */
+
    else  /* try to grow stack */
+
      res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK);
+
  }
+
  if (res && ci->top < L->top + n)
+
    ci->top = L->top + n;  /* adjust frame top */
+
  lua_unlock(L);
+
  return res;
+
}
+

+

+
LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
+
  int i;
+
  if (from == to) return;
+
  lua_lock(to);
+
  api_checknelems(from, n);
+
  api_check(from, G(from) == G(to), "moving among independent states");
+
  api_check(from, to->ci->top - to->top >= n, "stack overflow");
+
  from->top -= n;
+
  for (i = 0; i < n; i++) {
+
    setobj2s(to, to->top, from->top + i);
+
    to->top++;  /* stack already checked by previous 'api_check' */
+
  }
+
  lua_unlock(to);
+
}
+

+

+
LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
+
  lua_CFunction old;
+
  lua_lock(L);
+
  old = G(L)->panic;
+
  G(L)->panic = panicf;
+
  lua_unlock(L);
+
  return old;
+
}
+

+

+
LUA_API const lua_Number *lua_version (lua_State *L) {
+
  static const lua_Number version = LUA_VERSION_NUM;
+
  if (L == NULL) return &version;
+
  else return G(L)->version;
+
}
+

+

+

+
/*
+
** basic stack manipulation
+
*/
+

+

+
/*
+
** convert an acceptable stack index into an absolute index
+
*/
+
LUA_API int lua_absindex (lua_State *L, int idx) {
+
  return (idx > 0 || ispseudo(idx))
+
         ? idx
+
         : cast_int(L->top - L->ci->func) + idx;
+
}
+

+

+
LUA_API int lua_gettop (lua_State *L) {
+
  return cast_int(L->top - (L->ci->func + 1));
+
}
+

+

+
LUA_API void lua_settop (lua_State *L, int idx) {
+
  StkId func = L->ci->func;
+
  lua_lock(L);
+
  if (idx >= 0) {
+
    api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
+
    while (L->top < (func + 1) + idx)
+
      setnilvalue(L->top++);
+
    L->top = (func + 1) + idx;
+
  }
+
  else {
+
    api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
+
    L->top += idx+1;  /* 'subtract' index (index is negative) */
+
  }
+
  lua_unlock(L);
+
}
+

+

+
/*
+
** Reverse the stack segment from 'from' to 'to'
+
** (auxiliary to 'lua_rotate')
+
*/
+
static void reverse (lua_State *L, StkId from, StkId to) {
+
  for (; from < to; from++, to--) {
+
    TValue temp;
+
    setobj(L, &temp, from);
+
    setobjs2s(L, from, to);
+
    setobj2s(L, to, &temp);
+
  }
+
}
+

+

+
/*
+
** Let x = AB, where A is a prefix of length 'n'. Then,
+
** rotate x n == BA. But BA == (A^r . B^r)^r.
+
*/
+
LUA_API void lua_rotate (lua_State *L, int idx, int n) {
+
  StkId p, t, m;
+
  lua_lock(L);
+
  t = L->top - 1;  /* end of stack segment being rotated */
+
  p = index2addr(L, idx);  /* start of segment */
+
  api_checkstackindex(L, idx, p);
+
  api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
+
  m = (n >= 0 ? t - n : p - n - 1);  /* end of prefix */
+
  reverse(L, p, m);  /* reverse the prefix with length 'n' */
+
  reverse(L, m + 1, t);  /* reverse the suffix */
+
  reverse(L, p, t);  /* reverse the entire segment */
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
+
  TValue *fr, *to;
+
  lua_lock(L);
+
  fr = index2addr(L, fromidx);
+
  to = index2addr(L, toidx);
+
  api_checkvalidindex(L, to);
+
  setobj(L, to, fr);
+
  if (isupvalue(toidx))  /* function upvalue? */
+
    luaC_barrier(L, clCvalue(L->ci->func), fr);
+
  /* LUA_REGISTRYINDEX does not need gc barrier
+
     (collector revisits it before finishing collection) */
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_pushvalue (lua_State *L, int idx) {
+
  lua_lock(L);
+
  setobj2s(L, L->top, index2addr(L, idx));
+
  api_incr_top(L);
+
  lua_unlock(L);
+
}
+

+

+

+
/*
+
** access functions (stack -> C)
+
*/
+

+

+
LUA_API int lua_type (lua_State *L, int idx) {
+
  StkId o = index2addr(L, idx);
+
  return (isvalid(o) ? ttnov(o) : LUA_TNONE);
+
}
+

+

+
LUA_API const char *lua_typename (lua_State *L, int t) {
+
  UNUSED(L);
+
  api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
+
  return ttypename(t);
+
}
+

+

+
LUA_API int lua_iscfunction (lua_State *L, int idx) {
+
  StkId o = index2addr(L, idx);
+
  return (ttislcf(o) || (ttisCclosure(o)));
+
}
+

+

+
LUA_API int lua_isinteger (lua_State *L, int idx) {
+
  StkId o = index2addr(L, idx);
+
  return ttisinteger(o);
+
}
+

+

+
LUA_API int lua_isnumber (lua_State *L, int idx) {
+
  lua_Number n;
+
  const TValue *o = index2addr(L, idx);
+
  return tonumber(o, &n);
+
}
+

+

+
LUA_API int lua_isstring (lua_State *L, int idx) {
+
  const TValue *o = index2addr(L, idx);
+
  return (ttisstring(o) || cvt2str(o));
+
}
+

+

+
LUA_API int lua_isuserdata (lua_State *L, int idx) {
+
  const TValue *o = index2addr(L, idx);
+
  return (ttisfulluserdata(o) || ttislightuserdata(o));
+
}
+

+

+
LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
+
  StkId o1 = index2addr(L, index1);
+
  StkId o2 = index2addr(L, index2);
+
  return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
+
}
+

+

+
LUA_API void lua_arith (lua_State *L, int op) {
+
  lua_lock(L);
+
  if (op != LUA_OPUNM && op != LUA_OPBNOT)
+
    api_checknelems(L, 2);  /* all other operations expect two operands */
+
  else {  /* for unary operations, add fake 2nd operand */
+
    api_checknelems(L, 1);
+
    setobjs2s(L, L->top, L->top - 1);
+
    api_incr_top(L);
+
  }
+
  /* first operand at top - 2, second at top - 1; result go to top - 2 */
+
  luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
+
  L->top--;  /* remove second operand */
+
  lua_unlock(L);
+
}
+

+

+
LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
+
  StkId o1, o2;
+
  int i = 0;
+
  lua_lock(L);  /* may call tag method */
+
  o1 = index2addr(L, index1);
+
  o2 = index2addr(L, index2);
+
  if (isvalid(o1) && isvalid(o2)) {
+
    switch (op) {
+
      case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
+
      case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
+
      case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
+
      default: api_check(L, 0, "invalid option");
+
    }
+
  }
+
  lua_unlock(L);
+
  return i;
+
}
+

+

+
LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
+
  size_t sz = luaO_str2num(s, L->top);
+
  if (sz != 0)
+
    api_incr_top(L);
+
  return sz;
+
}
+

+

+
LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
+
  lua_Number n;
+
  const TValue *o = index2addr(L, idx);
+
  int isnum = tonumber(o, &n);
+
  if (!isnum)
+
    n = 0;  /* call to 'tonumber' may change 'n' even if it fails */
+
  if (pisnum) *pisnum = isnum;
+
  return n;
+
}
+

+

+
LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
+
  lua_Integer res;
+
  const TValue *o = index2addr(L, idx);
+
  int isnum = tointeger(o, &res);
+
  if (!isnum)
+
    res = 0;  /* call to 'tointeger' may change 'n' even if it fails */
+
  if (pisnum) *pisnum = isnum;
+
  return res;
+
}
+

+

+
LUA_API int lua_toboolean (lua_State *L, int idx) {
+
  const TValue *o = index2addr(L, idx);
+
  return !l_isfalse(o);
+
}
+

+

+
LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
+
  StkId o = index2addr(L, idx);
+
  if (!ttisstring(o)) {
+
    if (!cvt2str(o)) {  /* not convertible? */
+
      if (len != NULL) *len = 0;
+
      return NULL;
+
    }
+
    lua_lock(L);  /* 'luaO_tostring' may create a new string */
+
    luaO_tostring(L, o);
+
    luaC_checkGC(L);
+
    o = index2addr(L, idx);  /* previous call may reallocate the stack */
+
    lua_unlock(L);
+
  }
+
  if (len != NULL)
+
    *len = vslen(o);
+
  return svalue(o);
+
}
+

+

+
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
+
  StkId o = index2addr(L, idx);
+
  switch (ttype(o)) {
+
    case LUA_TSHRSTR: return tsvalue(o)->shrlen;
+
    case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
+
    case LUA_TUSERDATA: return uvalue(o)->len;
+
    case LUA_TTABLE: return luaH_getn(hvalue(o));
+
    default: return 0;
+
  }
+
}
+

+

+
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
+
  StkId o = index2addr(L, idx);
+
  if (ttislcf(o)) return fvalue(o);
+
  else if (ttisCclosure(o))
+
    return clCvalue(o)->f;
+
  else return NULL;  /* not a C function */
+
}
+

+

+
LUA_API void *lua_touserdata (lua_State *L, int idx) {
+
  StkId o = index2addr(L, idx);
+
  switch (ttnov(o)) {
+
    case LUA_TUSERDATA: return getudatamem(uvalue(o));
+
    case LUA_TLIGHTUSERDATA: return pvalue(o);
+
    default: return NULL;
+
  }
+
}
+

+

+
LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
+
  StkId o = index2addr(L, idx);
+
  return (!ttisthread(o)) ? NULL : thvalue(o);
+
}
+

+

+
LUA_API const void *lua_topointer (lua_State *L, int idx) {
+
  StkId o = index2addr(L, idx);
+
  switch (ttype(o)) {
+
    case LUA_TTABLE: return hvalue(o);
+
    case LUA_TLCL: return clLvalue(o);
+
    case LUA_TCCL: return clCvalue(o);
+
    case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
+
    case LUA_TTHREAD: return thvalue(o);
+
    case LUA_TUSERDATA: return getudatamem(uvalue(o));
+
    case LUA_TLIGHTUSERDATA: return pvalue(o);
+
    default: return NULL;
+
  }
+
}
+

+

+

+
/*
+
** push functions (C -> stack)
+
*/
+

+

+
LUA_API void lua_pushnil (lua_State *L) {
+
  lua_lock(L);
+
  setnilvalue(L->top);
+
  api_incr_top(L);
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
+
  lua_lock(L);
+
  setfltvalue(L->top, n);
+
  api_incr_top(L);
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
+
  lua_lock(L);
+
  setivalue(L->top, n);
+
  api_incr_top(L);
+
  lua_unlock(L);
+
}
+

+

+
/*
+
** Pushes on the stack a string with given length. Avoid using 's' when
+
** 'len' == 0 (as 's' can be NULL in that case), due to later use of
+
** 'memcmp' and 'memcpy'.
+
*/
+
LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
+
  TString *ts;
+
  lua_lock(L);
+
  ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
+
  setsvalue2s(L, L->top, ts);
+
  api_incr_top(L);
+
  luaC_checkGC(L);
+
  lua_unlock(L);
+
  return getstr(ts);
+
}
+

+

+
LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
+
  lua_lock(L);
+
  if (s == NULL)
+
    setnilvalue(L->top);
+
  else {
+
    TString *ts;
+
    ts = luaS_new(L, s);
+
    setsvalue2s(L, L->top, ts);
+
    s = getstr(ts);  /* internal copy's address */
+
  }
+
  api_incr_top(L);
+
  luaC_checkGC(L);
+
  lua_unlock(L);
+
  return s;
+
}
+

+

+
LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
+
                                      va_list argp) {
+
  const char *ret;
+
  lua_lock(L);
+
  ret = luaO_pushvfstring(L, fmt, argp);
+
  luaC_checkGC(L);
+
  lua_unlock(L);
+
  return ret;
+
}
+

+

+
LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
+
  const char *ret;
+
  va_list argp;
+
  lua_lock(L);
+
  va_start(argp, fmt);
+
  ret = luaO_pushvfstring(L, fmt, argp);
+
  va_end(argp);
+
  luaC_checkGC(L);
+
  lua_unlock(L);
+
  return ret;
+
}
+

+

+
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
+
  lua_lock(L);
+
  if (n == 0) {
+
    setfvalue(L->top, fn);
+
    api_incr_top(L);
+
  }
+
  else {
+
    CClosure *cl;
+
    api_checknelems(L, n);
+
    api_check(L, n <= MAXUPVAL, "upvalue index too large");
+
    cl = luaF_newCclosure(L, n);
+
    cl->f = fn;
+
    L->top -= n;
+
    while (n--) {
+
      setobj2n(L, &cl->upvalue[n], L->top + n);
+
      /* does not need barrier because closure is white */
+
    }
+
    setclCvalue(L, L->top, cl);
+
    api_incr_top(L);
+
    luaC_checkGC(L);
+
  }
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_pushboolean (lua_State *L, int b) {
+
  lua_lock(L);
+
  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
+
  api_incr_top(L);
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
+
  lua_lock(L);
+
  setpvalue(L->top, p);
+
  api_incr_top(L);
+
  lua_unlock(L);
+
}
+

+

+
LUA_API int lua_pushthread (lua_State *L) {
+
  lua_lock(L);
+
  setthvalue(L, L->top, L);
+
  api_incr_top(L);
+
  lua_unlock(L);
+
  return (G(L)->mainthread == L);
+
}
+

+

+

+
/*
+
** get functions (Lua -> stack)
+
*/
+

+

+
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
+
  const TValue *slot;
+
  TString *str = luaS_new(L, k);
+
  if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
+
    setobj2s(L, L->top, slot);
+
    api_incr_top(L);
+
  }
+
  else {
+
    setsvalue2s(L, L->top, str);
+
    api_incr_top(L);
+
    luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
+
  }
+
  lua_unlock(L);
+
  return ttnov(L->top - 1);
+
}
+

+

+
LUA_API int lua_getglobal (lua_State *L, const char *name) {
+
  Table *reg = hvalue(&G(L)->l_registry);
+
  lua_lock(L);
+
  return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
+
}
+

+

+
LUA_API int lua_gettable (lua_State *L, int idx) {
+
  StkId t;
+
  lua_lock(L);
+
  t = index2addr(L, idx);
+
  luaV_gettable(L, t, L->top - 1, L->top - 1);
+
  lua_unlock(L);
+
  return ttnov(L->top - 1);
+
}
+

+

+
LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
+
  lua_lock(L);
+
  return auxgetstr(L, index2addr(L, idx), k);
+
}
+

+

+
LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
+
  StkId t;
+
  const TValue *slot;
+
  lua_lock(L);
+
  t = index2addr(L, idx);
+
  if (luaV_fastget(L, t, n, slot, luaH_getint)) {
+
    setobj2s(L, L->top, slot);
+
    api_incr_top(L);
+
  }
+
  else {
+
    setivalue(L->top, n);
+
    api_incr_top(L);
+
    luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
+
  }
+
  lua_unlock(L);
+
  return ttnov(L->top - 1);
+
}
+

+

+
LUA_API int lua_rawget (lua_State *L, int idx) {
+
  StkId t;
+
  lua_lock(L);
+
  t = index2addr(L, idx);
+
  api_check(L, ttistable(t), "table expected");
+
  setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
+
  lua_unlock(L);
+
  return ttnov(L->top - 1);
+
}
+

+

+
LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
+
  StkId t;
+
  lua_lock(L);
+
  t = index2addr(L, idx);
+
  api_check(L, ttistable(t), "table expected");
+
  setobj2s(L, L->top, luaH_getint(hvalue(t), n));
+
  api_incr_top(L);
+
  lua_unlock(L);
+
  return ttnov(L->top - 1);
+
}
+

+

+
LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
+
  StkId t;
+
  TValue k;
+
  lua_lock(L);
+
  t = index2addr(L, idx);
+
  api_check(L, ttistable(t), "table expected");
+
  setpvalue(&k, cast(void *, p));
+
  setobj2s(L, L->top, luaH_get(hvalue(t), &k));
+
  api_incr_top(L);
+
  lua_unlock(L);
+
  return ttnov(L->top - 1);
+
}
+

+

+
LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
+
  Table *t;
+
  lua_lock(L);
+
  t = luaH_new(L);
+
  sethvalue(L, L->top, t);
+
  api_incr_top(L);
+
  if (narray > 0 || nrec > 0)
+
    luaH_resize(L, t, narray, nrec);
+
  luaC_checkGC(L);
+
  lua_unlock(L);
+
}
+

+

+
LUA_API int lua_getmetatable (lua_State *L, int objindex) {
+
  const TValue *obj;
+
  Table *mt;
+
  int res = 0;
+
  lua_lock(L);
+
  obj = index2addr(L, objindex);
+
  switch (ttnov(obj)) {
+
    case LUA_TTABLE:
+
      mt = hvalue(obj)->metatable;
+
      break;
+
    case LUA_TUSERDATA:
+
      mt = uvalue(obj)->metatable;
+
      break;
+
    default:
+
      mt = G(L)->mt[ttnov(obj)];
+
      break;
+
  }
+
  if (mt != NULL) {
+
    sethvalue(L, L->top, mt);
+
    api_incr_top(L);
+
    res = 1;
+
  }
+
  lua_unlock(L);
+
  return res;
+
}
+

+

+
LUA_API int lua_getuservalue (lua_State *L, int idx) {
+
  StkId o;
+
  lua_lock(L);
+
  o = index2addr(L, idx);
+
  api_check(L, ttisfulluserdata(o), "full userdata expected");
+
  getuservalue(L, uvalue(o), L->top);
+
  api_incr_top(L);
+
  lua_unlock(L);
+
  return ttnov(L->top - 1);
+
}
+

+

+
/*
+
** set functions (stack -> Lua)
+
*/
+

+
/*
+
** t[k] = value at the top of the stack (where 'k' is a string)
+
*/
+
static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
+
  const TValue *slot;
+
  TString *str = luaS_new(L, k);
+
  api_checknelems(L, 1);
+
  if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1))
+
    L->top--;  /* pop value */
+
  else {
+
    setsvalue2s(L, L->top, str);  /* push 'str' (to make it a TValue) */
+
    api_incr_top(L);
+
    luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
+
    L->top -= 2;  /* pop value and key */
+
  }
+
  lua_unlock(L);  /* lock done by caller */
+
}
+

+

+
LUA_API void lua_setglobal (lua_State *L, const char *name) {
+
  Table *reg = hvalue(&G(L)->l_registry);
+
  lua_lock(L);  /* unlock done in 'auxsetstr' */
+
  auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
+
}
+

+

+
LUA_API void lua_settable (lua_State *L, int idx) {
+
  StkId t;
+
  lua_lock(L);
+
  api_checknelems(L, 2);
+
  t = index2addr(L, idx);
+
  luaV_settable(L, t, L->top - 2, L->top - 1);
+
  L->top -= 2;  /* pop index and value */
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
+
  lua_lock(L);  /* unlock done in 'auxsetstr' */
+
  auxsetstr(L, index2addr(L, idx), k);
+
}
+

+

+
LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
+
  StkId t;
+
  const TValue *slot;
+
  lua_lock(L);
+
  api_checknelems(L, 1);
+
  t = index2addr(L, idx);
+
  if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1))
+
    L->top--;  /* pop value */
+
  else {
+
    setivalue(L->top, n);
+
    api_incr_top(L);
+
    luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
+
    L->top -= 2;  /* pop value and key */
+
  }
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_rawset (lua_State *L, int idx) {
+
  StkId o;
+
  TValue *slot;
+
  lua_lock(L);
+
  api_checknelems(L, 2);
+
  o = index2addr(L, idx);
+
  api_check(L, ttistable(o), "table expected");
+
  slot = luaH_set(L, hvalue(o), L->top - 2);
+
  setobj2t(L, slot, L->top - 1);
+
  invalidateTMcache(hvalue(o));
+
  luaC_barrierback(L, hvalue(o), L->top-1);
+
  L->top -= 2;
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
+
  StkId o;
+
  lua_lock(L);
+
  api_checknelems(L, 1);
+
  o = index2addr(L, idx);
+
  api_check(L, ttistable(o), "table expected");
+
  luaH_setint(L, hvalue(o), n, L->top - 1);
+
  luaC_barrierback(L, hvalue(o), L->top-1);
+
  L->top--;
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
+
  StkId o;
+
  TValue k, *slot;
+
  lua_lock(L);
+
  api_checknelems(L, 1);
+
  o = index2addr(L, idx);
+
  api_check(L, ttistable(o), "table expected");
+
  setpvalue(&k, cast(void *, p));
+
  slot = luaH_set(L, hvalue(o), &k);
+
  setobj2t(L, slot, L->top - 1);
+
  luaC_barrierback(L, hvalue(o), L->top - 1);
+
  L->top--;
+
  lua_unlock(L);
+
}
+

+

+
LUA_API int lua_setmetatable (lua_State *L, int objindex) {
+
  TValue *obj;
+
  Table *mt;
+
  lua_lock(L);
+
  api_checknelems(L, 1);
+
  obj = index2addr(L, objindex);
+
  if (ttisnil(L->top - 1))
+
    mt = NULL;
+
  else {
+
    api_check(L, ttistable(L->top - 1), "table expected");
+
    mt = hvalue(L->top - 1);
+
  }
+
  switch (ttnov(obj)) {
+
    case LUA_TTABLE: {
+
      hvalue(obj)->metatable = mt;
+
      if (mt) {
+
        luaC_objbarrier(L, gcvalue(obj), mt);
+
        luaC_checkfinalizer(L, gcvalue(obj), mt);
+
      }
+
      break;
+
    }
+
    case LUA_TUSERDATA: {
+
      uvalue(obj)->metatable = mt;
+
      if (mt) {
+
        luaC_objbarrier(L, uvalue(obj), mt);
+
        luaC_checkfinalizer(L, gcvalue(obj), mt);
+
      }
+
      break;
+
    }
+
    default: {
+
      G(L)->mt[ttnov(obj)] = mt;
+
      break;
+
    }
+
  }
+
  L->top--;
+
  lua_unlock(L);
+
  return 1;
+
}
+

+

+
LUA_API void lua_setuservalue (lua_State *L, int idx) {
+
  StkId o;
+
  lua_lock(L);
+
  api_checknelems(L, 1);
+
  o = index2addr(L, idx);
+
  api_check(L, ttisfulluserdata(o), "full userdata expected");
+
  setuservalue(L, uvalue(o), L->top - 1);
+
  luaC_barrier(L, gcvalue(o), L->top - 1);
+
  L->top--;
+
  lua_unlock(L);
+
}
+

+

+
/*
+
** 'load' and 'call' functions (run Lua code)
+
*/
+

+

+
#define checkresults(L,na,nr) \
+
     api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
+
	"results from function overflow current stack size")
+

+

+
LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
+
                        lua_KContext ctx, lua_KFunction k) {
+
  StkId func;
+
  lua_lock(L);
+
  api_check(L, k == NULL || !isLua(L->ci),
+
    "cannot use continuations inside hooks");
+
  api_checknelems(L, nargs+1);
+
  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
+
  checkresults(L, nargs, nresults);
+
  func = L->top - (nargs+1);
+
  if (k != NULL && L->nny == 0) {  /* need to prepare continuation? */
+
    L->ci->u.c.k = k;  /* save continuation */
+
    L->ci->u.c.ctx = ctx;  /* save context */
+
    luaD_call(L, func, nresults);  /* do the call */
+
  }
+
  else  /* no continuation or no yieldable */
+
    luaD_callnoyield(L, func, nresults);  /* just do the call */
+
  adjustresults(L, nresults);
+
  lua_unlock(L);
+
}
+

+

+

+
/*
+
** Execute a protected call.
+
*/
+
struct CallS {  /* data to 'f_call' */
+
  StkId func;
+
  int nresults;
+
};
+

+

+
static void f_call (lua_State *L, void *ud) {
+
  struct CallS *c = cast(struct CallS *, ud);
+
  luaD_callnoyield(L, c->func, c->nresults);
+
}
+

+

+

+
LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
+
                        lua_KContext ctx, lua_KFunction k) {
+
  struct CallS c;
+
  int status;
+
  ptrdiff_t func;
+
  lua_lock(L);
+
  api_check(L, k == NULL || !isLua(L->ci),
+
    "cannot use continuations inside hooks");
+
  api_checknelems(L, nargs+1);
+
  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
+
  checkresults(L, nargs, nresults);
+
  if (errfunc == 0)
+
    func = 0;
+
  else {
+
    StkId o = index2addr(L, errfunc);
+
    api_checkstackindex(L, errfunc, o);
+
    func = savestack(L, o);
+
  }
+
  c.func = L->top - (nargs+1);  /* function to be called */
+
  if (k == NULL || L->nny > 0) {  /* no continuation or no yieldable? */
+
    c.nresults = nresults;  /* do a 'conventional' protected call */
+
    status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
+
  }
+
  else {  /* prepare continuation (call is already protected by 'resume') */
+
    CallInfo *ci = L->ci;
+
    ci->u.c.k = k;  /* save continuation */
+
    ci->u.c.ctx = ctx;  /* save context */
+
    /* save information for error recovery */
+
    ci->extra = savestack(L, c.func);
+
    ci->u.c.old_errfunc = L->errfunc;
+
    L->errfunc = func;
+
    setoah(ci->callstatus, L->allowhook);  /* save value of 'allowhook' */
+
    ci->callstatus |= CIST_YPCALL;  /* function can do error recovery */
+
    luaD_call(L, c.func, nresults);  /* do the call */
+
    ci->callstatus &= ~CIST_YPCALL;
+
    L->errfunc = ci->u.c.old_errfunc;
+
    status = LUA_OK;  /* if it is here, there were no errors */
+
  }
+
  adjustresults(L, nresults);
+
  lua_unlock(L);
+
  return status;
+
}
+

+

+
LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
+
                      const char *chunkname, const char *mode) {
+
  ZIO z;
+
  int status;
+
  lua_lock(L);
+
  if (!chunkname) chunkname = "?";
+
  luaZ_init(L, &z, reader, data);
+
  status = luaD_protectedparser(L, &z, chunkname, mode);
+
  if (status == LUA_OK) {  /* no errors? */
+
    LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
+
    if (f->nupvalues >= 1) {  /* does it have an upvalue? */
+
      /* get global table from registry */
+
      Table *reg = hvalue(&G(L)->l_registry);
+
      const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+
      /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
+
      setobj(L, f->upvals[0]->v, gt);
+
      luaC_upvalbarrier(L, f->upvals[0]);
+
    }
+
  }
+
  lua_unlock(L);
+
  return status;
+
}
+

+

+
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
+
  int status;
+
  TValue *o;
+
  lua_lock(L);
+
  api_checknelems(L, 1);
+
  o = L->top - 1;
+
  if (isLfunction(o))
+
    status = luaU_dump(L, getproto(o), writer, data, strip);
+
  else
+
    status = 1;
+
  lua_unlock(L);
+
  return status;
+
}
+

+

+
LUA_API int lua_status (lua_State *L) {
+
  return L->status;
+
}
+

+

+
/*
+
** Garbage-collection function
+
*/
+

+
LUA_API int lua_gc (lua_State *L, int what, int data) {
+
  int res = 0;
+
  global_State *g;
+
  lua_lock(L);
+
  g = G(L);
+
  switch (what) {
+
    case LUA_GCSTOP: {
+
      g->gcrunning = 0;
+
      break;
+
    }
+
    case LUA_GCRESTART: {
+
      luaE_setdebt(g, 0);
+
      g->gcrunning = 1;
+
      break;
+
    }
+
    case LUA_GCCOLLECT: {
+
      luaC_fullgc(L, 0);
+
      break;
+
    }
+
    case LUA_GCCOUNT: {
+
      /* GC values are expressed in Kbytes: #bytes/2^10 */
+
      res = cast_int(gettotalbytes(g) >> 10);
+
      break;
+
    }
+
    case LUA_GCCOUNTB: {
+
      res = cast_int(gettotalbytes(g) & 0x3ff);
+
      break;
+
    }
+
    case LUA_GCSTEP: {
+
      l_mem debt = 1;  /* =1 to signal that it did an actual step */
+
      lu_byte oldrunning = g->gcrunning;
+
      g->gcrunning = 1;  /* allow GC to run */
+
      if (data == 0) {
+
        luaE_setdebt(g, -GCSTEPSIZE);  /* to do a "small" step */
+
        luaC_step(L);
+
      }
+
      else {  /* add 'data' to total debt */
+
        debt = cast(l_mem, data) * 1024 + g->GCdebt;
+
        luaE_setdebt(g, debt);
+
        luaC_checkGC(L);
+
      }
+
      g->gcrunning = oldrunning;  /* restore previous state */
+
      if (debt > 0 && g->gcstate == GCSpause)  /* end of cycle? */
+
        res = 1;  /* signal it */
+
      break;
+
    }
+
    case LUA_GCSETPAUSE: {
+
      res = g->gcpause;
+
      g->gcpause = data;
+
      break;
+
    }
+
    case LUA_GCSETSTEPMUL: {
+
      res = g->gcstepmul;
+
      if (data < 40) data = 40;  /* avoid ridiculous low values (and 0) */
+
      g->gcstepmul = data;
+
      break;
+
    }
+
    case LUA_GCISRUNNING: {
+
      res = g->gcrunning;
+
      break;
+
    }
+
    default: res = -1;  /* invalid option */
+
  }
+
  lua_unlock(L);
+
  return res;
+
}
+

+

+

+
/*
+
** miscellaneous functions
+
*/
+

+

+
LUA_API int lua_error (lua_State *L) {
+
  lua_lock(L);
+
  api_checknelems(L, 1);
+
  luaG_errormsg(L);
+
  /* code unreachable; will unlock when control actually leaves the kernel */
+
  return 0;  /* to avoid warnings */
+
}
+

+

+
LUA_API int lua_next (lua_State *L, int idx) {
+
  StkId t;
+
  int more;
+
  lua_lock(L);
+
  t = index2addr(L, idx);
+
  api_check(L, ttistable(t), "table expected");
+
  more = luaH_next(L, hvalue(t), L->top - 1);
+
  if (more) {
+
    api_incr_top(L);
+
  }
+
  else  /* no more elements */
+
    L->top -= 1;  /* remove key */
+
  lua_unlock(L);
+
  return more;
+
}
+

+

+
LUA_API void lua_concat (lua_State *L, int n) {
+
  lua_lock(L);
+
  api_checknelems(L, n);
+
  if (n >= 2) {
+
    luaV_concat(L, n);
+
  }
+
  else if (n == 0) {  /* push empty string */
+
    setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
+
    api_incr_top(L);
+
  }
+
  /* else n == 1; nothing to do */
+
  luaC_checkGC(L);
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_len (lua_State *L, int idx) {
+
  StkId t;
+
  lua_lock(L);
+
  t = index2addr(L, idx);
+
  luaV_objlen(L, L->top, t);
+
  api_incr_top(L);
+
  lua_unlock(L);
+
}
+

+

+
LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
+
  lua_Alloc f;
+
  lua_lock(L);
+
  if (ud) *ud = G(L)->ud;
+
  f = G(L)->frealloc;
+
  lua_unlock(L);
+
  return f;
+
}
+

+

+
LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
+
  lua_lock(L);
+
  G(L)->ud = ud;
+
  G(L)->frealloc = f;
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
+
  Udata *u;
+
  lua_lock(L);
+
  u = luaS_newudata(L, size);
+
  setuvalue(L, L->top, u);
+
  api_incr_top(L);
+
  luaC_checkGC(L);
+
  lua_unlock(L);
+
  return getudatamem(u);
+
}
+

+

+

+
static const char *aux_upvalue (StkId fi, int n, TValue **val,
+
                                CClosure **owner, UpVal **uv) {
+
  switch (ttype(fi)) {
+
    case LUA_TCCL: {  /* C closure */
+
      CClosure *f = clCvalue(fi);
+
      if (!(1 <= n && n <= f->nupvalues)) return NULL;
+
      *val = &f->upvalue[n-1];
+
      if (owner) *owner = f;
+
      return "";
+
    }
+
    case LUA_TLCL: {  /* Lua closure */
+
      LClosure *f = clLvalue(fi);
+
      TString *name;
+
      Proto *p = f->p;
+
      if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
+
      *val = f->upvals[n-1]->v;
+
      if (uv) *uv = f->upvals[n - 1];
+
      name = p->upvalues[n-1].name;
+
      return (name == NULL) ? "(*no name)" : getstr(name);
+
    }
+
    default: return NULL;  /* not a closure */
+
  }
+
}
+

+

+
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
+
  const char *name;
+
  TValue *val = NULL;  /* to avoid warnings */
+
  lua_lock(L);
+
  name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL);
+
  if (name) {
+
    setobj2s(L, L->top, val);
+
    api_incr_top(L);
+
  }
+
  lua_unlock(L);
+
  return name;
+
}
+

+

+
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
+
  const char *name;
+
  TValue *val = NULL;  /* to avoid warnings */
+
  CClosure *owner = NULL;
+
  UpVal *uv = NULL;
+
  StkId fi;
+
  lua_lock(L);
+
  fi = index2addr(L, funcindex);
+
  api_checknelems(L, 1);
+
  name = aux_upvalue(fi, n, &val, &owner, &uv);
+
  if (name) {
+
    L->top--;
+
    setobj(L, val, L->top);
+
    if (owner) { luaC_barrier(L, owner, L->top); }
+
    else if (uv) { luaC_upvalbarrier(L, uv); }
+
  }
+
  lua_unlock(L);
+
  return name;
+
}
+

+

+
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
+
  LClosure *f;
+
  StkId fi = index2addr(L, fidx);
+
  api_check(L, ttisLclosure(fi), "Lua function expected");
+
  f = clLvalue(fi);
+
  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 */
+
}
+

+

+
LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
+
  StkId fi = index2addr(L, fidx);
+
  switch (ttype(fi)) {
+
    case LUA_TLCL: {  /* lua closure */
+
      return *getupvalref(L, fidx, n, NULL);
+
    }
+
    case LUA_TCCL: {  /* C closure */
+
      CClosure *f = clCvalue(fi);
+
      api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
+
      return &f->upvalue[n - 1];
+
    }
+
    default: {
+
      api_check(L, 0, "closure expected");
+
      return NULL;
+
    }
+
  }
+
}
+

+

+
LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
+
                                            int fidx2, int n2) {
+
  LClosure *f1;
+
  UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
+
  UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
+
  luaC_upvdeccount(L, *up1);
+
  *up1 = *up2;
+
  (*up1)->refcount++;
+
  if (upisopen(*up1)) (*up1)->u.open.touched = 1;
+
  luaC_upvalbarrier(L, *up1);
+
}
+

+

added external/lua/src/lapi.h
@@ -0,0 +1,24 @@
+
/*
+
** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Auxiliary functions from Lua API
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lapi_h
+
#define lapi_h
+

+

+
#include "llimits.h"
+
#include "lstate.h"
+

+
#define api_incr_top(L)   {L->top++; api_check(L, L->top <= L->ci->top, \
+
				"stack overflow");}
+

+
#define adjustresults(L,nres) \
+
    { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
+

+
#define api_checknelems(L,n)	api_check(L, (n) < (L->top - L->ci->func), \
+
				  "not enough elements in the stack")
+

+

+
#endif
added external/lua/src/lauxlib.c
@@ -0,0 +1,1043 @@
+
/*
+
** $Id: lauxlib.c,v 1.289.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Auxiliary functions for building Lua libraries
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lauxlib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <errno.h>
+
#include <stdarg.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+

+
/*
+
** This file uses only the official API of Lua.
+
** Any function declared here could be written as an application function.
+
*/
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+

+

+
/*
+
** {======================================================
+
** Traceback
+
** =======================================================
+
*/
+

+

+
#define LEVELS1	10	/* size of the first part of the stack */
+
#define LEVELS2	11	/* size of the second part of the stack */
+

+

+

+
/*
+
** search for 'objidx' in table at index -1.
+
** return 1 + string at top if find a good name.
+
*/
+
static int findfield (lua_State *L, int objidx, int level) {
+
  if (level == 0 || !lua_istable(L, -1))
+
    return 0;  /* not found */
+
  lua_pushnil(L);  /* start 'next' loop */
+
  while (lua_next(L, -2)) {  /* for each pair in table */
+
    if (lua_type(L, -2) == LUA_TSTRING) {  /* ignore non-string keys */
+
      if (lua_rawequal(L, objidx, -1)) {  /* found object? */
+
        lua_pop(L, 1);  /* remove value (but keep name) */
+
        return 1;
+
      }
+
      else if (findfield(L, objidx, level - 1)) {  /* try recursively */
+
        lua_remove(L, -2);  /* remove table (but keep name) */
+
        lua_pushliteral(L, ".");
+
        lua_insert(L, -2);  /* place '.' between the two names */
+
        lua_concat(L, 3);
+
        return 1;
+
      }
+
    }
+
    lua_pop(L, 1);  /* remove value */
+
  }
+
  return 0;  /* not found */
+
}
+

+

+
/*
+
** Search for a name for a function in all loaded modules
+
*/
+
static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
+
  int top = lua_gettop(L);
+
  lua_getinfo(L, "f", ar);  /* push function */
+
  lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
+
  if (findfield(L, top + 1, 2)) {
+
    const char *name = lua_tostring(L, -1);
+
    if (strncmp(name, "_G.", 3) == 0) {  /* name start with '_G.'? */
+
      lua_pushstring(L, name + 3);  /* push name without prefix */
+
      lua_remove(L, -2);  /* remove original name */
+
    }
+
    lua_copy(L, -1, top + 1);  /* move name to proper place */
+
    lua_pop(L, 2);  /* remove pushed values */
+
    return 1;
+
  }
+
  else {
+
    lua_settop(L, top);  /* remove function and global table */
+
    return 0;
+
  }
+
}
+

+

+
static void pushfuncname (lua_State *L, lua_Debug *ar) {
+
  if (pushglobalfuncname(L, ar)) {  /* try first a global name */
+
    lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
+
    lua_remove(L, -2);  /* remove name */
+
  }
+
  else if (*ar->namewhat != '\0')  /* is there a name from code? */
+
    lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name);  /* use it */
+
  else if (*ar->what == 'm')  /* main? */
+
      lua_pushliteral(L, "main chunk");
+
  else if (*ar->what != 'C')  /* for Lua functions, use <file:line> */
+
    lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
+
  else  /* nothing left... */
+
    lua_pushliteral(L, "?");
+
}
+

+

+
static int lastlevel (lua_State *L) {
+
  lua_Debug ar;
+
  int li = 1, le = 1;
+
  /* find an upper bound */
+
  while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
+
  /* do a binary search */
+
  while (li < le) {
+
    int m = (li + le)/2;
+
    if (lua_getstack(L, m, &ar)) li = m + 1;
+
    else le = m;
+
  }
+
  return le - 1;
+
}
+

+

+
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
+
                                const char *msg, int level) {
+
  lua_Debug ar;
+
  int top = lua_gettop(L);
+
  int last = lastlevel(L1);
+
  int n1 = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1;
+
  if (msg)
+
    lua_pushfstring(L, "%s\n", msg);
+
  luaL_checkstack(L, 10, NULL);
+
  lua_pushliteral(L, "stack traceback:");
+
  while (lua_getstack(L1, level++, &ar)) {
+
    if (n1-- == 0) {  /* too many levels? */
+
      lua_pushliteral(L, "\n\t...");  /* add a '...' */
+
      level = last - LEVELS2 + 1;  /* and skip to last ones */
+
    }
+
    else {
+
      lua_getinfo(L1, "Slnt", &ar);
+
      lua_pushfstring(L, "\n\t%s:", ar.short_src);
+
      if (ar.currentline > 0)
+
        lua_pushfstring(L, "%d:", ar.currentline);
+
      lua_pushliteral(L, " in ");
+
      pushfuncname(L, &ar);
+
      if (ar.istailcall)
+
        lua_pushliteral(L, "\n\t(...tail calls...)");
+
      lua_concat(L, lua_gettop(L) - top);
+
    }
+
  }
+
  lua_concat(L, lua_gettop(L) - top);
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** Error-report functions
+
** =======================================================
+
*/
+

+
LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
+
  lua_Debug ar;
+
  if (!lua_getstack(L, 0, &ar))  /* no stack frame? */
+
    return luaL_error(L, "bad argument #%d (%s)", arg, extramsg);
+
  lua_getinfo(L, "n", &ar);
+
  if (strcmp(ar.namewhat, "method") == 0) {
+
    arg--;  /* do not count 'self' */
+
    if (arg == 0)  /* error is in the self argument itself? */
+
      return luaL_error(L, "calling '%s' on bad self (%s)",
+
                           ar.name, extramsg);
+
  }
+
  if (ar.name == NULL)
+
    ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
+
  return luaL_error(L, "bad argument #%d to '%s' (%s)",
+
                        arg, ar.name, extramsg);
+
}
+

+

+
static int typeerror (lua_State *L, int arg, const char *tname) {
+
  const char *msg;
+
  const char *typearg;  /* name for the type of the actual argument */
+
  if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
+
    typearg = lua_tostring(L, -1);  /* use the given type name */
+
  else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA)
+
    typearg = "light userdata";  /* special name for messages */
+
  else
+
    typearg = luaL_typename(L, arg);  /* standard name */
+
  msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg);
+
  return luaL_argerror(L, arg, msg);
+
}
+

+

+
static void tag_error (lua_State *L, int arg, int tag) {
+
  typeerror(L, arg, lua_typename(L, tag));
+
}
+

+

+
/*
+
** The use of 'lua_pushfstring' ensures this function does not
+
** need reserved stack space when called.
+
*/
+
LUALIB_API void luaL_where (lua_State *L, int level) {
+
  lua_Debug ar;
+
  if (lua_getstack(L, level, &ar)) {  /* check function at level */
+
    lua_getinfo(L, "Sl", &ar);  /* get info about it */
+
    if (ar.currentline > 0) {  /* is there info? */
+
      lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
+
      return;
+
    }
+
  }
+
  lua_pushfstring(L, "");  /* else, no information available... */
+
}
+

+

+
/*
+
** Again, the use of 'lua_pushvfstring' ensures this function does
+
** not need reserved stack space when called. (At worst, it generates
+
** an error with "stack overflow" instead of the given message.)
+
*/
+
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
+
  va_list argp;
+
  va_start(argp, fmt);
+
  luaL_where(L, 1);
+
  lua_pushvfstring(L, fmt, argp);
+
  va_end(argp);
+
  lua_concat(L, 2);
+
  return lua_error(L);
+
}
+

+

+
LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
+
  int en = errno;  /* calls to Lua API may change this value */
+
  if (stat) {
+
    lua_pushboolean(L, 1);
+
    return 1;
+
  }
+
  else {
+
    lua_pushnil(L);
+
    if (fname)
+
      lua_pushfstring(L, "%s: %s", fname, strerror(en));
+
    else
+
      lua_pushstring(L, strerror(en));
+
    lua_pushinteger(L, en);
+
    return 3;
+
  }
+
}
+

+

+
#if !defined(l_inspectstat)	/* { */
+

+
#if defined(LUA_USE_POSIX)
+

+
#include <sys/wait.h>
+

+
/*
+
** use appropriate macros to interpret 'pclose' return status
+
*/
+
#define l_inspectstat(stat,what)  \
+
   if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
+
   else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
+

+
#else
+

+
#define l_inspectstat(stat,what)  /* no op */
+

+
#endif
+

+
#endif				/* } */
+

+

+
LUALIB_API int luaL_execresult (lua_State *L, int stat) {
+
  const char *what = "exit";  /* type of termination */
+
  if (stat == -1)  /* error? */
+
    return luaL_fileresult(L, 0, NULL);
+
  else {
+
    l_inspectstat(stat, what);  /* interpret result */
+
    if (*what == 'e' && stat == 0)  /* successful termination? */
+
      lua_pushboolean(L, 1);
+
    else
+
      lua_pushnil(L);
+
    lua_pushstring(L, what);
+
    lua_pushinteger(L, stat);
+
    return 3;  /* return true/nil,what,code */
+
  }
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** Userdata's metatable manipulation
+
** =======================================================
+
*/
+

+
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
+
  if (luaL_getmetatable(L, tname) != LUA_TNIL)  /* name already in use? */
+
    return 0;  /* leave previous value on top, but return 0 */
+
  lua_pop(L, 1);
+
  lua_createtable(L, 0, 2);  /* create metatable */
+
  lua_pushstring(L, tname);
+
  lua_setfield(L, -2, "__name");  /* metatable.__name = tname */
+
  lua_pushvalue(L, -1);
+
  lua_setfield(L, LUA_REGISTRYINDEX, tname);  /* registry.name = metatable */
+
  return 1;
+
}
+

+

+
LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
+
  luaL_getmetatable(L, tname);
+
  lua_setmetatable(L, -2);
+
}
+

+

+
LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
+
  void *p = lua_touserdata(L, ud);
+
  if (p != NULL) {  /* value is a userdata? */
+
    if (lua_getmetatable(L, ud)) {  /* does it have a metatable? */
+
      luaL_getmetatable(L, tname);  /* get correct metatable */
+
      if (!lua_rawequal(L, -1, -2))  /* not the same? */
+
        p = NULL;  /* value is a userdata with wrong metatable */
+
      lua_pop(L, 2);  /* remove both metatables */
+
      return p;
+
    }
+
  }
+
  return NULL;  /* value is not a userdata with a metatable */
+
}
+

+

+
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
+
  void *p = luaL_testudata(L, ud, tname);
+
  if (p == NULL) typeerror(L, ud, tname);
+
  return p;
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** Argument check functions
+
** =======================================================
+
*/
+

+
LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
+
                                 const char *const lst[]) {
+
  const char *name = (def) ? luaL_optstring(L, arg, def) :
+
                             luaL_checkstring(L, arg);
+
  int i;
+
  for (i=0; lst[i]; i++)
+
    if (strcmp(lst[i], name) == 0)
+
      return i;
+
  return luaL_argerror(L, arg,
+
                       lua_pushfstring(L, "invalid option '%s'", name));
+
}
+

+

+
/*
+
** Ensures the stack has at least 'space' extra slots, raising an error
+
** if it cannot fulfill the request. (The error handling needs a few
+
** extra slots to format the error message. In case of an error without
+
** this extra space, Lua will generate the same 'stack overflow' error,
+
** but without 'msg'.)
+
*/
+
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
+
  if (!lua_checkstack(L, space)) {
+
    if (msg)
+
      luaL_error(L, "stack overflow (%s)", msg);
+
    else
+
      luaL_error(L, "stack overflow");
+
  }
+
}
+

+

+
LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
+
  if (lua_type(L, arg) != t)
+
    tag_error(L, arg, t);
+
}
+

+

+
LUALIB_API void luaL_checkany (lua_State *L, int arg) {
+
  if (lua_type(L, arg) == LUA_TNONE)
+
    luaL_argerror(L, arg, "value expected");
+
}
+

+

+
LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
+
  const char *s = lua_tolstring(L, arg, len);
+
  if (!s) tag_error(L, arg, LUA_TSTRING);
+
  return s;
+
}
+

+

+
LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
+
                                        const char *def, size_t *len) {
+
  if (lua_isnoneornil(L, arg)) {
+
    if (len)
+
      *len = (def ? strlen(def) : 0);
+
    return def;
+
  }
+
  else return luaL_checklstring(L, arg, len);
+
}
+

+

+
LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
+
  int isnum;
+
  lua_Number d = lua_tonumberx(L, arg, &isnum);
+
  if (!isnum)
+
    tag_error(L, arg, LUA_TNUMBER);
+
  return d;
+
}
+

+

+
LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) {
+
  return luaL_opt(L, luaL_checknumber, arg, def);
+
}
+

+

+
static void interror (lua_State *L, int arg) {
+
  if (lua_isnumber(L, arg))
+
    luaL_argerror(L, arg, "number has no integer representation");
+
  else
+
    tag_error(L, arg, LUA_TNUMBER);
+
}
+

+

+
LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
+
  int isnum;
+
  lua_Integer d = lua_tointegerx(L, arg, &isnum);
+
  if (!isnum) {
+
    interror(L, arg);
+
  }
+
  return d;
+
}
+

+

+
LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
+
                                                      lua_Integer def) {
+
  return luaL_opt(L, luaL_checkinteger, arg, def);
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** Generic Buffer manipulation
+
** =======================================================
+
*/
+

+
/* userdata to box arbitrary data */
+
typedef struct UBox {
+
  void *box;
+
  size_t bsize;
+
} UBox;
+

+

+
static void *resizebox (lua_State *L, int idx, size_t newsize) {
+
  void *ud;
+
  lua_Alloc allocf = lua_getallocf(L, &ud);
+
  UBox *box = (UBox *)lua_touserdata(L, idx);
+
  void *temp = allocf(ud, box->box, box->bsize, newsize);
+
  if (temp == NULL && newsize > 0) {  /* allocation error? */
+
    resizebox(L, idx, 0);  /* free buffer */
+
    luaL_error(L, "not enough memory for buffer allocation");
+
  }
+
  box->box = temp;
+
  box->bsize = newsize;
+
  return temp;
+
}
+

+

+
static int boxgc (lua_State *L) {
+
  resizebox(L, 1, 0);
+
  return 0;
+
}
+

+

+
static void *newbox (lua_State *L, size_t newsize) {
+
  UBox *box = (UBox *)lua_newuserdata(L, sizeof(UBox));
+
  box->box = NULL;
+
  box->bsize = 0;
+
  if (luaL_newmetatable(L, "LUABOX")) {  /* creating metatable? */
+
    lua_pushcfunction(L, boxgc);
+
    lua_setfield(L, -2, "__gc");  /* metatable.__gc = boxgc */
+
  }
+
  lua_setmetatable(L, -2);
+
  return resizebox(L, -1, newsize);
+
}
+

+

+
/*
+
** check whether buffer is using a userdata on the stack as a temporary
+
** buffer
+
*/
+
#define buffonstack(B)	((B)->b != (B)->initb)
+

+

+
/*
+
** returns a pointer to a free area with at least 'sz' bytes
+
*/
+
LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
+
  lua_State *L = B->L;
+
  if (B->size - B->n < sz) {  /* not enough space? */
+
    char *newbuff;
+
    size_t newsize = B->size * 2;  /* double buffer size */
+
    if (newsize - B->n < sz)  /* not big enough? */
+
      newsize = B->n + sz;
+
    if (newsize < B->n || newsize - B->n < sz)
+
      luaL_error(L, "buffer too large");
+
    /* create larger buffer */
+
    if (buffonstack(B))
+
      newbuff = (char *)resizebox(L, -1, newsize);
+
    else {  /* no buffer yet */
+
      newbuff = (char *)newbox(L, newsize);
+
      memcpy(newbuff, B->b, B->n * sizeof(char));  /* copy original content */
+
    }
+
    B->b = newbuff;
+
    B->size = newsize;
+
  }
+
  return &B->b[B->n];
+
}
+

+

+
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
+
  if (l > 0) {  /* avoid 'memcpy' when 's' can be NULL */
+
    char *b = luaL_prepbuffsize(B, l);
+
    memcpy(b, s, l * sizeof(char));
+
    luaL_addsize(B, l);
+
  }
+
}
+

+

+
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
+
  luaL_addlstring(B, s, strlen(s));
+
}
+

+

+
LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
+
  lua_State *L = B->L;
+
  lua_pushlstring(L, B->b, B->n);
+
  if (buffonstack(B)) {
+
    resizebox(L, -2, 0);  /* delete old buffer */
+
    lua_remove(L, -2);  /* remove its header from the stack */
+
  }
+
}
+

+

+
LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
+
  luaL_addsize(B, sz);
+
  luaL_pushresult(B);
+
}
+

+

+
LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
+
  lua_State *L = B->L;
+
  size_t l;
+
  const char *s = lua_tolstring(L, -1, &l);
+
  if (buffonstack(B))
+
    lua_insert(L, -2);  /* put value below buffer */
+
  luaL_addlstring(B, s, l);
+
  lua_remove(L, (buffonstack(B)) ? -2 : -1);  /* remove value */
+
}
+

+

+
LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
+
  B->L = L;
+
  B->b = B->initb;
+
  B->n = 0;
+
  B->size = LUAL_BUFFERSIZE;
+
}
+

+

+
LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
+
  luaL_buffinit(L, B);
+
  return luaL_prepbuffsize(B, sz);
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** Reference system
+
** =======================================================
+
*/
+

+
/* index of free-list header */
+
#define freelist	0
+

+

+
LUALIB_API int luaL_ref (lua_State *L, int t) {
+
  int ref;
+
  if (lua_isnil(L, -1)) {
+
    lua_pop(L, 1);  /* remove from stack */
+
    return LUA_REFNIL;  /* 'nil' has a unique fixed reference */
+
  }
+
  t = lua_absindex(L, t);
+
  lua_rawgeti(L, t, freelist);  /* get first free element */
+
  ref = (int)lua_tointeger(L, -1);  /* ref = t[freelist] */
+
  lua_pop(L, 1);  /* remove it from stack */
+
  if (ref != 0) {  /* any free element? */
+
    lua_rawgeti(L, t, ref);  /* remove it from list */
+
    lua_rawseti(L, t, freelist);  /* (t[freelist] = t[ref]) */
+
  }
+
  else  /* no free elements */
+
    ref = (int)lua_rawlen(L, t) + 1;  /* get a new reference */
+
  lua_rawseti(L, t, ref);
+
  return ref;
+
}
+

+

+
LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
+
  if (ref >= 0) {
+
    t = lua_absindex(L, t);
+
    lua_rawgeti(L, t, freelist);
+
    lua_rawseti(L, t, ref);  /* t[ref] = t[freelist] */
+
    lua_pushinteger(L, ref);
+
    lua_rawseti(L, t, freelist);  /* t[freelist] = ref */
+
  }
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** Load functions
+
** =======================================================
+
*/
+

+
typedef struct LoadF {
+
  int n;  /* number of pre-read characters */
+
  FILE *f;  /* file being read */
+
  char buff[BUFSIZ];  /* area for reading file */
+
} LoadF;
+

+

+
static const char *getF (lua_State *L, void *ud, size_t *size) {
+
  LoadF *lf = (LoadF *)ud;
+
  (void)L;  /* not used */
+
  if (lf->n > 0) {  /* are there pre-read characters to be read? */
+
    *size = lf->n;  /* return them (chars already in buffer) */
+
    lf->n = 0;  /* no more pre-read characters */
+
  }
+
  else {  /* read a block from file */
+
    /* 'fread' can return > 0 *and* set the EOF flag. If next call to
+
       'getF' called 'fread', it might still wait for user input.
+
       The next check avoids this problem. */
+
    if (feof(lf->f)) return NULL;
+
    *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);  /* read block */
+
  }
+
  return lf->buff;
+
}
+

+

+
static int errfile (lua_State *L, const char *what, int fnameindex) {
+
  const char *serr = strerror(errno);
+
  const char *filename = lua_tostring(L, fnameindex) + 1;
+
  lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
+
  lua_remove(L, fnameindex);
+
  return LUA_ERRFILE;
+
}
+

+

+
static int skipBOM (LoadF *lf) {
+
  const char *p = "\xEF\xBB\xBF";  /* UTF-8 BOM mark */
+
  int c;
+
  lf->n = 0;
+
  do {
+
    c = getc(lf->f);
+
    if (c == EOF || c != *(const unsigned char *)p++) return c;
+
    lf->buff[lf->n++] = c;  /* to be read by the parser */
+
  } while (*p != '\0');
+
  lf->n = 0;  /* prefix matched; discard it */
+
  return getc(lf->f);  /* return next character */
+
}
+

+

+
/*
+
** reads the first character of file 'f' and skips an optional BOM mark
+
** in its beginning plus its first line if it starts with '#'. Returns
+
** true if it skipped the first line.  In any case, '*cp' has the
+
** first "valid" character of the file (after the optional BOM and
+
** a first-line comment).
+
*/
+
static int skipcomment (LoadF *lf, int *cp) {
+
  int c = *cp = skipBOM(lf);
+
  if (c == '#') {  /* first line is a comment (Unix exec. file)? */
+
    do {  /* skip first line */
+
      c = getc(lf->f);
+
    } while (c != EOF && c != '\n');
+
    *cp = getc(lf->f);  /* skip end-of-line, if present */
+
    return 1;  /* there was a comment */
+
  }
+
  else return 0;  /* no comment */
+
}
+

+

+
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
+
                                             const char *mode) {
+
  LoadF lf;
+
  int status, readstatus;
+
  int c;
+
  int fnameindex = lua_gettop(L) + 1;  /* index of filename on the stack */
+
  if (filename == NULL) {
+
    lua_pushliteral(L, "=stdin");
+
    lf.f = stdin;
+
  }
+
  else {
+
    lua_pushfstring(L, "@%s", filename);
+
    lf.f = fopen(filename, "r");
+
    if (lf.f == NULL) return errfile(L, "open", fnameindex);
+
  }
+
  if (skipcomment(&lf, &c))  /* read initial portion */
+
    lf.buff[lf.n++] = '\n';  /* add line to correct line numbers */
+
  if (c == LUA_SIGNATURE[0] && filename) {  /* binary file? */
+
    lf.f = freopen(filename, "rb", lf.f);  /* reopen in binary mode */
+
    if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
+
    skipcomment(&lf, &c);  /* re-read initial portion */
+
  }
+
  if (c != EOF)
+
    lf.buff[lf.n++] = c;  /* 'c' is the first character of the stream */
+
  status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
+
  readstatus = ferror(lf.f);
+
  if (filename) fclose(lf.f);  /* close file (even in case of errors) */
+
  if (readstatus) {
+
    lua_settop(L, fnameindex);  /* ignore results from 'lua_load' */
+
    return errfile(L, "read", fnameindex);
+
  }
+
  lua_remove(L, fnameindex);
+
  return status;
+
}
+

+

+
typedef struct LoadS {
+
  const char *s;
+
  size_t size;
+
} LoadS;
+

+

+
static const char *getS (lua_State *L, void *ud, size_t *size) {
+
  LoadS *ls = (LoadS *)ud;
+
  (void)L;  /* not used */
+
  if (ls->size == 0) return NULL;
+
  *size = ls->size;
+
  ls->size = 0;
+
  return ls->s;
+
}
+

+

+
LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
+
                                 const char *name, const char *mode) {
+
  LoadS ls;
+
  ls.s = buff;
+
  ls.size = size;
+
  return lua_load(L, getS, &ls, name, mode);
+
}
+

+

+
LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
+
  return luaL_loadbuffer(L, s, strlen(s), s);
+
}
+

+
/* }====================================================== */
+

+

+

+
LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
+
  if (!lua_getmetatable(L, obj))  /* no metatable? */
+
    return LUA_TNIL;
+
  else {
+
    int tt;
+
    lua_pushstring(L, event);
+
    tt = lua_rawget(L, -2);
+
    if (tt == LUA_TNIL)  /* is metafield nil? */
+
      lua_pop(L, 2);  /* remove metatable and metafield */
+
    else
+
      lua_remove(L, -2);  /* remove only metatable */
+
    return tt;  /* return metafield type */
+
  }
+
}
+

+

+
LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
+
  obj = lua_absindex(L, obj);
+
  if (luaL_getmetafield(L, obj, event) == LUA_TNIL)  /* no metafield? */
+
    return 0;
+
  lua_pushvalue(L, obj);
+
  lua_call(L, 1, 1);
+
  return 1;
+
}
+

+

+
LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
+
  lua_Integer l;
+
  int isnum;
+
  lua_len(L, idx);
+
  l = lua_tointegerx(L, -1, &isnum);
+
  if (!isnum)
+
    luaL_error(L, "object length is not an integer");
+
  lua_pop(L, 1);  /* remove object */
+
  return l;
+
}
+

+

+
LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
+
  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)) {
+
      case LUA_TNUMBER: {
+
        if (lua_isinteger(L, idx))
+
          lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx));
+
        else
+
          lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx));
+
        break;
+
      }
+
      case LUA_TSTRING:
+
        lua_pushvalue(L, idx);
+
        break;
+
      case LUA_TBOOLEAN:
+
        lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
+
        break;
+
      case LUA_TNIL:
+
        lua_pushliteral(L, "nil");
+
        break;
+
      default: {
+
        int tt = luaL_getmetafield(L, idx, "__name");  /* try name */
+
        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;
+
      }
+
    }
+
  }
+
  return lua_tolstring(L, -1, len);
+
}
+

+

+
/*
+
** {======================================================
+
** Compatibility with 5.1 module functions
+
** =======================================================
+
*/
+
#if defined(LUA_COMPAT_MODULE)
+

+
static const char *luaL_findtable (lua_State *L, int idx,
+
                                   const char *fname, int szhint) {
+
  const char *e;
+
  if (idx) lua_pushvalue(L, idx);
+
  do {
+
    e = strchr(fname, '.');
+
    if (e == NULL) e = fname + strlen(fname);
+
    lua_pushlstring(L, fname, e - fname);
+
    if (lua_rawget(L, -2) == LUA_TNIL) {  /* no such field? */
+
      lua_pop(L, 1);  /* remove this nil */
+
      lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
+
      lua_pushlstring(L, fname, e - fname);
+
      lua_pushvalue(L, -2);
+
      lua_settable(L, -4);  /* set new table into field */
+
    }
+
    else if (!lua_istable(L, -1)) {  /* field has a non-table value? */
+
      lua_pop(L, 2);  /* remove table and value */
+
      return fname;  /* return problematic part of the name */
+
    }
+
    lua_remove(L, -2);  /* remove previous table */
+
    fname = e + 1;
+
  } while (*e == '.');
+
  return NULL;
+
}
+

+

+
/*
+
** Count number of elements in a luaL_Reg list.
+
*/
+
static int libsize (const luaL_Reg *l) {
+
  int size = 0;
+
  for (; l && l->name; l++) size++;
+
  return size;
+
}
+

+

+
/*
+
** Find or create a module table with a given name. The function
+
** first looks at the LOADED table and, if that fails, try a
+
** global variable with that name. In any case, leaves on the stack
+
** the module table.
+
*/
+
LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
+
                                 int sizehint) {
+
  luaL_findtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE, 1);
+
  if (lua_getfield(L, -1, modname) != LUA_TTABLE) {  /* no LOADED[modname]? */
+
    lua_pop(L, 1);  /* remove previous result */
+
    /* try global variable (and create one if it does not exist) */
+
    lua_pushglobaltable(L);
+
    if (luaL_findtable(L, 0, modname, sizehint) != NULL)
+
      luaL_error(L, "name conflict for module '%s'", modname);
+
    lua_pushvalue(L, -1);
+
    lua_setfield(L, -3, modname);  /* LOADED[modname] = new table */
+
  }
+
  lua_remove(L, -2);  /* remove LOADED table */
+
}
+

+

+
LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
+
                               const luaL_Reg *l, int nup) {
+
  luaL_checkversion(L);
+
  if (libname) {
+
    luaL_pushmodule(L, libname, libsize(l));  /* get/create library table */
+
    lua_insert(L, -(nup + 1));  /* move library table to below upvalues */
+
  }
+
  if (l)
+
    luaL_setfuncs(L, l, nup);
+
  else
+
    lua_pop(L, nup);  /* remove upvalues */
+
}
+

+
#endif
+
/* }====================================================== */
+

+
/*
+
** set functions from list 'l' into table at top - 'nup'; each
+
** function gets the 'nup' elements at the top as upvalues.
+
** Returns with only the table at the stack.
+
*/
+
LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
+
  luaL_checkstack(L, nup, "too many upvalues");
+
  for (; l->name != NULL; l++) {  /* fill the table with given functions */
+
    int i;
+
    for (i = 0; i < nup; i++)  /* copy upvalues to the top */
+
      lua_pushvalue(L, -nup);
+
    lua_pushcclosure(L, l->func, nup);  /* closure with those upvalues */
+
    lua_setfield(L, -(nup + 2), l->name);
+
  }
+
  lua_pop(L, nup);  /* remove upvalues */
+
}
+

+

+
/*
+
** ensure that stack[idx][fname] has a table and push that table
+
** into the stack
+
*/
+
LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
+
  if (lua_getfield(L, idx, fname) == LUA_TTABLE)
+
    return 1;  /* table already there */
+
  else {
+
    lua_pop(L, 1);  /* remove previous result */
+
    idx = lua_absindex(L, idx);
+
    lua_newtable(L);
+
    lua_pushvalue(L, -1);  /* copy to be left at top */
+
    lua_setfield(L, idx, fname);  /* assign new table to field */
+
    return 0;  /* false, because did not find table there */
+
  }
+
}
+

+

+
/*
+
** Stripped-down 'require': After checking "loaded" table, calls 'openf'
+
** to open a module, registers the result in 'package.loaded' table and,
+
** if 'glb' is true, also registers the result in the global table.
+
** Leaves resulting module on the top.
+
*/
+
LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
+
                               lua_CFunction openf, int glb) {
+
  luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
+
  lua_getfield(L, -1, modname);  /* LOADED[modname] */
+
  if (!lua_toboolean(L, -1)) {  /* package not already loaded? */
+
    lua_pop(L, 1);  /* remove field */
+
    lua_pushcfunction(L, openf);
+
    lua_pushstring(L, modname);  /* argument to open function */
+
    lua_call(L, 1, 1);  /* call 'openf' to open module */
+
    lua_pushvalue(L, -1);  /* make copy of module (call result) */
+
    lua_setfield(L, -3, modname);  /* LOADED[modname] = module */
+
  }
+
  lua_remove(L, -2);  /* remove LOADED table */
+
  if (glb) {
+
    lua_pushvalue(L, -1);  /* copy of module */
+
    lua_setglobal(L, modname);  /* _G[modname] = module */
+
  }
+
}
+

+

+
LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
+
                                                               const char *r) {
+
  const char *wild;
+
  size_t l = strlen(p);
+
  luaL_Buffer b;
+
  luaL_buffinit(L, &b);
+
  while ((wild = strstr(s, p)) != NULL) {
+
    luaL_addlstring(&b, s, wild - s);  /* push prefix */
+
    luaL_addstring(&b, r);  /* push replacement in place of pattern */
+
    s = wild + l;  /* continue after 'p' */
+
  }
+
  luaL_addstring(&b, s);  /* push last suffix */
+
  luaL_pushresult(&b);
+
  return lua_tostring(L, -1);
+
}
+

+

+
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
+
  (void)ud; (void)osize;  /* not used */
+
  if (nsize == 0) {
+
    free(ptr);
+
    return NULL;
+
  }
+
  else
+
    return realloc(ptr, nsize);
+
}
+

+

+
static int panic (lua_State *L) {
+
  lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
+
                        lua_tostring(L, -1));
+
  return 0;  /* return to Lua to abort */
+
}
+

+

+
LUALIB_API lua_State *luaL_newstate (void) {
+
  lua_State *L = lua_newstate(l_alloc, NULL);
+
  if (L) lua_atpanic(L, &panic);
+
  return L;
+
}
+

+

+
LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
+
  const lua_Number *v = lua_version(L);
+
  if (sz != LUAL_NUMSIZES)  /* check numeric types */
+
    luaL_error(L, "core and library have incompatible numeric types");
+
  if (v != lua_version(NULL))
+
    luaL_error(L, "multiple Lua VMs detected");
+
  else if (*v != ver)
+
    luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
+
                  (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v);
+
}
+

added external/lua/src/lauxlib.h
@@ -0,0 +1,264 @@
+
/*
+
** $Id: lauxlib.h,v 1.131.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Auxiliary functions for building Lua libraries
+
** See Copyright Notice in lua.h
+
*/
+

+

+
#ifndef lauxlib_h
+
#define lauxlib_h
+

+

+
#include <stddef.h>
+
#include <stdio.h>
+

+
#include "lua.h"
+

+

+

+
/* extra error code for 'luaL_loadfilex' */
+
#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 {
+
  const char *name;
+
  lua_CFunction func;
+
} luaL_Reg;
+

+

+
#define LUAL_NUMSIZES	(sizeof(lua_Integer)*16 + sizeof(lua_Number))
+

+
LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz);
+
#define luaL_checkversion(L)  \
+
	  luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
+

+
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
+
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
+
LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
+
LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
+
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
+
                                                          size_t *l);
+
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
+
                                          const char *def, size_t *l);
+
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg);
+
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
+

+
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
+
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
+
                                          lua_Integer def);
+

+
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
+
LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
+
LUALIB_API void (luaL_checkany) (lua_State *L, int arg);
+

+
LUALIB_API int   (luaL_newmetatable) (lua_State *L, const char *tname);
+
LUALIB_API void  (luaL_setmetatable) (lua_State *L, const char *tname);
+
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
+
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
+

+
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
+
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
+

+
LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
+
                                   const char *const lst[]);
+

+
LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
+
LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
+

+
/* predefined references */
+
#define LUA_NOREF       (-2)
+
#define LUA_REFNIL      (-1)
+

+
LUALIB_API int (luaL_ref) (lua_State *L, int t);
+
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
+

+
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
+
                                               const char *mode);
+

+
#define luaL_loadfile(L,f)	luaL_loadfilex(L,f,NULL)
+

+
LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
+
                                   const char *name, const char *mode);
+
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
+

+
LUALIB_API lua_State *(luaL_newstate) (void);
+

+
LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
+

+
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
+
                                                  const char *r);
+

+
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
+

+
LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
+

+
LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
+
                                  const char *msg, int level);
+

+
LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
+
                                 lua_CFunction openf, int glb);
+

+
/*
+
** ===============================================================
+
** some useful macros
+
** ===============================================================
+
*/
+

+

+
#define luaL_newlibtable(L,l)	\
+
  lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
+

+
#define luaL_newlib(L,l)  \
+
  (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
+

+
#define luaL_argcheck(L, cond,arg,extramsg)	\
+
		((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
+
#define luaL_checkstring(L,n)	(luaL_checklstring(L, (n), NULL))
+
#define luaL_optstring(L,n,d)	(luaL_optlstring(L, (n), (d), NULL))
+

+
#define luaL_typename(L,i)	lua_typename(L, lua_type(L,(i)))
+

+
#define luaL_dofile(L, fn) \
+
	(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
+

+
#define luaL_dostring(L, s) \
+
	(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
+

+
#define luaL_getmetatable(L,n)	(lua_getfield(L, LUA_REGISTRYINDEX, (n)))
+

+
#define luaL_opt(L,f,n,d)	(lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
+

+
#define luaL_loadbuffer(L,s,sz,n)	luaL_loadbufferx(L,s,sz,n,NULL)
+

+

+
/*
+
** {======================================================
+
** Generic Buffer manipulation
+
** =======================================================
+
*/
+

+
typedef struct luaL_Buffer {
+
  char *b;  /* buffer address */
+
  size_t size;  /* buffer size */
+
  size_t n;  /* number of characters in buffer */
+
  lua_State *L;
+
  char initb[LUAL_BUFFERSIZE];  /* initial buffer */
+
} luaL_Buffer;
+

+

+
#define luaL_addchar(B,c) \
+
  ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
+
   ((B)->b[(B)->n++] = (c)))
+

+
#define luaL_addsize(B,s)	((B)->n += (s))
+

+
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+
LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
+
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
+
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
+
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
+
LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
+
LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
+

+
#define luaL_prepbuffer(B)	luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
+

+
/* }====================================================== */
+

+

+

+
/*
+
** {======================================================
+
** File handles for IO library
+
** =======================================================
+
*/
+

+
/*
+
** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
+
** initial structure 'luaL_Stream' (it may contain other fields
+
** after that initial structure).
+
*/
+

+
#define LUA_FILEHANDLE          "FILE*"
+

+

+
typedef struct luaL_Stream {
+
  FILE *f;  /* stream (NULL for incompletely created streams) */
+
  lua_CFunction closef;  /* to close stream (NULL for closed streams) */
+
} luaL_Stream;
+

+
/* }====================================================== */
+

+

+

+
/* compatibility with old module system */
+
#if defined(LUA_COMPAT_MODULE)
+

+
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
+
                                   int sizehint);
+
LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
+
                                const luaL_Reg *l, int nup);
+

+
#define luaL_register(L,n,l)	(luaL_openlib(L,(n),(l),0))
+

+
#endif
+

+

+
/*
+
** {==================================================================
+
** "Abstraction Layer" for basic report of messages and errors
+
** ===================================================================
+
*/
+

+
/* print a string */
+
#if !defined(lua_writestring)
+
#define lua_writestring(s,l)   fwrite((s), sizeof(char), (l), stdout)
+
#endif
+

+
/* print a newline and flush the output */
+
#if !defined(lua_writeline)
+
#define lua_writeline()        (lua_writestring("\n", 1), fflush(stdout))
+
#endif
+

+
/* print an error message */
+
#if !defined(lua_writestringerror)
+
#define lua_writestringerror(s,p) \
+
        (fprintf(stderr, (s), (p)), fflush(stderr))
+
#endif
+

+
/* }================================================================== */
+

+

+
/*
+
** {============================================================
+
** Compatibility with deprecated conversions
+
** =============================================================
+
*/
+
#if defined(LUA_COMPAT_APIINTCASTS)
+

+
#define luaL_checkunsigned(L,a)	((lua_Unsigned)luaL_checkinteger(L,a))
+
#define luaL_optunsigned(L,a,d)	\
+
	((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
+

+
#define luaL_checkint(L,n)	((int)luaL_checkinteger(L, (n)))
+
#define luaL_optint(L,n,d)	((int)luaL_optinteger(L, (n), (d)))
+

+
#define luaL_checklong(L,n)	((long)luaL_checkinteger(L, (n)))
+
#define luaL_optlong(L,n,d)	((long)luaL_optinteger(L, (n), (d)))
+

+
#endif
+
/* }============================================================ */
+

+

+

+
#endif
+

+

added external/lua/src/lbaselib.c
@@ -0,0 +1,498 @@
+
/*
+
** $Id: lbaselib.c,v 1.314.1.1 2017/04/19 17:39:34 roberto Exp $
+
** Basic library
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lbaselib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <ctype.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+
static int luaB_print (lua_State *L) {
+
  int n = lua_gettop(L);  /* number of arguments */
+
  int i;
+
  lua_getglobal(L, "tostring");
+
  for (i=1; i<=n; i++) {
+
    const char *s;
+
    size_t l;
+
    lua_pushvalue(L, -1);  /* function to be called */
+
    lua_pushvalue(L, i);   /* value to print */
+
    lua_call(L, 1, 1);
+
    s = lua_tolstring(L, -1, &l);  /* get result */
+
    if (s == NULL)
+
      return luaL_error(L, "'tostring' must return a string to 'print'");
+
    if (i>1) lua_writestring("\t", 1);
+
    lua_writestring(s, l);
+
    lua_pop(L, 1);  /* pop result */
+
  }
+
  lua_writeline();
+
  return 0;
+
}
+

+

+
#define SPACECHARS	" \f\n\r\t\v"
+

+
static const char *b_str2int (const char *s, int base, lua_Integer *pn) {
+
  lua_Unsigned n = 0;
+
  int neg = 0;
+
  s += strspn(s, SPACECHARS);  /* skip initial spaces */
+
  if (*s == '-') { s++; neg = 1; }  /* handle signal */
+
  else if (*s == '+') s++;
+
  if (!isalnum((unsigned char)*s))  /* no digit? */
+
    return NULL;
+
  do {
+
    int digit = (isdigit((unsigned char)*s)) ? *s - '0'
+
                   : (toupper((unsigned char)*s) - 'A') + 10;
+
    if (digit >= base) return NULL;  /* invalid numeral */
+
    n = n * base + digit;
+
    s++;
+
  } while (isalnum((unsigned char)*s));
+
  s += strspn(s, SPACECHARS);  /* skip trailing spaces */
+
  *pn = (lua_Integer)((neg) ? (0u - n) : n);
+
  return s;
+
}
+

+

+
static int luaB_tonumber (lua_State *L) {
+
  if (lua_isnoneornil(L, 2)) {  /* standard conversion? */
+
    luaL_checkany(L, 1);
+
    if (lua_type(L, 1) == LUA_TNUMBER) {  /* already a number? */
+
      lua_settop(L, 1);  /* yes; return it */
+
      return 1;
+
    }
+
    else {
+
      size_t l;
+
      const char *s = lua_tolstring(L, 1, &l);
+
      if (s != NULL && lua_stringtonumber(L, s) == l + 1)
+
        return 1;  /* successful conversion to number */
+
      /* else not a number */
+
    }
+
  }
+
  else {
+
    size_t l;
+
    const char *s;
+
    lua_Integer n = 0;  /* to avoid warnings */
+
    lua_Integer base = luaL_checkinteger(L, 2);
+
    luaL_checktype(L, 1, LUA_TSTRING);  /* no numbers as strings */
+
    s = lua_tolstring(L, 1, &l);
+
    luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
+
    if (b_str2int(s, (int)base, &n) == s + l) {
+
      lua_pushinteger(L, n);
+
      return 1;
+
    }  /* else not a number */
+
  }  /* else not a number */
+
  lua_pushnil(L);  /* not a number */
+
  return 1;
+
}
+

+

+
static int luaB_error (lua_State *L) {
+
  int level = (int)luaL_optinteger(L, 2, 1);
+
  lua_settop(L, 1);
+
  if (lua_type(L, 1) == LUA_TSTRING && level > 0) {
+
    luaL_where(L, level);   /* add extra information */
+
    lua_pushvalue(L, 1);
+
    lua_concat(L, 2);
+
  }
+
  return lua_error(L);
+
}
+

+

+
static int luaB_getmetatable (lua_State *L) {
+
  luaL_checkany(L, 1);
+
  if (!lua_getmetatable(L, 1)) {
+
    lua_pushnil(L);
+
    return 1;  /* no metatable */
+
  }
+
  luaL_getmetafield(L, 1, "__metatable");
+
  return 1;  /* returns either __metatable field (if present) or metatable */
+
}
+

+

+
static int luaB_setmetatable (lua_State *L) {
+
  int t = lua_type(L, 2);
+
  luaL_checktype(L, 1, LUA_TTABLE);
+
  luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
+
                    "nil or table expected");
+
  if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
+
    return luaL_error(L, "cannot change a protected metatable");
+
  lua_settop(L, 2);
+
  lua_setmetatable(L, 1);
+
  return 1;
+
}
+

+

+
static int luaB_rawequal (lua_State *L) {
+
  luaL_checkany(L, 1);
+
  luaL_checkany(L, 2);
+
  lua_pushboolean(L, lua_rawequal(L, 1, 2));
+
  return 1;
+
}
+

+

+
static int luaB_rawlen (lua_State *L) {
+
  int t = lua_type(L, 1);
+
  luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
+
                   "table or string expected");
+
  lua_pushinteger(L, lua_rawlen(L, 1));
+
  return 1;
+
}
+

+

+
static int luaB_rawget (lua_State *L) {
+
  luaL_checktype(L, 1, LUA_TTABLE);
+
  luaL_checkany(L, 2);
+
  lua_settop(L, 2);
+
  lua_rawget(L, 1);
+
  return 1;
+
}
+

+
static int luaB_rawset (lua_State *L) {
+
  luaL_checktype(L, 1, LUA_TTABLE);
+
  luaL_checkany(L, 2);
+
  luaL_checkany(L, 3);
+
  lua_settop(L, 3);
+
  lua_rawset(L, 1);
+
  return 1;
+
}
+

+

+
static int luaB_collectgarbage (lua_State *L) {
+
  static const char *const opts[] = {"stop", "restart", "collect",
+
    "count", "step", "setpause", "setstepmul",
+
    "isrunning", NULL};
+
  static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
+
    LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
+
    LUA_GCISRUNNING};
+
  int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
+
  int ex = (int)luaL_optinteger(L, 2, 0);
+
  int res = lua_gc(L, o, ex);
+
  switch (o) {
+
    case LUA_GCCOUNT: {
+
      int b = lua_gc(L, LUA_GCCOUNTB, 0);
+
      lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024));
+
      return 1;
+
    }
+
    case LUA_GCSTEP: case LUA_GCISRUNNING: {
+
      lua_pushboolean(L, res);
+
      return 1;
+
    }
+
    default: {
+
      lua_pushinteger(L, res);
+
      return 1;
+
    }
+
  }
+
}
+

+

+
static int luaB_type (lua_State *L) {
+
  int t = lua_type(L, 1);
+
  luaL_argcheck(L, t != LUA_TNONE, 1, "value expected");
+
  lua_pushstring(L, lua_typename(L, t));
+
  return 1;
+
}
+

+

+
static int pairsmeta (lua_State *L, const char *method, int iszero,
+
                      lua_CFunction iter) {
+
  luaL_checkany(L, 1);
+
  if (luaL_getmetafield(L, 1, method) == LUA_TNIL) {  /* no metamethod? */
+
    lua_pushcfunction(L, iter);  /* will return generator, */
+
    lua_pushvalue(L, 1);  /* state, */
+
    if (iszero) lua_pushinteger(L, 0);  /* and initial value */
+
    else lua_pushnil(L);
+
  }
+
  else {
+
    lua_pushvalue(L, 1);  /* argument 'self' to metamethod */
+
    lua_call(L, 1, 3);  /* get 3 values from metamethod */
+
  }
+
  return 3;
+
}
+

+

+
static int luaB_next (lua_State *L) {
+
  luaL_checktype(L, 1, LUA_TTABLE);
+
  lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
+
  if (lua_next(L, 1))
+
    return 2;
+
  else {
+
    lua_pushnil(L);
+
    return 1;
+
  }
+
}
+

+

+
static int luaB_pairs (lua_State *L) {
+
  return pairsmeta(L, "__pairs", 0, luaB_next);
+
}
+

+

+
/*
+
** Traversal function for 'ipairs'
+
*/
+
static int ipairsaux (lua_State *L) {
+
  lua_Integer i = luaL_checkinteger(L, 2) + 1;
+
  lua_pushinteger(L, i);
+
  return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
+
}
+

+

+
/*
+
** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
+
** (The given "table" may not be a table.)
+
*/
+
static int luaB_ipairs (lua_State *L) {
+
#if defined(LUA_COMPAT_IPAIRS)
+
  return pairsmeta(L, "__ipairs", 1, ipairsaux);
+
#else
+
  luaL_checkany(L, 1);
+
  lua_pushcfunction(L, ipairsaux);  /* iteration function */
+
  lua_pushvalue(L, 1);  /* state */
+
  lua_pushinteger(L, 0);  /* initial value */
+
  return 3;
+
#endif
+
}
+

+

+
static int load_aux (lua_State *L, int status, int envidx) {
+
  if (status == LUA_OK) {
+
    if (envidx != 0) {  /* 'env' parameter? */
+
      lua_pushvalue(L, envidx);  /* environment for loaded function */
+
      if (!lua_setupvalue(L, -2, 1))  /* set it as 1st upvalue */
+
        lua_pop(L, 1);  /* remove 'env' if not used by previous call */
+
    }
+
    return 1;
+
  }
+
  else {  /* error (message is on top of the stack) */
+
    lua_pushnil(L);
+
    lua_insert(L, -2);  /* put before error message */
+
    return 2;  /* return nil plus error message */
+
  }
+
}
+

+

+
static int luaB_loadfile (lua_State *L) {
+
  const char *fname = luaL_optstring(L, 1, NULL);
+
  const char *mode = luaL_optstring(L, 2, NULL);
+
  int env = (!lua_isnone(L, 3) ? 3 : 0);  /* 'env' index or 0 if no 'env' */
+
  int status = luaL_loadfilex(L, fname, mode);
+
  return load_aux(L, status, env);
+
}
+

+

+
/*
+
** {======================================================
+
** Generic Read function
+
** =======================================================
+
*/
+

+

+
/*
+
** reserved slot, above all arguments, to hold a copy of the returned
+
** string to avoid it being collected while parsed. 'load' has four
+
** optional arguments (chunk, source name, mode, and environment).
+
*/
+
#define RESERVEDSLOT	5
+

+

+
/*
+
** Reader for generic 'load' function: 'lua_load' uses the
+
** stack for internal stuff, so the reader cannot change the
+
** stack top. Instead, it keeps its resulting string in a
+
** reserved slot inside the stack.
+
*/
+
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
+
  (void)(ud);  /* not used */
+
  luaL_checkstack(L, 2, "too many nested functions");
+
  lua_pushvalue(L, 1);  /* get function */
+
  lua_call(L, 0, 1);  /* call it */
+
  if (lua_isnil(L, -1)) {
+
    lua_pop(L, 1);  /* pop result */
+
    *size = 0;
+
    return NULL;
+
  }
+
  else if (!lua_isstring(L, -1))
+
    luaL_error(L, "reader function must return a string");
+
  lua_replace(L, RESERVEDSLOT);  /* save string in reserved slot */
+
  return lua_tolstring(L, RESERVEDSLOT, size);
+
}
+

+

+
static int luaB_load (lua_State *L) {
+
  int status;
+
  size_t l;
+
  const char *s = lua_tolstring(L, 1, &l);
+
  const char *mode = luaL_optstring(L, 3, "bt");
+
  int env = (!lua_isnone(L, 4) ? 4 : 0);  /* 'env' index or 0 if no 'env' */
+
  if (s != NULL) {  /* loading a string? */
+
    const char *chunkname = luaL_optstring(L, 2, s);
+
    status = luaL_loadbufferx(L, s, l, chunkname, mode);
+
  }
+
  else {  /* loading from a reader function */
+
    const char *chunkname = luaL_optstring(L, 2, "=(load)");
+
    luaL_checktype(L, 1, LUA_TFUNCTION);
+
    lua_settop(L, RESERVEDSLOT);  /* create reserved slot */
+
    status = lua_load(L, generic_reader, NULL, chunkname, mode);
+
  }
+
  return load_aux(L, status, env);
+
}
+

+
/* }====================================================== */
+

+

+
static int dofilecont (lua_State *L, int d1, lua_KContext d2) {
+
  (void)d1;  (void)d2;  /* only to match 'lua_Kfunction' prototype */
+
  return lua_gettop(L) - 1;
+
}
+

+

+
static int luaB_dofile (lua_State *L) {
+
  const char *fname = luaL_optstring(L, 1, NULL);
+
  lua_settop(L, 1);
+
  if (luaL_loadfile(L, fname) != LUA_OK)
+
    return lua_error(L);
+
  lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
+
  return dofilecont(L, 0, 0);
+
}
+

+

+
static int luaB_assert (lua_State *L) {
+
  if (lua_toboolean(L, 1))  /* condition is true? */
+
    return lua_gettop(L);  /* return all arguments */
+
  else {  /* error */
+
    luaL_checkany(L, 1);  /* there must be a condition */
+
    lua_remove(L, 1);  /* remove it */
+
    lua_pushliteral(L, "assertion failed!");  /* default message */
+
    lua_settop(L, 1);  /* leave only message (default if no other one) */
+
    return luaB_error(L);  /* call 'error' */
+
  }
+
}
+

+

+
static int luaB_select (lua_State *L) {
+
  int n = lua_gettop(L);
+
  if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
+
    lua_pushinteger(L, n-1);
+
    return 1;
+
  }
+
  else {
+
    lua_Integer i = luaL_checkinteger(L, 1);
+
    if (i < 0) i = n + i;
+
    else if (i > n) i = n;
+
    luaL_argcheck(L, 1 <= i, 1, "index out of range");
+
    return n - (int)i;
+
  }
+
}
+

+

+
/*
+
** Continuation function for 'pcall' and 'xpcall'. Both functions
+
** already pushed a 'true' before doing the call, so in case of success
+
** 'finishpcall' only has to return everything in the stack minus
+
** 'extra' values (where 'extra' is exactly the number of items to be
+
** ignored).
+
*/
+
static int finishpcall (lua_State *L, int status, lua_KContext extra) {
+
  if (status != LUA_OK && status != LUA_YIELD) {  /* error? */
+
    lua_pushboolean(L, 0);  /* first result (false) */
+
    lua_pushvalue(L, -2);  /* error message */
+
    return 2;  /* return false, msg */
+
  }
+
  else
+
    return lua_gettop(L) - (int)extra;  /* return all results */
+
}
+

+

+
static int luaB_pcall (lua_State *L) {
+
  int status;
+
  luaL_checkany(L, 1);
+
  lua_pushboolean(L, 1);  /* first result if no errors */
+
  lua_insert(L, 1);  /* put it in place */
+
  status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall);
+
  return finishpcall(L, status, 0);
+
}
+

+

+
/*
+
** Do a protected call with error handling. After 'lua_rotate', the
+
** stack will have <f, err, true, f, [args...]>; so, the function passes
+
** 2 to 'finishpcall' to skip the 2 first values when returning results.
+
*/
+
static int luaB_xpcall (lua_State *L) {
+
  int status;
+
  int n = lua_gettop(L);
+
  luaL_checktype(L, 2, LUA_TFUNCTION);  /* check error function */
+
  lua_pushboolean(L, 1);  /* first result */
+
  lua_pushvalue(L, 1);  /* function */
+
  lua_rotate(L, 3, 2);  /* move them below function's arguments */
+
  status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall);
+
  return finishpcall(L, status, 2);
+
}
+

+

+
static int luaB_tostring (lua_State *L) {
+
  luaL_checkany(L, 1);
+
  luaL_tolstring(L, 1, NULL);
+
  return 1;
+
}
+

+

+
static const luaL_Reg base_funcs[] = {
+
  {"assert", luaB_assert},
+
  {"collectgarbage", luaB_collectgarbage},
+
  {"dofile", luaB_dofile},
+
  {"error", luaB_error},
+
  {"getmetatable", luaB_getmetatable},
+
  {"ipairs", luaB_ipairs},
+
  {"loadfile", luaB_loadfile},
+
  {"load", luaB_load},
+
#if defined(LUA_COMPAT_LOADSTRING)
+
  {"loadstring", luaB_load},
+
#endif
+
  {"next", luaB_next},
+
  {"pairs", luaB_pairs},
+
  {"pcall", luaB_pcall},
+
  {"print", luaB_print},
+
  {"rawequal", luaB_rawequal},
+
  {"rawlen", luaB_rawlen},
+
  {"rawget", luaB_rawget},
+
  {"rawset", luaB_rawset},
+
  {"select", luaB_select},
+
  {"setmetatable", luaB_setmetatable},
+
  {"tonumber", luaB_tonumber},
+
  {"tostring", luaB_tostring},
+
  {"type", luaB_type},
+
  {"xpcall", luaB_xpcall},
+
  /* placeholders */
+
  {"_G", NULL},
+
  {"_VERSION", NULL},
+
  {NULL, NULL}
+
};
+

+

+
LUAMOD_API int luaopen_base (lua_State *L) {
+
  /* open lib into global table */
+
  lua_pushglobaltable(L);
+
  luaL_setfuncs(L, base_funcs, 0);
+
  /* set global _G */
+
  lua_pushvalue(L, -1);
+
  lua_setfield(L, -2, "_G");
+
  /* set global _VERSION */
+
  lua_pushliteral(L, LUA_VERSION);
+
  lua_setfield(L, -2, "_VERSION");
+
  return 1;
+
}
+

added external/lua/src/lbitlib.c
@@ -0,0 +1,233 @@
+
/*
+
** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Standard library for bitwise operations
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lbitlib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+
#if defined(LUA_COMPAT_BITLIB)		/* { */
+

+

+
#define pushunsigned(L,n)	lua_pushinteger(L, (lua_Integer)(n))
+
#define checkunsigned(L,i)	((lua_Unsigned)luaL_checkinteger(L,i))
+

+

+
/* number of bits to consider in a number */
+
#if !defined(LUA_NBITS)
+
#define LUA_NBITS	32
+
#endif
+

+

+
/*
+
** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must
+
** be made in two parts to avoid problems when LUA_NBITS is equal to the
+
** number of bits in a lua_Unsigned.)
+
*/
+
#define ALLONES		(~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
+

+

+
/* macro to trim extra bits */
+
#define trim(x)		((x) & ALLONES)
+

+

+
/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
+
#define mask(n)		(~((ALLONES << 1) << ((n) - 1)))
+

+

+

+
static lua_Unsigned andaux (lua_State *L) {
+
  int i, n = lua_gettop(L);
+
  lua_Unsigned r = ~(lua_Unsigned)0;
+
  for (i = 1; i <= n; i++)
+
    r &= checkunsigned(L, i);
+
  return trim(r);
+
}
+

+

+
static int b_and (lua_State *L) {
+
  lua_Unsigned r = andaux(L);
+
  pushunsigned(L, r);
+
  return 1;
+
}
+

+

+
static int b_test (lua_State *L) {
+
  lua_Unsigned r = andaux(L);
+
  lua_pushboolean(L, r != 0);
+
  return 1;
+
}
+

+

+
static int b_or (lua_State *L) {
+
  int i, n = lua_gettop(L);
+
  lua_Unsigned r = 0;
+
  for (i = 1; i <= n; i++)
+
    r |= checkunsigned(L, i);
+
  pushunsigned(L, trim(r));
+
  return 1;
+
}
+

+

+
static int b_xor (lua_State *L) {
+
  int i, n = lua_gettop(L);
+
  lua_Unsigned r = 0;
+
  for (i = 1; i <= n; i++)
+
    r ^= checkunsigned(L, i);
+
  pushunsigned(L, trim(r));
+
  return 1;
+
}
+

+

+
static int b_not (lua_State *L) {
+
  lua_Unsigned r = ~checkunsigned(L, 1);
+
  pushunsigned(L, trim(r));
+
  return 1;
+
}
+

+

+
static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) {
+
  if (i < 0) {  /* shift right? */
+
    i = -i;
+
    r = trim(r);
+
    if (i >= LUA_NBITS) r = 0;
+
    else r >>= i;
+
  }
+
  else {  /* shift left */
+
    if (i >= LUA_NBITS) r = 0;
+
    else r <<= i;
+
    r = trim(r);
+
  }
+
  pushunsigned(L, r);
+
  return 1;
+
}
+

+

+
static int b_lshift (lua_State *L) {
+
  return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2));
+
}
+

+

+
static int b_rshift (lua_State *L) {
+
  return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2));
+
}
+

+

+
static int b_arshift (lua_State *L) {
+
  lua_Unsigned r = checkunsigned(L, 1);
+
  lua_Integer i = luaL_checkinteger(L, 2);
+
  if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
+
    return b_shift(L, r, -i);
+
  else {  /* arithmetic shift for 'negative' number */
+
    if (i >= LUA_NBITS) r = ALLONES;
+
    else
+
      r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i));  /* add signal bit */
+
    pushunsigned(L, r);
+
    return 1;
+
  }
+
}
+

+

+
static int b_rot (lua_State *L, lua_Integer d) {
+
  lua_Unsigned r = checkunsigned(L, 1);
+
  int i = d & (LUA_NBITS - 1);  /* i = d % NBITS */
+
  r = trim(r);
+
  if (i != 0)  /* avoid undefined shift of LUA_NBITS when i == 0 */
+
    r = (r << i) | (r >> (LUA_NBITS - i));
+
  pushunsigned(L, trim(r));
+
  return 1;
+
}
+

+

+
static int b_lrot (lua_State *L) {
+
  return b_rot(L, luaL_checkinteger(L, 2));
+
}
+

+

+
static int b_rrot (lua_State *L) {
+
  return b_rot(L, -luaL_checkinteger(L, 2));
+
}
+

+

+
/*
+
** get field and width arguments for field-manipulation functions,
+
** checking whether they are valid.
+
** ('luaL_error' called without 'return' to avoid later warnings about
+
** 'width' being used uninitialized.)
+
*/
+
static int fieldargs (lua_State *L, int farg, int *width) {
+
  lua_Integer f = luaL_checkinteger(L, farg);
+
  lua_Integer w = luaL_optinteger(L, farg + 1, 1);
+
  luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
+
  luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
+
  if (f + w > LUA_NBITS)
+
    luaL_error(L, "trying to access non-existent bits");
+
  *width = (int)w;
+
  return (int)f;
+
}
+

+

+
static int b_extract (lua_State *L) {
+
  int w;
+
  lua_Unsigned r = trim(checkunsigned(L, 1));
+
  int f = fieldargs(L, 2, &w);
+
  r = (r >> f) & mask(w);
+
  pushunsigned(L, r);
+
  return 1;
+
}
+

+

+
static int b_replace (lua_State *L) {
+
  int w;
+
  lua_Unsigned r = trim(checkunsigned(L, 1));
+
  lua_Unsigned v = trim(checkunsigned(L, 2));
+
  int f = fieldargs(L, 3, &w);
+
  lua_Unsigned m = mask(w);
+
  r = (r & ~(m << f)) | ((v & m) << f);
+
  pushunsigned(L, r);
+
  return 1;
+
}
+

+

+
static const luaL_Reg bitlib[] = {
+
  {"arshift", b_arshift},
+
  {"band", b_and},
+
  {"bnot", b_not},
+
  {"bor", b_or},
+
  {"bxor", b_xor},
+
  {"btest", b_test},
+
  {"extract", b_extract},
+
  {"lrotate", b_lrot},
+
  {"lshift", b_lshift},
+
  {"replace", b_replace},
+
  {"rrotate", b_rrot},
+
  {"rshift", b_rshift},
+
  {NULL, NULL}
+
};
+

+

+

+
LUAMOD_API int luaopen_bit32 (lua_State *L) {
+
  luaL_newlib(L, bitlib);
+
  return 1;
+
}
+

+

+
#else					/* }{ */
+

+

+
LUAMOD_API int luaopen_bit32 (lua_State *L) {
+
  return luaL_error(L, "library 'bit32' has been deprecated");
+
}
+

+
#endif					/* } */
added external/lua/src/lcode.c
@@ -0,0 +1,1203 @@
+
/*
+
** $Id: lcode.c,v 2.112.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Code generator for Lua
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lcode_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <math.h>
+
#include <stdlib.h>
+

+
#include "lua.h"
+

+
#include "lcode.h"
+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lgc.h"
+
#include "llex.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lopcodes.h"
+
#include "lparser.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "lvm.h"
+

+

+
/* Maximum number of registers in a Lua function (must fit in 8 bits) */
+
#define MAXREGS		255
+

+

+
#define hasjumps(e)	((e)->t != (e)->f)
+

+

+
/*
+
** If expression is a numeric constant, fills 'v' with its value
+
** and returns 1. Otherwise, returns 0.
+
*/
+
static int tonumeral(const expdesc *e, TValue *v) {
+
  if (hasjumps(e))
+
    return 0;  /* not a numeral */
+
  switch (e->k) {
+
    case VKINT:
+
      if (v) setivalue(v, e->u.ival);
+
      return 1;
+
    case VKFLT:
+
      if (v) setfltvalue(v, e->u.nval);
+
      return 1;
+
    default: return 0;
+
  }
+
}
+

+

+
/*
+
** Create a OP_LOADNIL instruction, but try to optimize: if the previous
+
** instruction is also OP_LOADNIL and ranges are compatible, adjust
+
** range of previous instruction instead of emitting a new one. (For
+
** instance, 'local a; local b' will generate a single opcode.)
+
*/
+
void luaK_nil (FuncState *fs, int from, int n) {
+
  Instruction *previous;
+
  int l = from + n - 1;  /* last register to set nil */
+
  if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
+
    previous = &fs->f->code[fs->pc-1];
+
    if (GET_OPCODE(*previous) == OP_LOADNIL) {  /* previous is LOADNIL? */
+
      int pfrom = GETARG_A(*previous);  /* get previous range */
+
      int pl = pfrom + GETARG_B(*previous);
+
      if ((pfrom <= from && from <= pl + 1) ||
+
          (from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
+
        if (pfrom < from) from = pfrom;  /* from = min(from, pfrom) */
+
        if (pl > l) l = pl;  /* l = max(l, pl) */
+
        SETARG_A(*previous, from);
+
        SETARG_B(*previous, l - from);
+
        return;
+
      }
+
    }  /* else go through */
+
  }
+
  luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0);  /* else no optimization */
+
}
+

+

+
/*
+
** Gets the destination address of a jump instruction. Used to traverse
+
** a list of jumps.
+
*/
+
static int getjump (FuncState *fs, int pc) {
+
  int offset = GETARG_sBx(fs->f->code[pc]);
+
  if (offset == NO_JUMP)  /* point to itself represents end of list */
+
    return NO_JUMP;  /* end of list */
+
  else
+
    return (pc+1)+offset;  /* turn offset into absolute position */
+
}
+

+

+
/*
+
** Fix jump instruction at position 'pc' to jump to 'dest'.
+
** (Jump addresses are relative in Lua)
+
*/
+
static void fixjump (FuncState *fs, int pc, int dest) {
+
  Instruction *jmp = &fs->f->code[pc];
+
  int offset = dest - (pc + 1);
+
  lua_assert(dest != NO_JUMP);
+
  if (abs(offset) > MAXARG_sBx)
+
    luaX_syntaxerror(fs->ls, "control structure too long");
+
  SETARG_sBx(*jmp, offset);
+
}
+

+

+
/*
+
** Concatenate jump-list 'l2' into jump-list 'l1'
+
*/
+
void luaK_concat (FuncState *fs, int *l1, int l2) {
+
  if (l2 == NO_JUMP) return;  /* nothing to concatenate? */
+
  else if (*l1 == NO_JUMP)  /* no original list? */
+
    *l1 = l2;  /* 'l1' points to 'l2' */
+
  else {
+
    int list = *l1;
+
    int next;
+
    while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
+
      list = next;
+
    fixjump(fs, list, l2);  /* last element links to 'l2' */
+
  }
+
}
+

+

+
/*
+
** Create a jump instruction and return its position, so its destination
+
** can be fixed later (with 'fixjump'). If there are jumps to
+
** this position (kept in 'jpc'), link them all together so that
+
** 'patchlistaux' will fix all them directly to the final destination.
+
*/
+
int luaK_jump (FuncState *fs) {
+
  int jpc = fs->jpc;  /* save list of jumps to here */
+
  int j;
+
  fs->jpc = NO_JUMP;  /* no more jumps to here */
+
  j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
+
  luaK_concat(fs, &j, jpc);  /* keep them on hold */
+
  return j;
+
}
+

+

+
/*
+
** Code a 'return' instruction
+
*/
+
void luaK_ret (FuncState *fs, int first, int nret) {
+
  luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
+
}
+

+

+
/*
+
** Code a "conditional jump", that is, a test or comparison opcode
+
** followed by a jump. Return jump position.
+
*/
+
static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
+
  luaK_codeABC(fs, op, A, B, C);
+
  return luaK_jump(fs);
+
}
+

+

+
/*
+
** returns current 'pc' and marks it as a jump target (to avoid wrong
+
** optimizations with consecutive instructions not in the same basic block).
+
*/
+
int luaK_getlabel (FuncState *fs) {
+
  fs->lasttarget = fs->pc;
+
  return fs->pc;
+
}
+

+

+
/*
+
** Returns the position of the instruction "controlling" a given
+
** jump (that is, its condition), or the jump itself if it is
+
** unconditional.
+
*/
+
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
+
  Instruction *pi = &fs->f->code[pc];
+
  if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
+
    return pi-1;
+
  else
+
    return pi;
+
}
+

+

+
/*
+
** Patch destination register for a TESTSET instruction.
+
** If instruction in position 'node' is not a TESTSET, return 0 ("fails").
+
** Otherwise, if 'reg' is not 'NO_REG', set it as the destination
+
** register. Otherwise, change instruction to a simple 'TEST' (produces
+
** no register value)
+
*/
+
static int patchtestreg (FuncState *fs, int node, int reg) {
+
  Instruction *i = getjumpcontrol(fs, node);
+
  if (GET_OPCODE(*i) != OP_TESTSET)
+
    return 0;  /* cannot patch other instructions */
+
  if (reg != NO_REG && reg != GETARG_B(*i))
+
    SETARG_A(*i, reg);
+
  else {
+
     /* no register to put value or register already has the value;
+
        change instruction to simple test */
+
    *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
+
  }
+
  return 1;
+
}
+

+

+
/*
+
** Traverse a list of tests ensuring no one produces a value
+
*/
+
static void removevalues (FuncState *fs, int list) {
+
  for (; list != NO_JUMP; list = getjump(fs, list))
+
      patchtestreg(fs, list, NO_REG);
+
}
+

+

+
/*
+
** Traverse a list of tests, patching their destination address and
+
** registers: tests producing values jump to 'vtarget' (and put their
+
** values in 'reg'), other tests jump to 'dtarget'.
+
*/
+
static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
+
                          int dtarget) {
+
  while (list != NO_JUMP) {
+
    int next = getjump(fs, list);
+
    if (patchtestreg(fs, list, reg))
+
      fixjump(fs, list, vtarget);
+
    else
+
      fixjump(fs, list, dtarget);  /* jump to default target */
+
    list = next;
+
  }
+
}
+

+

+
/*
+
** Ensure all pending jumps to current position are fixed (jumping
+
** to current position with no values) and reset list of pending
+
** jumps
+
*/
+
static void dischargejpc (FuncState *fs) {
+
  patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
+
  fs->jpc = NO_JUMP;
+
}
+

+

+
/*
+
** Add elements in 'list' to list of pending jumps to "here"
+
** (current position)
+
*/
+
void luaK_patchtohere (FuncState *fs, int list) {
+
  luaK_getlabel(fs);  /* mark "here" as a jump target */
+
  luaK_concat(fs, &fs->jpc, list);
+
}
+

+

+
/*
+
** Path all jumps in 'list' to jump to 'target'.
+
** (The assert means that we cannot fix a jump to a forward address
+
** because we only know addresses once code is generated.)
+
*/
+
void luaK_patchlist (FuncState *fs, int list, int target) {
+
  if (target == fs->pc)  /* 'target' is current position? */
+
    luaK_patchtohere(fs, list);  /* add list to pending jumps */
+
  else {
+
    lua_assert(target < fs->pc);
+
    patchlistaux(fs, list, target, NO_REG, target);
+
  }
+
}
+

+

+
/*
+
** Path all jumps in 'list' to close upvalues up to given 'level'
+
** (The assertion checks that jumps either were closing nothing
+
** or were closing higher levels, from inner blocks.)
+
*/
+
void luaK_patchclose (FuncState *fs, int list, int level) {
+
  level++;  /* argument is +1 to reserve 0 as non-op */
+
  for (; list != NO_JUMP; list = getjump(fs, list)) {
+
    lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
+
                (GETARG_A(fs->f->code[list]) == 0 ||
+
                 GETARG_A(fs->f->code[list]) >= level));
+
    SETARG_A(fs->f->code[list], level);
+
  }
+
}
+

+

+
/*
+
** Emit instruction 'i', checking for array sizes and saving also its
+
** line information. Return 'i' position.
+
*/
+
static int luaK_code (FuncState *fs, Instruction i) {
+
  Proto *f = fs->f;
+
  dischargejpc(fs);  /* 'pc' will change */
+
  /* put new instruction in code array */
+
  luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
+
                  MAX_INT, "opcodes");
+
  f->code[fs->pc] = i;
+
  /* save corresponding line information */
+
  luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
+
                  MAX_INT, "opcodes");
+
  f->lineinfo[fs->pc] = fs->ls->lastline;
+
  return fs->pc++;
+
}
+

+

+
/*
+
** Format and emit an 'iABC' instruction. (Assertions check consistency
+
** of parameters versus opcode.)
+
*/
+
int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
+
  lua_assert(getOpMode(o) == iABC);
+
  lua_assert(getBMode(o) != OpArgN || b == 0);
+
  lua_assert(getCMode(o) != OpArgN || c == 0);
+
  lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
+
  return luaK_code(fs, CREATE_ABC(o, a, b, c));
+
}
+

+

+
/*
+
** Format and emit an 'iABx' instruction.
+
*/
+
int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
+
  lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
+
  lua_assert(getCMode(o) == OpArgN);
+
  lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
+
  return luaK_code(fs, CREATE_ABx(o, a, bc));
+
}
+

+

+
/*
+
** Emit an "extra argument" instruction (format 'iAx')
+
*/
+
static int codeextraarg (FuncState *fs, int a) {
+
  lua_assert(a <= MAXARG_Ax);
+
  return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
+
}
+

+

+
/*
+
** Emit a "load constant" instruction, using either 'OP_LOADK'
+
** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX'
+
** instruction with "extra argument".
+
*/
+
int luaK_codek (FuncState *fs, int reg, int k) {
+
  if (k <= MAXARG_Bx)
+
    return luaK_codeABx(fs, OP_LOADK, reg, k);
+
  else {
+
    int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
+
    codeextraarg(fs, k);
+
    return p;
+
  }
+
}
+

+

+
/*
+
** Check register-stack level, keeping track of its maximum size
+
** in field 'maxstacksize'
+
*/
+
void luaK_checkstack (FuncState *fs, int n) {
+
  int newstack = fs->freereg + n;
+
  if (newstack > fs->f->maxstacksize) {
+
    if (newstack >= MAXREGS)
+
      luaX_syntaxerror(fs->ls,
+
        "function or expression needs too many registers");
+
    fs->f->maxstacksize = cast_byte(newstack);
+
  }
+
}
+

+

+
/*
+
** Reserve 'n' registers in register stack
+
*/
+
void luaK_reserveregs (FuncState *fs, int n) {
+
  luaK_checkstack(fs, n);
+
  fs->freereg += n;
+
}
+

+

+
/*
+
** Free register 'reg', if it is neither a constant index nor
+
** a local variable.
+
)
+
*/
+
static void freereg (FuncState *fs, int reg) {
+
  if (!ISK(reg) && reg >= fs->nactvar) {
+
    fs->freereg--;
+
    lua_assert(reg == fs->freereg);
+
  }
+
}
+

+

+
/*
+
** Free register used by expression 'e' (if any)
+
*/
+
static void freeexp (FuncState *fs, expdesc *e) {
+
  if (e->k == VNONRELOC)
+
    freereg(fs, e->u.info);
+
}
+

+

+
/*
+
** Free registers used by expressions 'e1' and 'e2' (if any) in proper
+
** order.
+
*/
+
static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
+
  int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1;
+
  int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1;
+
  if (r1 > r2) {
+
    freereg(fs, r1);
+
    freereg(fs, r2);
+
  }
+
  else {
+
    freereg(fs, r2);
+
    freereg(fs, r1);
+
  }
+
}
+

+

+
/*
+
** Add constant 'v' to prototype's list of constants (field 'k').
+
** Use scanner's table to cache position of constants in constant list
+
** and try to reuse constants. Because some values should not be used
+
** as keys (nil cannot be a key, integer keys can collapse with float
+
** keys), the caller must provide a useful 'key' for indexing the cache.
+
*/
+
static int addk (FuncState *fs, TValue *key, TValue *v) {
+
  lua_State *L = fs->ls->L;
+
  Proto *f = fs->f;
+
  TValue *idx = luaH_set(L, fs->ls->h, key);  /* index scanner table */
+
  int k, oldsize;
+
  if (ttisinteger(idx)) {  /* is there an index there? */
+
    k = cast_int(ivalue(idx));
+
    /* correct value? (warning: must distinguish floats from integers!) */
+
    if (k < fs->nk && ttype(&f->k[k]) == ttype(v) &&
+
                      luaV_rawequalobj(&f->k[k], v))
+
      return k;  /* reuse index */
+
  }
+
  /* constant not found; create a new entry */
+
  oldsize = f->sizek;
+
  k = fs->nk;
+
  /* numerical value does not need GC barrier;
+
     table has no metatable, so it does not need to invalidate cache */
+
  setivalue(idx, k);
+
  luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
+
  while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
+
  setobj(L, &f->k[k], v);
+
  fs->nk++;
+
  luaC_barrier(L, f, v);
+
  return k;
+
}
+

+

+
/*
+
** Add a string to list of constants and return its index.
+
*/
+
int luaK_stringK (FuncState *fs, TString *s) {
+
  TValue o;
+
  setsvalue(fs->ls->L, &o, s);
+
  return addk(fs, &o, &o);  /* use string itself as key */
+
}
+

+

+
/*
+
** Add an integer to list of constants and return its index.
+
** Integers use userdata as keys to avoid collision with floats with
+
** same value; conversion to 'void*' is used only for hashing, so there
+
** are no "precision" problems.
+
*/
+
int luaK_intK (FuncState *fs, lua_Integer n) {
+
  TValue k, o;
+
  setpvalue(&k, cast(void*, cast(size_t, n)));
+
  setivalue(&o, n);
+
  return addk(fs, &k, &o);
+
}
+

+
/*
+
** Add a float to list of constants and return its index.
+
*/
+
static int luaK_numberK (FuncState *fs, lua_Number r) {
+
  TValue o;
+
  setfltvalue(&o, r);
+
  return addk(fs, &o, &o);  /* use number itself as key */
+
}
+

+

+
/*
+
** Add a boolean to list of constants and return its index.
+
*/
+
static int boolK (FuncState *fs, int b) {
+
  TValue o;
+
  setbvalue(&o, b);
+
  return addk(fs, &o, &o);  /* use boolean itself as key */
+
}
+

+

+
/*
+
** Add nil to list of constants and return its index.
+
*/
+
static int nilK (FuncState *fs) {
+
  TValue k, v;
+
  setnilvalue(&v);
+
  /* cannot use nil as key; instead use table itself to represent nil */
+
  sethvalue(fs->ls->L, &k, fs->ls->h);
+
  return addk(fs, &k, &v);
+
}
+

+

+
/*
+
** Fix an expression to return the number of results 'nresults'.
+
** Either 'e' is a multi-ret expression (function call or vararg)
+
** or 'nresults' is LUA_MULTRET (as any expression can satisfy that).
+
*/
+
void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
+
  if (e->k == VCALL) {  /* expression is an open function call? */
+
    SETARG_C(getinstruction(fs, e), nresults + 1);
+
  }
+
  else if (e->k == VVARARG) {
+
    Instruction *pc = &getinstruction(fs, e);
+
    SETARG_B(*pc, nresults + 1);
+
    SETARG_A(*pc, fs->freereg);
+
    luaK_reserveregs(fs, 1);
+
  }
+
  else lua_assert(nresults == LUA_MULTRET);
+
}
+

+

+
/*
+
** Fix an expression to return one result.
+
** If expression is not a multi-ret expression (function call or
+
** vararg), it already returns one result, so nothing needs to be done.
+
** Function calls become VNONRELOC expressions (as its result comes
+
** fixed in the base register of the call), while vararg expressions
+
** become VRELOCABLE (as OP_VARARG puts its results where it wants).
+
** (Calls are created returning one result, so that does not need
+
** to be fixed.)
+
*/
+
void luaK_setoneret (FuncState *fs, expdesc *e) {
+
  if (e->k == VCALL) {  /* expression is an open function call? */
+
    /* already returns 1 value */
+
    lua_assert(GETARG_C(getinstruction(fs, e)) == 2);
+
    e->k = VNONRELOC;  /* result has fixed position */
+
    e->u.info = GETARG_A(getinstruction(fs, e));
+
  }
+
  else if (e->k == VVARARG) {
+
    SETARG_B(getinstruction(fs, e), 2);
+
    e->k = VRELOCABLE;  /* can relocate its simple result */
+
  }
+
}
+

+

+
/*
+
** Ensure that expression 'e' is not a variable.
+
*/
+
void luaK_dischargevars (FuncState *fs, expdesc *e) {
+
  switch (e->k) {
+
    case VLOCAL: {  /* already in a register */
+
      e->k = VNONRELOC;  /* becomes a non-relocatable value */
+
      break;
+
    }
+
    case VUPVAL: {  /* move value to some (pending) register */
+
      e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
+
      e->k = VRELOCABLE;
+
      break;
+
    }
+
    case VINDEXED: {
+
      OpCode op;
+
      freereg(fs, e->u.ind.idx);
+
      if (e->u.ind.vt == VLOCAL) {  /* is 't' in a register? */
+
        freereg(fs, e->u.ind.t);
+
        op = OP_GETTABLE;
+
      }
+
      else {
+
        lua_assert(e->u.ind.vt == VUPVAL);
+
        op = OP_GETTABUP;  /* 't' is in an upvalue */
+
      }
+
      e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
+
      e->k = VRELOCABLE;
+
      break;
+
    }
+
    case VVARARG: case VCALL: {
+
      luaK_setoneret(fs, e);
+
      break;
+
    }
+
    default: break;  /* there is one value available (somewhere) */
+
  }
+
}
+

+

+
/*
+
** Ensures expression value is in register 'reg' (and therefore
+
** 'e' will become a non-relocatable expression).
+
*/
+
static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
+
  luaK_dischargevars(fs, e);
+
  switch (e->k) {
+
    case VNIL: {
+
      luaK_nil(fs, reg, 1);
+
      break;
+
    }
+
    case VFALSE: case VTRUE: {
+
      luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
+
      break;
+
    }
+
    case VK: {
+
      luaK_codek(fs, reg, e->u.info);
+
      break;
+
    }
+
    case VKFLT: {
+
      luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
+
      break;
+
    }
+
    case VKINT: {
+
      luaK_codek(fs, reg, luaK_intK(fs, e->u.ival));
+
      break;
+
    }
+
    case VRELOCABLE: {
+
      Instruction *pc = &getinstruction(fs, e);
+
      SETARG_A(*pc, reg);  /* instruction will put result in 'reg' */
+
      break;
+
    }
+
    case VNONRELOC: {
+
      if (reg != e->u.info)
+
        luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
+
      break;
+
    }
+
    default: {
+
      lua_assert(e->k == VJMP);
+
      return;  /* nothing to do... */
+
    }
+
  }
+
  e->u.info = reg;
+
  e->k = VNONRELOC;
+
}
+

+

+
/*
+
** Ensures expression value is in any register.
+
*/
+
static void discharge2anyreg (FuncState *fs, expdesc *e) {
+
  if (e->k != VNONRELOC) {  /* no fixed register yet? */
+
    luaK_reserveregs(fs, 1);  /* get a register */
+
    discharge2reg(fs, e, fs->freereg-1);  /* put value there */
+
  }
+
}
+

+

+
static int code_loadbool (FuncState *fs, int A, int b, int jump) {
+
  luaK_getlabel(fs);  /* those instructions may be jump targets */
+
  return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
+
}
+

+

+
/*
+
** check whether list has any jump that do not produce a value
+
** or produce an inverted value
+
*/
+
static int need_value (FuncState *fs, int list) {
+
  for (; list != NO_JUMP; list = getjump(fs, list)) {
+
    Instruction i = *getjumpcontrol(fs, list);
+
    if (GET_OPCODE(i) != OP_TESTSET) return 1;
+
  }
+
  return 0;  /* not found */
+
}
+

+

+
/*
+
** Ensures final expression result (including results from its jump
+
** lists) is in register 'reg'.
+
** If expression has jumps, need to patch these jumps either to
+
** its final position or to "load" instructions (for those tests
+
** that do not produce values).
+
*/
+
static void exp2reg (FuncState *fs, expdesc *e, int reg) {
+
  discharge2reg(fs, e, reg);
+
  if (e->k == VJMP)  /* expression itself is a test? */
+
    luaK_concat(fs, &e->t, e->u.info);  /* put this jump in 't' list */
+
  if (hasjumps(e)) {
+
    int final;  /* position after whole expression */
+
    int p_f = NO_JUMP;  /* position of an eventual LOAD false */
+
    int p_t = NO_JUMP;  /* position of an eventual LOAD true */
+
    if (need_value(fs, e->t) || need_value(fs, e->f)) {
+
      int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
+
      p_f = code_loadbool(fs, reg, 0, 1);
+
      p_t = code_loadbool(fs, reg, 1, 0);
+
      luaK_patchtohere(fs, fj);
+
    }
+
    final = luaK_getlabel(fs);
+
    patchlistaux(fs, e->f, final, reg, p_f);
+
    patchlistaux(fs, e->t, final, reg, p_t);
+
  }
+
  e->f = e->t = NO_JUMP;
+
  e->u.info = reg;
+
  e->k = VNONRELOC;
+
}
+

+

+
/*
+
** Ensures final expression result (including results from its jump
+
** lists) is in next available register.
+
*/
+
void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
+
  luaK_dischargevars(fs, e);
+
  freeexp(fs, e);
+
  luaK_reserveregs(fs, 1);
+
  exp2reg(fs, e, fs->freereg - 1);
+
}
+

+

+
/*
+
** Ensures final expression result (including results from its jump
+
** lists) is in some (any) register and return that register.
+
*/
+
int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
+
  luaK_dischargevars(fs, e);
+
  if (e->k == VNONRELOC) {  /* expression already has a register? */
+
    if (!hasjumps(e))  /* no jumps? */
+
      return e->u.info;  /* result is already in a register */
+
    if (e->u.info >= fs->nactvar) {  /* reg. is not a local? */
+
      exp2reg(fs, e, e->u.info);  /* put final result in it */
+
      return e->u.info;
+
    }
+
  }
+
  luaK_exp2nextreg(fs, e);  /* otherwise, use next available register */
+
  return e->u.info;
+
}
+

+

+
/*
+
** Ensures final expression result is either in a register or in an
+
** upvalue.
+
*/
+
void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
+
  if (e->k != VUPVAL || hasjumps(e))
+
    luaK_exp2anyreg(fs, e);
+
}
+

+

+
/*
+
** Ensures final expression result is either in a register or it is
+
** a constant.
+
*/
+
void luaK_exp2val (FuncState *fs, expdesc *e) {
+
  if (hasjumps(e))
+
    luaK_exp2anyreg(fs, e);
+
  else
+
    luaK_dischargevars(fs, e);
+
}
+

+

+
/*
+
** Ensures final expression result is in a valid R/K index
+
** (that is, it is either in a register or in 'k' with an index
+
** in the range of R/K indices).
+
** Returns R/K index.
+
*/
+
int luaK_exp2RK (FuncState *fs, expdesc *e) {
+
  luaK_exp2val(fs, e);
+
  switch (e->k) {  /* move constants to 'k' */
+
    case VTRUE: e->u.info = boolK(fs, 1); goto vk;
+
    case VFALSE: e->u.info = boolK(fs, 0); goto vk;
+
    case VNIL: e->u.info = nilK(fs); goto vk;
+
    case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk;
+
    case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk;
+
    case VK:
+
     vk:
+
      e->k = VK;
+
      if (e->u.info <= MAXINDEXRK)  /* constant fits in 'argC'? */
+
        return RKASK(e->u.info);
+
      else break;
+
    default: break;
+
  }
+
  /* not a constant in the right range: put it in a register */
+
  return luaK_exp2anyreg(fs, e);
+
}
+

+

+
/*
+
** Generate code to store result of expression 'ex' into variable 'var'.
+
*/
+
void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
+
  switch (var->k) {
+
    case VLOCAL: {
+
      freeexp(fs, ex);
+
      exp2reg(fs, ex, var->u.info);  /* compute 'ex' into proper place */
+
      return;
+
    }
+
    case VUPVAL: {
+
      int e = luaK_exp2anyreg(fs, ex);
+
      luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
+
      break;
+
    }
+
    case VINDEXED: {
+
      OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
+
      int e = luaK_exp2RK(fs, ex);
+
      luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
+
      break;
+
    }
+
    default: lua_assert(0);  /* invalid var kind to store */
+
  }
+
  freeexp(fs, ex);
+
}
+

+

+
/*
+
** Emit SELF instruction (convert expression 'e' into 'e:key(e,').
+
*/
+
void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
+
  int ereg;
+
  luaK_exp2anyreg(fs, e);
+
  ereg = e->u.info;  /* register where 'e' was placed */
+
  freeexp(fs, e);
+
  e->u.info = fs->freereg;  /* base register for op_self */
+
  e->k = VNONRELOC;  /* self expression has a fixed register */
+
  luaK_reserveregs(fs, 2);  /* function and 'self' produced by op_self */
+
  luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
+
  freeexp(fs, key);
+
}
+

+

+
/*
+
** Negate condition 'e' (where 'e' is a comparison).
+
*/
+
static void negatecondition (FuncState *fs, expdesc *e) {
+
  Instruction *pc = getjumpcontrol(fs, e->u.info);
+
  lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
+
                                           GET_OPCODE(*pc) != OP_TEST);
+
  SETARG_A(*pc, !(GETARG_A(*pc)));
+
}
+

+

+
/*
+
** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond'
+
** is true, code will jump if 'e' is true.) Return jump position.
+
** Optimize when 'e' is 'not' something, inverting the condition
+
** and removing the 'not'.
+
*/
+
static int jumponcond (FuncState *fs, expdesc *e, int cond) {
+
  if (e->k == VRELOCABLE) {
+
    Instruction ie = getinstruction(fs, e);
+
    if (GET_OPCODE(ie) == OP_NOT) {
+
      fs->pc--;  /* remove previous OP_NOT */
+
      return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
+
    }
+
    /* else go through */
+
  }
+
  discharge2anyreg(fs, e);
+
  freeexp(fs, e);
+
  return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
+
}
+

+

+
/*
+
** Emit code to go through if 'e' is true, jump otherwise.
+
*/
+
void luaK_goiftrue (FuncState *fs, expdesc *e) {
+
  int pc;  /* pc of new jump */
+
  luaK_dischargevars(fs, e);
+
  switch (e->k) {
+
    case VJMP: {  /* condition? */
+
      negatecondition(fs, e);  /* jump when it is false */
+
      pc = e->u.info;  /* save jump position */
+
      break;
+
    }
+
    case VK: case VKFLT: case VKINT: case VTRUE: {
+
      pc = NO_JUMP;  /* always true; do nothing */
+
      break;
+
    }
+
    default: {
+
      pc = jumponcond(fs, e, 0);  /* jump when false */
+
      break;
+
    }
+
  }
+
  luaK_concat(fs, &e->f, pc);  /* insert new jump in false list */
+
  luaK_patchtohere(fs, e->t);  /* true list jumps to here (to go through) */
+
  e->t = NO_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 VJMP: {
+
      pc = e->u.info;  /* already jump if true */
+
      break;
+
    }
+
    case VNIL: case VFALSE: {
+
      pc = NO_JUMP;  /* always false; do nothing */
+
      break;
+
    }
+
    default: {
+
      pc = jumponcond(fs, e, 1);  /* jump if true */
+
      break;
+
    }
+
  }
+
  luaK_concat(fs, &e->t, pc);  /* insert new jump in 't' list */
+
  luaK_patchtohere(fs, e->f);  /* false list jumps to here (to go through) */
+
  e->f = NO_JUMP;
+
}
+

+

+
/*
+
** Code 'not e', doing constant folding.
+
*/
+
static void codenot (FuncState *fs, expdesc *e) {
+
  luaK_dischargevars(fs, e);
+
  switch (e->k) {
+
    case VNIL: case VFALSE: {
+
      e->k = VTRUE;  /* true == not nil == not false */
+
      break;
+
    }
+
    case VK: case VKFLT: case VKINT: case VTRUE: {
+
      e->k = VFALSE;  /* false == not "x" == not 0.5 == not 1 == not true */
+
      break;
+
    }
+
    case VJMP: {
+
      negatecondition(fs, e);
+
      break;
+
    }
+
    case VRELOCABLE:
+
    case VNONRELOC: {
+
      discharge2anyreg(fs, e);
+
      freeexp(fs, e);
+
      e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
+
      e->k = VRELOCABLE;
+
      break;
+
    }
+
    default: lua_assert(0);  /* cannot happen */
+
  }
+
  /* interchange true and false lists */
+
  { int temp = e->f; e->f = e->t; e->t = temp; }
+
  removevalues(fs, e->f);  /* values are useless when negated */
+
  removevalues(fs, e->t);
+
}
+

+

+
/*
+
** Create expression 't[k]'. 't' must have its final result already in a
+
** register or upvalue.
+
*/
+
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
+
  lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL));
+
  t->u.ind.t = t->u.info;  /* register or upvalue index */
+
  t->u.ind.idx = luaK_exp2RK(fs, k);  /* R/K index for key */
+
  t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL;
+
  t->k = VINDEXED;
+
}
+

+

+
/*
+
** Return false if folding can raise an error.
+
** Bitwise operations need operands convertible to integers; division
+
** operations cannot have 0 as divisor.
+
*/
+
static int validop (int op, TValue *v1, TValue *v2) {
+
  switch (op) {
+
    case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
+
    case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: {  /* conversion errors */
+
      lua_Integer i;
+
      return (tointeger(v1, &i) && tointeger(v2, &i));
+
    }
+
    case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD:  /* division by 0 */
+
      return (nvalue(v2) != 0);
+
    default: return 1;  /* everything else is valid */
+
  }
+
}
+

+

+
/*
+
** Try to "constant-fold" an operation; return 1 iff successful.
+
** (In this case, 'e1' has the final result.)
+
*/
+
static int constfolding (FuncState *fs, int op, expdesc *e1,
+
                                                const expdesc *e2) {
+
  TValue v1, v2, res;
+
  if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
+
    return 0;  /* non-numeric operands or not safe to fold */
+
  luaO_arith(fs->ls->L, op, &v1, &v2, &res);  /* does operation */
+
  if (ttisinteger(&res)) {
+
    e1->k = VKINT;
+
    e1->u.ival = ivalue(&res);
+
  }
+
  else {  /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */
+
    lua_Number n = fltvalue(&res);
+
    if (luai_numisnan(n) || n == 0)
+
      return 0;
+
    e1->k = VKFLT;
+
    e1->u.nval = n;
+
  }
+
  return 1;
+
}
+

+

+
/*
+
** Emit code for unary expressions that "produce values"
+
** (everything but 'not').
+
** Expression to produce final result will be encoded in 'e'.
+
*/
+
static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
+
  int r = luaK_exp2anyreg(fs, e);  /* opcodes operate only on registers */
+
  freeexp(fs, e);
+
  e->u.info = luaK_codeABC(fs, op, 0, r, 0);  /* generate opcode */
+
  e->k = VRELOCABLE;  /* all those operations are relocatable */
+
  luaK_fixline(fs, line);
+
}
+

+

+
/*
+
** Emit code for binary expressions that "produce values"
+
** (everything but logical operators 'and'/'or' and comparison
+
** operators).
+
** Expression to produce final result will be encoded in 'e1'.
+
** Because 'luaK_exp2RK' can free registers, its calls must be
+
** in "stack order" (that is, first on 'e2', which may have more
+
** recent registers to be released).
+
*/
+
static void codebinexpval (FuncState *fs, OpCode op,
+
                           expdesc *e1, expdesc *e2, int line) {
+
  int rk2 = luaK_exp2RK(fs, e2);  /* both operands are "RK" */
+
  int rk1 = luaK_exp2RK(fs, e1);
+
  freeexps(fs, e1, e2);
+
  e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2);  /* generate opcode */
+
  e1->k = VRELOCABLE;  /* all those operations are relocatable */
+
  luaK_fixline(fs, line);
+
}
+

+

+
/*
+
** Emit code for comparisons.
+
** 'e1' was already put in R/K form by 'luaK_infix'.
+
*/
+
static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
+
  int rk1 = (e1->k == VK) ? RKASK(e1->u.info)
+
                          : check_exp(e1->k == VNONRELOC, e1->u.info);
+
  int rk2 = luaK_exp2RK(fs, e2);
+
  freeexps(fs, e1, e2);
+
  switch (opr) {
+
    case OPR_NE: {  /* '(a ~= b)' ==> 'not (a == b)' */
+
      e1->u.info = condjump(fs, OP_EQ, 0, rk1, rk2);
+
      break;
+
    }
+
    case OPR_GT: case OPR_GE: {
+
      /* '(a > b)' ==> '(b < a)';  '(a >= b)' ==> '(b <= a)' */
+
      OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
+
      e1->u.info = condjump(fs, op, 1, rk2, rk1);  /* invert operands */
+
      break;
+
    }
+
    default: {  /* '==', '<', '<=' use their own opcodes */
+
      OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
+
      e1->u.info = condjump(fs, op, 1, rk1, rk2);
+
      break;
+
    }
+
  }
+
  e1->k = VJMP;
+
}
+

+

+
/*
+
** Aplly prefix operation 'op' to expression 'e'.
+
*/
+
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
+
  static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
+
  switch (op) {
+
    case OPR_MINUS: case OPR_BNOT:  /* use 'ef' as fake 2nd operand */
+
      if (constfolding(fs, op + LUA_OPUNM, e, &ef))
+
        break;
+
      /* FALLTHROUGH */
+
    case OPR_LEN:
+
      codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line);
+
      break;
+
    case OPR_NOT: codenot(fs, e); break;
+
    default: lua_assert(0);
+
  }
+
}
+

+

+
/*
+
** Process 1st operand 'v' of binary operation 'op' before reading
+
** 2nd operand.
+
*/
+
void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
+
  switch (op) {
+
    case OPR_AND: {
+
      luaK_goiftrue(fs, v);  /* go ahead only if 'v' is true */
+
      break;
+
    }
+
    case OPR_OR: {
+
      luaK_goiffalse(fs, v);  /* go ahead only if 'v' is false */
+
      break;
+
    }
+
    case OPR_CONCAT: {
+
      luaK_exp2nextreg(fs, v);  /* operand must be on the 'stack' */
+
      break;
+
    }
+
    case OPR_ADD: case OPR_SUB:
+
    case OPR_MUL: case OPR_DIV: case OPR_IDIV:
+
    case OPR_MOD: case OPR_POW:
+
    case OPR_BAND: case OPR_BOR: case OPR_BXOR:
+
    case OPR_SHL: case OPR_SHR: {
+
      if (!tonumeral(v, NULL))
+
        luaK_exp2RK(fs, v);
+
      /* else keep numeral, which may be folded with 2nd operand */
+
      break;
+
    }
+
    default: {
+
      luaK_exp2RK(fs, v);
+
      break;
+
    }
+
  }
+
}
+

+

+
/*
+
** Finalize code for binary operation, after reading 2nd operand.
+
** For '(a .. b .. c)' (which is '(a .. (b .. c))', because
+
** concatenation is right associative), merge second CONCAT into first
+
** one.
+
*/
+
void luaK_posfix (FuncState *fs, BinOpr op,
+
                  expdesc *e1, expdesc *e2, int line) {
+
  switch (op) {
+
    case OPR_AND: {
+
      lua_assert(e1->t == NO_JUMP);  /* list closed by 'luK_infix' */
+
      luaK_dischargevars(fs, e2);
+
      luaK_concat(fs, &e2->f, e1->f);
+
      *e1 = *e2;
+
      break;
+
    }
+
    case OPR_OR: {
+
      lua_assert(e1->f == NO_JUMP);  /* list closed by 'luK_infix' */
+
      luaK_dischargevars(fs, e2);
+
      luaK_concat(fs, &e2->t, e1->t);
+
      *e1 = *e2;
+
      break;
+
    }
+
    case OPR_CONCAT: {
+
      luaK_exp2val(fs, e2);
+
      if (e2->k == VRELOCABLE &&
+
          GET_OPCODE(getinstruction(fs, e2)) == OP_CONCAT) {
+
        lua_assert(e1->u.info == GETARG_B(getinstruction(fs, e2))-1);
+
        freeexp(fs, e1);
+
        SETARG_B(getinstruction(fs, e2), e1->u.info);
+
        e1->k = VRELOCABLE; e1->u.info = e2->u.info;
+
      }
+
      else {
+
        luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
+
        codebinexpval(fs, OP_CONCAT, e1, e2, line);
+
      }
+
      break;
+
    }
+
    case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
+
    case OPR_IDIV: case OPR_MOD: case OPR_POW:
+
    case OPR_BAND: case OPR_BOR: case OPR_BXOR:
+
    case OPR_SHL: case OPR_SHR: {
+
      if (!constfolding(fs, op + LUA_OPADD, e1, e2))
+
        codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line);
+
      break;
+
    }
+
    case OPR_EQ: case OPR_LT: case OPR_LE:
+
    case OPR_NE: case OPR_GT: case OPR_GE: {
+
      codecomp(fs, op, e1, e2);
+
      break;
+
    }
+
    default: lua_assert(0);
+
  }
+
}
+

+

+
/*
+
** Change line information associated with current position.
+
*/
+
void luaK_fixline (FuncState *fs, int line) {
+
  fs->f->lineinfo[fs->pc - 1] = line;
+
}
+

+

+
/*
+
** Emit a SETLIST instruction.
+
** 'base' is register that keeps table;
+
** 'nelems' is #table plus those to be stored now;
+
** 'tostore' is number of values (in registers 'base + 1',...) to add to
+
** table (or LUA_MULTRET to add up to stack top).
+
*/
+
void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
+
  int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
+
  int b = (tostore == LUA_MULTRET) ? 0 : tostore;
+
  lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH);
+
  if (c <= MAXARG_C)
+
    luaK_codeABC(fs, OP_SETLIST, base, b, c);
+
  else if (c <= MAXARG_Ax) {
+
    luaK_codeABC(fs, OP_SETLIST, base, b, 0);
+
    codeextraarg(fs, c);
+
  }
+
  else
+
    luaX_syntaxerror(fs->ls, "constructor too long");
+
  fs->freereg = base + 1;  /* free registers with list values */
+
}
+

added external/lua/src/lcode.h
@@ -0,0 +1,88 @@
+
/*
+
** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Code generator for Lua
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lcode_h
+
#define lcode_h
+

+
#include "llex.h"
+
#include "lobject.h"
+
#include "lopcodes.h"
+
#include "lparser.h"
+

+

+
/*
+
** Marks the end of a patch list. It is an invalid value both as an absolute
+
** address, and as a list link (would link an element to itself).
+
*/
+
#define NO_JUMP (-1)
+

+

+
/*
+
** grep "ORDER OPR" if you change these enums  (ORDER OP)
+
*/
+
typedef enum BinOpr {
+
  OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW,
+
  OPR_DIV,
+
  OPR_IDIV,
+
  OPR_BAND, OPR_BOR, OPR_BXOR,
+
  OPR_SHL, OPR_SHR,
+
  OPR_CONCAT,
+
  OPR_EQ, OPR_LT, OPR_LE,
+
  OPR_NE, OPR_GT, OPR_GE,
+
  OPR_AND, OPR_OR,
+
  OPR_NOBINOPR
+
} BinOpr;
+

+

+
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
+

+

+
/* get (pointer to) instruction of given 'expdesc' */
+
#define getinstruction(fs,e)	((fs)->f->code[(e)->u.info])
+

+
#define luaK_codeAsBx(fs,o,A,sBx)	luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
+

+
#define luaK_setmultret(fs,e)	luaK_setreturns(fs, e, LUA_MULTRET)
+

+
#define luaK_jumpto(fs,t)	luaK_patchlist(fs, luaK_jump(fs), t)
+

+
LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
+
LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
+
LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k);
+
LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
+
LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
+
LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
+
LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
+
LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
+
LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n);
+
LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
+
LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
+
LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
+
LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
+
LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
+
LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
+
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
+
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
+
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
+
LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
+
LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
+
LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
+
LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
+
LUAI_FUNC int luaK_jump (FuncState *fs);
+
LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
+
LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
+
LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
+
LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level);
+
LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
+
LUAI_FUNC int luaK_getlabel (FuncState *fs);
+
LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
+
LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
+
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
+
                            expdesc *v2, int line);
+
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
+

+

+
#endif
added external/lua/src/lcorolib.c
@@ -0,0 +1,168 @@
+
/*
+
** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Coroutine Library
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lcorolib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <stdlib.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+
static lua_State *getco (lua_State *L) {
+
  lua_State *co = lua_tothread(L, 1);
+
  luaL_argcheck(L, co, 1, "thread expected");
+
  return co;
+
}
+

+

+
static int auxresume (lua_State *L, lua_State *co, int narg) {
+
  int status;
+
  if (!lua_checkstack(co, narg)) {
+
    lua_pushliteral(L, "too many arguments to resume");
+
    return -1;  /* error flag */
+
  }
+
  if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
+
    lua_pushliteral(L, "cannot resume dead coroutine");
+
    return -1;  /* error flag */
+
  }
+
  lua_xmove(L, co, narg);
+
  status = lua_resume(co, L, narg);
+
  if (status == LUA_OK || status == LUA_YIELD) {
+
    int nres = lua_gettop(co);
+
    if (!lua_checkstack(L, nres + 1)) {
+
      lua_pop(co, nres);  /* remove results anyway */
+
      lua_pushliteral(L, "too many results to resume");
+
      return -1;  /* error flag */
+
    }
+
    lua_xmove(co, L, nres);  /* move yielded values */
+
    return nres;
+
  }
+
  else {
+
    lua_xmove(co, L, 1);  /* move error message */
+
    return -1;  /* error flag */
+
  }
+
}
+

+

+
static int luaB_coresume (lua_State *L) {
+
  lua_State *co = getco(L);
+
  int r;
+
  r = auxresume(L, co, lua_gettop(L) - 1);
+
  if (r < 0) {
+
    lua_pushboolean(L, 0);
+
    lua_insert(L, -2);
+
    return 2;  /* return false + error message */
+
  }
+
  else {
+
    lua_pushboolean(L, 1);
+
    lua_insert(L, -(r + 1));
+
    return r + 1;  /* return true + 'resume' returns */
+
  }
+
}
+

+

+
static int luaB_auxwrap (lua_State *L) {
+
  lua_State *co = lua_tothread(L, lua_upvalueindex(1));
+
  int r = auxresume(L, co, lua_gettop(L));
+
  if (r < 0) {
+
    if (lua_type(L, -1) == LUA_TSTRING) {  /* error object is a string? */
+
      luaL_where(L, 1);  /* add extra info */
+
      lua_insert(L, -2);
+
      lua_concat(L, 2);
+
    }
+
    return lua_error(L);  /* propagate error */
+
  }
+
  return r;
+
}
+

+

+
static int luaB_cocreate (lua_State *L) {
+
  lua_State *NL;
+
  luaL_checktype(L, 1, LUA_TFUNCTION);
+
  NL = lua_newthread(L);
+
  lua_pushvalue(L, 1);  /* move function to top */
+
  lua_xmove(L, NL, 1);  /* move function from L to NL */
+
  return 1;
+
}
+

+

+
static int luaB_cowrap (lua_State *L) {
+
  luaB_cocreate(L);
+
  lua_pushcclosure(L, luaB_auxwrap, 1);
+
  return 1;
+
}
+

+

+
static int luaB_yield (lua_State *L) {
+
  return lua_yield(L, lua_gettop(L));
+
}
+

+

+
static int luaB_costatus (lua_State *L) {
+
  lua_State *co = getco(L);
+
  if (L == co) lua_pushliteral(L, "running");
+
  else {
+
    switch (lua_status(co)) {
+
      case LUA_YIELD:
+
        lua_pushliteral(L, "suspended");
+
        break;
+
      case LUA_OK: {
+
        lua_Debug ar;
+
        if (lua_getstack(co, 0, &ar) > 0)  /* does it have frames? */
+
          lua_pushliteral(L, "normal");  /* it is running */
+
        else if (lua_gettop(co) == 0)
+
            lua_pushliteral(L, "dead");
+
        else
+
          lua_pushliteral(L, "suspended");  /* initial state */
+
        break;
+
      }
+
      default:  /* some error occurred */
+
        lua_pushliteral(L, "dead");
+
        break;
+
    }
+
  }
+
  return 1;
+
}
+

+

+
static int luaB_yieldable (lua_State *L) {
+
  lua_pushboolean(L, lua_isyieldable(L));
+
  return 1;
+
}
+

+

+
static int luaB_corunning (lua_State *L) {
+
  int ismain = lua_pushthread(L);
+
  lua_pushboolean(L, ismain);
+
  return 2;
+
}
+

+

+
static const luaL_Reg co_funcs[] = {
+
  {"create", luaB_cocreate},
+
  {"resume", luaB_coresume},
+
  {"running", luaB_corunning},
+
  {"status", luaB_costatus},
+
  {"wrap", luaB_cowrap},
+
  {"yield", luaB_yield},
+
  {"isyieldable", luaB_yieldable},
+
  {NULL, NULL}
+
};
+

+

+

+
LUAMOD_API int luaopen_coroutine (lua_State *L) {
+
  luaL_newlib(L, co_funcs);
+
  return 1;
+
}
+

added external/lua/src/lctype.c
@@ -0,0 +1,55 @@
+
/*
+
** $Id: lctype.c,v 1.12.1.1 2017/04/19 17:20:42 roberto Exp $
+
** 'ctype' functions for Lua
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lctype_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include "lctype.h"
+

+
#if !LUA_USE_CTYPE	/* { */
+

+
#include <limits.h>
+

+
LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
+
  0x00,  /* EOZ */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* 0. */
+
  0x00,  0x08,  0x08,  0x08,  0x08,  0x08,  0x00,  0x00,
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* 1. */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
  0x0c,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,	/* 2. */
+
  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,
+
  0x16,  0x16,  0x16,  0x16,  0x16,  0x16,  0x16,  0x16,	/* 3. */
+
  0x16,  0x16,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,
+
  0x04,  0x15,  0x15,  0x15,  0x15,  0x15,  0x15,  0x05,	/* 4. */
+
  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,
+
  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,	/* 5. */
+
  0x05,  0x05,  0x05,  0x04,  0x04,  0x04,  0x04,  0x05,
+
  0x04,  0x15,  0x15,  0x15,  0x15,  0x15,  0x15,  0x05,	/* 6. */
+
  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,
+
  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,	/* 7. */
+
  0x05,  0x05,  0x05,  0x04,  0x04,  0x04,  0x04,  0x00,
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* 8. */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* 9. */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* a. */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* b. */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* c. */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* d. */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* e. */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* f. */
+
  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
};
+

+
#endif			/* } */
added external/lua/src/lctype.h
@@ -0,0 +1,95 @@
+
/*
+
** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
+
** 'ctype' functions for Lua
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lctype_h
+
#define lctype_h
+

+
#include "lua.h"
+

+

+
/*
+
** WARNING: the functions defined here do not necessarily correspond
+
** to the similar functions in the standard C ctype.h. They are
+
** optimized for the specific needs of Lua
+
*/
+

+
#if !defined(LUA_USE_CTYPE)
+

+
#if 'A' == 65 && '0' == 48
+
/* ASCII case: can use its own tables; faster and fixed */
+
#define LUA_USE_CTYPE	0
+
#else
+
/* must use standard C ctype */
+
#define LUA_USE_CTYPE	1
+
#endif
+

+
#endif
+

+

+
#if !LUA_USE_CTYPE	/* { */
+

+
#include <limits.h>
+

+
#include "llimits.h"
+

+

+
#define ALPHABIT	0
+
#define DIGITBIT	1
+
#define PRINTBIT	2
+
#define SPACEBIT	3
+
#define XDIGITBIT	4
+

+

+
#define MASK(B)		(1 << (B))
+

+

+
/*
+
** add 1 to char to allow index -1 (EOZ)
+
*/
+
#define testprop(c,p)	(luai_ctype_[(c)+1] & (p))
+

+
/*
+
** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
+
*/
+
#define lislalpha(c)	testprop(c, MASK(ALPHABIT))
+
#define lislalnum(c)	testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
+
#define lisdigit(c)	testprop(c, MASK(DIGITBIT))
+
#define lisspace(c)	testprop(c, MASK(SPACEBIT))
+
#define lisprint(c)	testprop(c, MASK(PRINTBIT))
+
#define lisxdigit(c)	testprop(c, MASK(XDIGITBIT))
+

+
/*
+
** this 'ltolower' only works for alphabetic characters
+
*/
+
#define ltolower(c)	((c) | ('A' ^ 'a'))
+

+

+
/* two more entries for 0 and -1 (EOZ) */
+
LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
+

+

+
#else			/* }{ */
+

+
/*
+
** use standard C ctypes
+
*/
+

+
#include <ctype.h>
+

+

+
#define lislalpha(c)	(isalpha(c) || (c) == '_')
+
#define lislalnum(c)	(isalnum(c) || (c) == '_')
+
#define lisdigit(c)	(isdigit(c))
+
#define lisspace(c)	(isspace(c))
+
#define lisprint(c)	(isprint(c))
+
#define lisxdigit(c)	(isxdigit(c))
+

+
#define ltolower(c)	(tolower(c))
+

+
#endif			/* } */
+

+
#endif
+

added external/lua/src/ldblib.c
@@ -0,0 +1,456 @@
+
/*
+
** $Id: ldblib.c,v 1.151.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Interface from Lua to its debug API
+
** See Copyright Notice in lua.h
+
*/
+

+
#define ldblib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+
/*
+
** The hook table at registry[&HOOKKEY] maps threads to their current
+
** hook function. (We only need the unique address of 'HOOKKEY'.)
+
*/
+
static const int HOOKKEY = 0;
+

+

+
/*
+
** If L1 != L, L1 can be in any state, and therefore there are no
+
** guarantees about its stack space; any push in L1 must be
+
** checked.
+
*/
+
static void checkstack (lua_State *L, lua_State *L1, int n) {
+
  if (L != L1 && !lua_checkstack(L1, n))
+
    luaL_error(L, "stack overflow");
+
}
+

+

+
static int db_getregistry (lua_State *L) {
+
  lua_pushvalue(L, LUA_REGISTRYINDEX);
+
  return 1;
+
}
+

+

+
static int db_getmetatable (lua_State *L) {
+
  luaL_checkany(L, 1);
+
  if (!lua_getmetatable(L, 1)) {
+
    lua_pushnil(L);  /* no metatable */
+
  }
+
  return 1;
+
}
+

+

+
static int db_setmetatable (lua_State *L) {
+
  int t = lua_type(L, 2);
+
  luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
+
                    "nil or table expected");
+
  lua_settop(L, 2);
+
  lua_setmetatable(L, 1);
+
  return 1;  /* return 1st argument */
+
}
+

+

+
static int db_getuservalue (lua_State *L) {
+
  if (lua_type(L, 1) != LUA_TUSERDATA)
+
    lua_pushnil(L);
+
  else
+
    lua_getuservalue(L, 1);
+
  return 1;
+
}
+

+

+
static int db_setuservalue (lua_State *L) {
+
  luaL_checktype(L, 1, LUA_TUSERDATA);
+
  luaL_checkany(L, 2);
+
  lua_settop(L, 2);
+
  lua_setuservalue(L, 1);
+
  return 1;
+
}
+

+

+
/*
+
** Auxiliary function used by several library functions: check for
+
** an optional thread as function's first argument and set 'arg' with
+
** 1 if this argument is present (so that functions can skip it to
+
** access their other arguments)
+
*/
+
static lua_State *getthread (lua_State *L, int *arg) {
+
  if (lua_isthread(L, 1)) {
+
    *arg = 1;
+
    return lua_tothread(L, 1);
+
  }
+
  else {
+
    *arg = 0;
+
    return L;  /* function will operate over current thread */
+
  }
+
}
+

+

+
/*
+
** Variations of 'lua_settable', used by 'db_getinfo' to put results
+
** from 'lua_getinfo' into result table. Key is always a string;
+
** value can be a string, an int, or a boolean.
+
*/
+
static void settabss (lua_State *L, const char *k, const char *v) {
+
  lua_pushstring(L, v);
+
  lua_setfield(L, -2, k);
+
}
+

+
static void settabsi (lua_State *L, const char *k, int v) {
+
  lua_pushinteger(L, v);
+
  lua_setfield(L, -2, k);
+
}
+

+
static void settabsb (lua_State *L, const char *k, int v) {
+
  lua_pushboolean(L, v);
+
  lua_setfield(L, -2, k);
+
}
+

+

+
/*
+
** In function 'db_getinfo', the call to 'lua_getinfo' may push
+
** results on the stack; later it creates the result table to put
+
** these objects. Function 'treatstackoption' puts the result from
+
** 'lua_getinfo' on top of the result table so that it can call
+
** 'lua_setfield'.
+
*/
+
static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
+
  if (L == L1)
+
    lua_rotate(L, -2, 1);  /* exchange object and table */
+
  else
+
    lua_xmove(L1, L, 1);  /* move object to the "main" stack */
+
  lua_setfield(L, -2, fname);  /* put object into table */
+
}
+

+

+
/*
+
** Calls 'lua_getinfo' and collects all results in a new table.
+
** L1 needs stack space for an optional input (function) plus
+
** two optional outputs (function and line table) from function
+
** 'lua_getinfo'.
+
*/
+
static int db_getinfo (lua_State *L) {
+
  lua_Debug ar;
+
  int arg;
+
  lua_State *L1 = getthread(L, &arg);
+
  const char *options = luaL_optstring(L, arg+2, "flnStu");
+
  checkstack(L, L1, 3);
+
  if (lua_isfunction(L, arg + 1)) {  /* info about a function? */
+
    options = lua_pushfstring(L, ">%s", options);  /* add '>' to 'options' */
+
    lua_pushvalue(L, arg + 1);  /* move function to 'L1' stack */
+
    lua_xmove(L, L1, 1);
+
  }
+
  else {  /* stack level */
+
    if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) {
+
      lua_pushnil(L);  /* level out of range */
+
      return 1;
+
    }
+
  }
+
  if (!lua_getinfo(L1, options, &ar))
+
    return luaL_argerror(L, arg+2, "invalid option");
+
  lua_newtable(L);  /* table to collect results */
+
  if (strchr(options, 'S')) {
+
    settabss(L, "source", ar.source);
+
    settabss(L, "short_src", ar.short_src);
+
    settabsi(L, "linedefined", ar.linedefined);
+
    settabsi(L, "lastlinedefined", ar.lastlinedefined);
+
    settabss(L, "what", ar.what);
+
  }
+
  if (strchr(options, 'l'))
+
    settabsi(L, "currentline", ar.currentline);
+
  if (strchr(options, 'u')) {
+
    settabsi(L, "nups", ar.nups);
+
    settabsi(L, "nparams", ar.nparams);
+
    settabsb(L, "isvararg", ar.isvararg);
+
  }
+
  if (strchr(options, 'n')) {
+
    settabss(L, "name", ar.name);
+
    settabss(L, "namewhat", ar.namewhat);
+
  }
+
  if (strchr(options, 't'))
+
    settabsb(L, "istailcall", ar.istailcall);
+
  if (strchr(options, 'L'))
+
    treatstackoption(L, L1, "activelines");
+
  if (strchr(options, 'f'))
+
    treatstackoption(L, L1, "func");
+
  return 1;  /* return table */
+
}
+

+

+
static int db_getlocal (lua_State *L) {
+
  int arg;
+
  lua_State *L1 = getthread(L, &arg);
+
  lua_Debug ar;
+
  const char *name;
+
  int nvar = (int)luaL_checkinteger(L, arg + 2);  /* local-variable index */
+
  if (lua_isfunction(L, arg + 1)) {  /* function argument? */
+
    lua_pushvalue(L, arg + 1);  /* push function */
+
    lua_pushstring(L, lua_getlocal(L, NULL, nvar));  /* push local name */
+
    return 1;  /* return only name (there is no value) */
+
  }
+
  else {  /* stack-level argument */
+
    int level = (int)luaL_checkinteger(L, arg + 1);
+
    if (!lua_getstack(L1, level, &ar))  /* out of range? */
+
      return luaL_argerror(L, arg+1, "level out of range");
+
    checkstack(L, L1, 1);
+
    name = lua_getlocal(L1, &ar, nvar);
+
    if (name) {
+
      lua_xmove(L1, L, 1);  /* move local value */
+
      lua_pushstring(L, name);  /* push name */
+
      lua_rotate(L, -2, 1);  /* re-order */
+
      return 2;
+
    }
+
    else {
+
      lua_pushnil(L);  /* no name (nor value) */
+
      return 1;
+
    }
+
  }
+
}
+

+

+
static int db_setlocal (lua_State *L) {
+
  int arg;
+
  const char *name;
+
  lua_State *L1 = getthread(L, &arg);
+
  lua_Debug ar;
+
  int level = (int)luaL_checkinteger(L, arg + 1);
+
  int nvar = (int)luaL_checkinteger(L, arg + 2);
+
  if (!lua_getstack(L1, level, &ar))  /* out of range? */
+
    return luaL_argerror(L, arg+1, "level out of range");
+
  luaL_checkany(L, arg+3);
+
  lua_settop(L, arg+3);
+
  checkstack(L, L1, 1);
+
  lua_xmove(L, L1, 1);
+
  name = lua_setlocal(L1, &ar, nvar);
+
  if (name == NULL)
+
    lua_pop(L1, 1);  /* pop value (if not popped by 'lua_setlocal') */
+
  lua_pushstring(L, name);
+
  return 1;
+
}
+

+

+
/*
+
** get (if 'get' is true) or set an upvalue from a closure
+
*/
+
static int auxupvalue (lua_State *L, int get) {
+
  const char *name;
+
  int n = (int)luaL_checkinteger(L, 2);  /* upvalue index */
+
  luaL_checktype(L, 1, LUA_TFUNCTION);  /* closure */
+
  name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
+
  if (name == NULL) return 0;
+
  lua_pushstring(L, name);
+
  lua_insert(L, -(get+1));  /* no-op if get is false */
+
  return get + 1;
+
}
+

+

+
static int db_getupvalue (lua_State *L) {
+
  return auxupvalue(L, 1);
+
}
+

+

+
static int db_setupvalue (lua_State *L) {
+
  luaL_checkany(L, 3);
+
  return auxupvalue(L, 0);
+
}
+

+

+
/*
+
** Check whether a given upvalue from a given closure exists and
+
** returns its index
+
*/
+
static int checkupval (lua_State *L, int argf, int argnup) {
+
  int nup = (int)luaL_checkinteger(L, argnup);  /* upvalue index */
+
  luaL_checktype(L, argf, LUA_TFUNCTION);  /* closure */
+
  luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup,
+
                   "invalid upvalue index");
+
  return nup;
+
}
+

+

+
static int db_upvalueid (lua_State *L) {
+
  int n = checkupval(L, 1, 2);
+
  lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
+
  return 1;
+
}
+

+

+
static int db_upvaluejoin (lua_State *L) {
+
  int n1 = checkupval(L, 1, 2);
+
  int n2 = checkupval(L, 3, 4);
+
  luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
+
  luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
+
  lua_upvaluejoin(L, 1, n1, 3, n2);
+
  return 0;
+
}
+

+

+
/*
+
** Call hook function registered at hook table for the current
+
** thread (if there is one)
+
*/
+
static void hookf (lua_State *L, lua_Debug *ar) {
+
  static const char *const hooknames[] =
+
    {"call", "return", "line", "count", "tail call"};
+
  lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
+
  lua_pushthread(L);
+
  if (lua_rawget(L, -2) == LUA_TFUNCTION) {  /* is there a hook function? */
+
    lua_pushstring(L, hooknames[(int)ar->event]);  /* push event name */
+
    if (ar->currentline >= 0)
+
      lua_pushinteger(L, ar->currentline);  /* push current line */
+
    else lua_pushnil(L);
+
    lua_assert(lua_getinfo(L, "lS", ar));
+
    lua_call(L, 2, 0);  /* call hook function */
+
  }
+
}
+

+

+
/*
+
** Convert a string mask (for 'sethook') into a bit mask
+
*/
+
static int makemask (const char *smask, int count) {
+
  int mask = 0;
+
  if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
+
  if (strchr(smask, 'r')) mask |= LUA_MASKRET;
+
  if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
+
  if (count > 0) mask |= LUA_MASKCOUNT;
+
  return mask;
+
}
+

+

+
/*
+
** Convert a bit mask (for 'gethook') into a string mask
+
*/
+
static char *unmakemask (int mask, char *smask) {
+
  int i = 0;
+
  if (mask & LUA_MASKCALL) smask[i++] = 'c';
+
  if (mask & LUA_MASKRET) smask[i++] = 'r';
+
  if (mask & LUA_MASKLINE) smask[i++] = 'l';
+
  smask[i] = '\0';
+
  return smask;
+
}
+

+

+
static int db_sethook (lua_State *L) {
+
  int arg, mask, count;
+
  lua_Hook func;
+
  lua_State *L1 = getthread(L, &arg);
+
  if (lua_isnoneornil(L, arg+1)) {  /* no hook? */
+
    lua_settop(L, arg+1);
+
    func = NULL; mask = 0; count = 0;  /* turn off hooks */
+
  }
+
  else {
+
    const char *smask = luaL_checkstring(L, arg+2);
+
    luaL_checktype(L, arg+1, LUA_TFUNCTION);
+
    count = (int)luaL_optinteger(L, arg + 3, 0);
+
    func = hookf; mask = makemask(smask, count);
+
  }
+
  if (lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY) == LUA_TNIL) {
+
    lua_createtable(L, 0, 2);  /* create a hook table */
+
    lua_pushvalue(L, -1);
+
    lua_rawsetp(L, LUA_REGISTRYINDEX, &HOOKKEY);  /* set it in position */
+
    lua_pushstring(L, "k");
+
    lua_setfield(L, -2, "__mode");  /** hooktable.__mode = "k" */
+
    lua_pushvalue(L, -1);
+
    lua_setmetatable(L, -2);  /* setmetatable(hooktable) = hooktable */
+
  }
+
  checkstack(L, L1, 1);
+
  lua_pushthread(L1); lua_xmove(L1, L, 1);  /* key (thread) */
+
  lua_pushvalue(L, arg + 1);  /* value (hook function) */
+
  lua_rawset(L, -3);  /* hooktable[L1] = new Lua hook */
+
  lua_sethook(L1, func, mask, count);
+
  return 0;
+
}
+

+

+
static int db_gethook (lua_State *L) {
+
  int arg;
+
  lua_State *L1 = getthread(L, &arg);
+
  char buff[5];
+
  int mask = lua_gethookmask(L1);
+
  lua_Hook hook = lua_gethook(L1);
+
  if (hook == NULL)  /* no hook? */
+
    lua_pushnil(L);
+
  else if (hook != hookf)  /* external hook? */
+
    lua_pushliteral(L, "external hook");
+
  else {  /* hook table must exist */
+
    lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
+
    checkstack(L, L1, 1);
+
    lua_pushthread(L1); lua_xmove(L1, L, 1);
+
    lua_rawget(L, -2);   /* 1st result = hooktable[L1] */
+
    lua_remove(L, -2);  /* remove hook table */
+
  }
+
  lua_pushstring(L, unmakemask(mask, buff));  /* 2nd result = mask */
+
  lua_pushinteger(L, lua_gethookcount(L1));  /* 3rd result = count */
+
  return 3;
+
}
+

+

+
static int db_debug (lua_State *L) {
+
  for (;;) {
+
    char buffer[250];
+
    lua_writestringerror("%s", "lua_debug> ");
+
    if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
+
        strcmp(buffer, "cont\n") == 0)
+
      return 0;
+
    if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
+
        lua_pcall(L, 0, 0, 0))
+
      lua_writestringerror("%s\n", lua_tostring(L, -1));
+
    lua_settop(L, 0);  /* remove eventual returns */
+
  }
+
}
+

+

+
static int db_traceback (lua_State *L) {
+
  int arg;
+
  lua_State *L1 = getthread(L, &arg);
+
  const char *msg = lua_tostring(L, arg + 1);
+
  if (msg == NULL && !lua_isnoneornil(L, arg + 1))  /* non-string 'msg'? */
+
    lua_pushvalue(L, arg + 1);  /* return it untouched */
+
  else {
+
    int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0);
+
    luaL_traceback(L, L1, msg, level);
+
  }
+
  return 1;
+
}
+

+

+
static const luaL_Reg dblib[] = {
+
  {"debug", db_debug},
+
  {"getuservalue", db_getuservalue},
+
  {"gethook", db_gethook},
+
  {"getinfo", db_getinfo},
+
  {"getlocal", db_getlocal},
+
  {"getregistry", db_getregistry},
+
  {"getmetatable", db_getmetatable},
+
  {"getupvalue", db_getupvalue},
+
  {"upvaluejoin", db_upvaluejoin},
+
  {"upvalueid", db_upvalueid},
+
  {"setuservalue", db_setuservalue},
+
  {"sethook", db_sethook},
+
  {"setlocal", db_setlocal},
+
  {"setmetatable", db_setmetatable},
+
  {"setupvalue", db_setupvalue},
+
  {"traceback", db_traceback},
+
  {NULL, NULL}
+
};
+

+

+
LUAMOD_API int luaopen_debug (lua_State *L) {
+
  luaL_newlib(L, dblib);
+
  return 1;
+
}
+

added external/lua/src/ldebug.c
@@ -0,0 +1,699 @@
+
/*
+
** $Id: ldebug.c,v 2.121.1.2 2017/07/10 17:21:50 roberto Exp $
+
** Debug Interface
+
** See Copyright Notice in lua.h
+
*/
+

+
#define ldebug_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <stdarg.h>
+
#include <stddef.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lapi.h"
+
#include "lcode.h"
+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lfunc.h"
+
#include "lobject.h"
+
#include "lopcodes.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "ltm.h"
+
#include "lvm.h"
+

+

+

+
#define noLuaClosure(f)		((f) == NULL || (f)->c.tt == LUA_TCCL)
+

+

+
/* Active Lua function (given call info) */
+
#define ci_func(ci)		(clLvalue((ci)->func))
+

+

+
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
+
                                    const char **name);
+

+

+
static int currentpc (CallInfo *ci) {
+
  lua_assert(isLua(ci));
+
  return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
+
}
+

+

+
static int currentline (CallInfo *ci) {
+
  return getfuncline(ci_func(ci)->p, currentpc(ci));
+
}
+

+

+
/*
+
** If function yielded, its 'func' can be in the 'extra' field. The
+
** next function restores 'func' to its correct value for debugging
+
** purposes. (It exchanges 'func' and 'extra'; so, when called again,
+
** after debugging, it also "re-restores" ** 'func' to its altered value.
+
*/
+
static void swapextra (lua_State *L) {
+
  if (L->status == LUA_YIELD) {
+
    CallInfo *ci = L->ci;  /* get function that yielded */
+
    StkId temp = ci->func;  /* exchange its 'func' and 'extra' values */
+
    ci->func = restorestack(L, ci->extra);
+
    ci->extra = savestack(L, temp);
+
  }
+
}
+

+

+
/*
+
** This function can be called asynchronously (e.g. during a signal).
+
** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
+
** 'resethookcount') are for debug only, and it is no problem if they
+
** get arbitrary values (causes at most one wrong hook call). 'hookmask'
+
** is an atomic value. We assume that pointers are atomic too (e.g., gcc
+
** ensures that for all platforms where it runs). Moreover, 'hook' is
+
** always checked before being called (see 'luaD_hook').
+
*/
+
LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
+
  if (func == NULL || mask == 0) {  /* turn off hooks? */
+
    mask = 0;
+
    func = NULL;
+
  }
+
  if (isLua(L->ci))
+
    L->oldpc = L->ci->u.l.savedpc;
+
  L->hook = func;
+
  L->basehookcount = count;
+
  resethookcount(L);
+
  L->hookmask = cast_byte(mask);
+
}
+

+

+
LUA_API lua_Hook lua_gethook (lua_State *L) {
+
  return L->hook;
+
}
+

+

+
LUA_API int lua_gethookmask (lua_State *L) {
+
  return L->hookmask;
+
}
+

+

+
LUA_API int lua_gethookcount (lua_State *L) {
+
  return L->basehookcount;
+
}
+

+

+
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
+
  int status;
+
  CallInfo *ci;
+
  if (level < 0) return 0;  /* invalid (negative) level */
+
  lua_lock(L);
+
  for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
+
    level--;
+
  if (level == 0 && ci != &L->base_ci) {  /* level found? */
+
    status = 1;
+
    ar->i_ci = ci;
+
  }
+
  else status = 0;  /* no such level */
+
  lua_unlock(L);
+
  return status;
+
}
+

+

+
static const char *upvalname (Proto *p, int uv) {
+
  TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
+
  if (s == NULL) return "?";
+
  else return getstr(s);
+
}
+

+

+
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
+
  int nparams = clLvalue(ci->func)->p->numparams;
+
  if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
+
    return NULL;  /* no such vararg */
+
  else {
+
    *pos = ci->func + nparams + n;
+
    return "(*vararg)";  /* generic name for any vararg */
+
  }
+
}
+

+

+
static const char *findlocal (lua_State *L, CallInfo *ci, int n,
+
                              StkId *pos) {
+
  const char *name = NULL;
+
  StkId base;
+
  if (isLua(ci)) {
+
    if (n < 0)  /* access to vararg values? */
+
      return findvararg(ci, -n, pos);
+
    else {
+
      base = ci->u.l.base;
+
      name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
+
    }
+
  }
+
  else
+
    base = ci->func + 1;
+
  if (name == NULL) {  /* no 'standard' name? */
+
    StkId limit = (ci == L->ci) ? L->top : ci->next->func;
+
    if (limit - base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
+
      name = "(*temporary)";  /* generic name for any valid slot */
+
    else
+
      return NULL;  /* no name */
+
  }
+
  *pos = base + (n - 1);
+
  return name;
+
}
+

+

+
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
+
  const char *name;
+
  lua_lock(L);
+
  swapextra(L);
+
  if (ar == NULL) {  /* information about non-active function? */
+
    if (!isLfunction(L->top - 1))  /* not a Lua function? */
+
      name = NULL;
+
    else  /* consider live variables at function start (parameters) */
+
      name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
+
  }
+
  else {  /* active function; get information through 'ar' */
+
    StkId pos = NULL;  /* to avoid warnings */
+
    name = findlocal(L, ar->i_ci, n, &pos);
+
    if (name) {
+
      setobj2s(L, L->top, pos);
+
      api_incr_top(L);
+
    }
+
  }
+
  swapextra(L);
+
  lua_unlock(L);
+
  return name;
+
}
+

+

+
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
+
  StkId pos = NULL;  /* to avoid warnings */
+
  const char *name;
+
  lua_lock(L);
+
  swapextra(L);
+
  name = findlocal(L, ar->i_ci, n, &pos);
+
  if (name) {
+
    setobjs2s(L, pos, L->top - 1);
+
    L->top--;  /* pop value */
+
  }
+
  swapextra(L);
+
  lua_unlock(L);
+
  return name;
+
}
+

+

+
static void funcinfo (lua_Debug *ar, Closure *cl) {
+
  if (noLuaClosure(cl)) {
+
    ar->source = "=[C]";
+
    ar->linedefined = -1;
+
    ar->lastlinedefined = -1;
+
    ar->what = "C";
+
  }
+
  else {
+
    Proto *p = cl->l.p;
+
    ar->source = p->source ? getstr(p->source) : "=?";
+
    ar->linedefined = p->linedefined;
+
    ar->lastlinedefined = p->lastlinedefined;
+
    ar->what = (ar->linedefined == 0) ? "main" : "Lua";
+
  }
+
  luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
+
}
+

+

+
static void collectvalidlines (lua_State *L, Closure *f) {
+
  if (noLuaClosure(f)) {
+
    setnilvalue(L->top);
+
    api_incr_top(L);
+
  }
+
  else {
+
    int i;
+
    TValue v;
+
    int *lineinfo = f->l.p->lineinfo;
+
    Table *t = luaH_new(L);  /* new table to store active lines */
+
    sethvalue(L, L->top, t);  /* push it on stack */
+
    api_incr_top(L);
+
    setbvalue(&v, 1);  /* boolean 'true' to be the value of all indices */
+
    for (i = 0; i < f->l.p->sizelineinfo; i++)  /* for all lines with code */
+
      luaH_setint(L, t, lineinfo[i], &v);  /* table[line] = true */
+
  }
+
}
+

+

+
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,
+
                       Closure *f, CallInfo *ci) {
+
  int status = 1;
+
  for (; *what; what++) {
+
    switch (*what) {
+
      case 'S': {
+
        funcinfo(ar, f);
+
        break;
+
      }
+
      case 'l': {
+
        ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
+
        break;
+
      }
+
      case 'u': {
+
        ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
+
        if (noLuaClosure(f)) {
+
          ar->isvararg = 1;
+
          ar->nparams = 0;
+
        }
+
        else {
+
          ar->isvararg = f->l.p->is_vararg;
+
          ar->nparams = f->l.p->numparams;
+
        }
+
        break;
+
      }
+
      case 't': {
+
        ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
+
        break;
+
      }
+
      case 'n': {
+
        ar->namewhat = getfuncname(L, ci, &ar->name);
+
        if (ar->namewhat == NULL) {
+
          ar->namewhat = "";  /* not found */
+
          ar->name = NULL;
+
        }
+
        break;
+
      }
+
      case 'L':
+
      case 'f':  /* handled by lua_getinfo */
+
        break;
+
      default: status = 0;  /* invalid option */
+
    }
+
  }
+
  return status;
+
}
+

+

+
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
+
  int status;
+
  Closure *cl;
+
  CallInfo *ci;
+
  StkId func;
+
  lua_lock(L);
+
  swapextra(L);
+
  if (*what == '>') {
+
    ci = NULL;
+
    func = L->top - 1;
+
    api_check(L, ttisfunction(func), "function expected");
+
    what++;  /* skip the '>' */
+
    L->top--;  /* pop function */
+
  }
+
  else {
+
    ci = ar->i_ci;
+
    func = ci->func;
+
    lua_assert(ttisfunction(ci->func));
+
  }
+
  cl = ttisclosure(func) ? clvalue(func) : NULL;
+
  status = auxgetinfo(L, what, ar, cl, ci);
+
  if (strchr(what, 'f')) {
+
    setobjs2s(L, L->top, func);
+
    api_incr_top(L);
+
  }
+
  swapextra(L);  /* correct before option 'L', which can raise a mem. error */
+
  if (strchr(what, 'L'))
+
    collectvalidlines(L, cl);
+
  lua_unlock(L);
+
  return status;
+
}
+

+

+
/*
+
** {======================================================
+
** Symbolic Execution
+
** =======================================================
+
*/
+

+
static const char *getobjname (Proto *p, int lastpc, int reg,
+
                               const char **name);
+

+

+
/*
+
** find a "name" for the RK value 'c'
+
*/
+
static void kname (Proto *p, int pc, int c, const char **name) {
+
  if (ISK(c)) {  /* is 'c' a constant? */
+
    TValue *kvalue = &p->k[INDEXK(c)];
+
    if (ttisstring(kvalue)) {  /* literal constant? */
+
      *name = svalue(kvalue);  /* it is its own name */
+
      return;
+
    }
+
    /* else no reasonable name found */
+
  }
+
  else {  /* 'c' is a register */
+
    const char *what = getobjname(p, pc, c, name); /* search for 'c' */
+
    if (what && *what == 'c') {  /* found a constant name? */
+
      return;  /* 'name' already filled */
+
    }
+
    /* else no reasonable name found */
+
  }
+
  *name = "?";  /* no reasonable name found */
+
}
+

+

+
static int filterpc (int pc, int jmptarget) {
+
  if (pc < jmptarget)  /* is code conditional (inside a jump)? */
+
    return -1;  /* cannot know who sets that register */
+
  else return pc;  /* current position sets that register */
+
}
+

+

+
/*
+
** try to find last instruction before 'lastpc' that modified register 'reg'
+
*/
+
static int findsetreg (Proto *p, int lastpc, int reg) {
+
  int pc;
+
  int setreg = -1;  /* keep last instruction that changed 'reg' */
+
  int jmptarget = 0;  /* any code before this address is conditional */
+
  for (pc = 0; pc < lastpc; pc++) {
+
    Instruction i = p->code[pc];
+
    OpCode op = GET_OPCODE(i);
+
    int a = GETARG_A(i);
+
    switch (op) {
+
      case OP_LOADNIL: {
+
        int b = GETARG_B(i);
+
        if (a <= reg && reg <= a + b)  /* set registers from 'a' to 'a+b' */
+
          setreg = filterpc(pc, jmptarget);
+
        break;
+
      }
+
      case OP_TFORCALL: {
+
        if (reg >= a + 2)  /* affect all regs above its base */
+
          setreg = filterpc(pc, jmptarget);
+
        break;
+
      }
+
      case OP_CALL:
+
      case OP_TAILCALL: {
+
        if (reg >= a)  /* affect all registers above base */
+
          setreg = filterpc(pc, jmptarget);
+
        break;
+
      }
+
      case OP_JMP: {
+
        int b = GETARG_sBx(i);
+
        int dest = pc + 1 + b;
+
        /* jump is forward and do not skip 'lastpc'? */
+
        if (pc < dest && dest <= lastpc) {
+
          if (dest > jmptarget)
+
            jmptarget = dest;  /* update 'jmptarget' */
+
        }
+
        break;
+
      }
+
      default:
+
        if (testAMode(op) && reg == a)  /* any instruction that set A */
+
          setreg = filterpc(pc, jmptarget);
+
        break;
+
    }
+
  }
+
  return setreg;
+
}
+

+

+
static const char *getobjname (Proto *p, int lastpc, int reg,
+
                               const char **name) {
+
  int pc;
+
  *name = luaF_getlocalname(p, reg + 1, lastpc);
+
  if (*name)  /* is a local? */
+
    return "local";
+
  /* else try symbolic execution */
+
  pc = findsetreg(p, lastpc, reg);
+
  if (pc != -1) {  /* could find instruction? */
+
    Instruction i = p->code[pc];
+
    OpCode op = GET_OPCODE(i);
+
    switch (op) {
+
      case OP_MOVE: {
+
        int b = GETARG_B(i);  /* move from 'b' to 'a' */
+
        if (b < GETARG_A(i))
+
          return getobjname(p, pc, b, name);  /* get name for 'b' */
+
        break;
+
      }
+
      case OP_GETTABUP:
+
      case OP_GETTABLE: {
+
        int k = GETARG_C(i);  /* key index */
+
        int t = GETARG_B(i);  /* table index */
+
        const char *vn = (op == OP_GETTABLE)  /* name of indexed variable */
+
                         ? luaF_getlocalname(p, t + 1, pc)
+
                         : upvalname(p, t);
+
        kname(p, pc, k, name);
+
        return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
+
      }
+
      case OP_GETUPVAL: {
+
        *name = upvalname(p, GETARG_B(i));
+
        return "upvalue";
+
      }
+
      case OP_LOADK:
+
      case OP_LOADKX: {
+
        int b = (op == OP_LOADK) ? GETARG_Bx(i)
+
                                 : GETARG_Ax(p->code[pc + 1]);
+
        if (ttisstring(&p->k[b])) {
+
          *name = svalue(&p->k[b]);
+
          return "constant";
+
        }
+
        break;
+
      }
+
      case OP_SELF: {
+
        int k = GETARG_C(i);  /* key index */
+
        kname(p, pc, k, name);
+
        return "method";
+
      }
+
      default: break;  /* go through to return NULL */
+
    }
+
  }
+
  return NULL;  /* could not find reasonable name */
+
}
+

+

+
/*
+
** 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 */
+
  int pc = currentpc(ci);  /* calling instruction index */
+
  Instruction i = p->code[pc];  /* calling instruction */
+
  if (ci->callstatus & CIST_HOOKED) {  /* was it called inside a hook? */
+
    *name = "?";
+
    return "hook";
+
  }
+
  switch (GET_OPCODE(i)) {
+
    case OP_CALL:
+
    case OP_TAILCALL:
+
      return getobjname(p, pc, GETARG_A(i), name);  /* get function name */
+
    case OP_TFORCALL: {  /* for iterator */
+
      *name = "for iterator";
+
       return "for iterator";
+
    }
+
    /* other instructions can do calls through metamethods */
+
    case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
+
      tm = TM_INDEX;
+
      break;
+
    case OP_SETTABUP: case OP_SETTABLE:
+
      tm = TM_NEWINDEX;
+
      break;
+
    case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD:
+
    case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND:
+
    case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: {
+
      int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD);  /* ORDER OP */
+
      tm = cast(TMS, offset + cast_int(TM_ADD));  /* ORDER TM */
+
      break;
+
    }
+
    case OP_UNM: tm = TM_UNM; break;
+
    case OP_BNOT: tm = TM_BNOT; break;
+
    case OP_LEN: tm = TM_LEN; break;
+
    case OP_CONCAT: tm = TM_CONCAT; break;
+
    case OP_EQ: tm = TM_EQ; break;
+
    case OP_LT: tm = TM_LT; break;
+
    case OP_LE: tm = TM_LE; break;
+
    default:
+
      return NULL;  /* cannot find a reasonable name */
+
  }
+
  *name = getstr(G(L)->tmname[tm]);
+
  return "metamethod";
+
}
+

+
/* }====================================================== */
+

+

+

+
/*
+
** The subtraction of two potentially unrelated pointers is
+
** not ISO C, but it should not crash a program; the subsequent
+
** checks are ISO C and ensure a correct result.
+
*/
+
static int isinstack (CallInfo *ci, const TValue *o) {
+
  ptrdiff_t i = o - ci->u.l.base;
+
  return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o);
+
}
+

+

+
/*
+
** Checks whether value 'o' came from an upvalue. (That can only happen
+
** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
+
** upvalues.)
+
*/
+
static const char *getupvalname (CallInfo *ci, const TValue *o,
+
                                 const char **name) {
+
  LClosure *c = ci_func(ci);
+
  int i;
+
  for (i = 0; i < c->nupvalues; i++) {
+
    if (c->upvals[i]->v == o) {
+
      *name = upvalname(c->p, i);
+
      return "upvalue";
+
    }
+
  }
+
  return NULL;
+
}
+

+

+
static const char *varinfo (lua_State *L, const TValue *o) {
+
  const char *name = NULL;  /* to avoid warnings */
+
  CallInfo *ci = L->ci;
+
  const char *kind = NULL;
+
  if (isLua(ci)) {
+
    kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
+
    if (!kind && isinstack(ci, o))  /* no? try a register */
+
      kind = getobjname(ci_func(ci)->p, currentpc(ci),
+
                        cast_int(o - ci->u.l.base), &name);
+
  }
+
  return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
+
}
+

+

+
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+
  const char *t = luaT_objtypename(L, o);
+
  luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
+
}
+

+

+
l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
+
  if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
+
  luaG_typeerror(L, p1, "concatenate");
+
}
+

+

+
l_noret luaG_opinterror (lua_State *L, const TValue *p1,
+
                         const TValue *p2, const char *msg) {
+
  lua_Number temp;
+
  if (!tonumber(p1, &temp))  /* first operand is wrong? */
+
    p2 = p1;  /* now second is wrong */
+
  luaG_typeerror(L, p2, msg);
+
}
+

+

+
/*
+
** Error when both values are convertible to numbers, but not to integers
+
*/
+
l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
+
  lua_Integer temp;
+
  if (!tointeger(p1, &temp))
+
    p2 = p1;
+
  luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2));
+
}
+

+

+
l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
+
  const char *t1 = luaT_objtypename(L, p1);
+
  const char *t2 = luaT_objtypename(L, p2);
+
  if (strcmp(t1, t2) == 0)
+
    luaG_runerror(L, "attempt to compare two %s values", t1);
+
  else
+
    luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
+
}
+

+

+
/* add src:line information to 'msg' */
+
const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
+
                                        int line) {
+
  char buff[LUA_IDSIZE];
+
  if (src)
+
    luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
+
  else {  /* no source available; use "?" instead */
+
    buff[0] = '?'; buff[1] = '\0';
+
  }
+
  return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
+
}
+

+

+
l_noret luaG_errormsg (lua_State *L) {
+
  if (L->errfunc != 0) {  /* is there an error handling function? */
+
    StkId errfunc = restorestack(L, L->errfunc);
+
    setobjs2s(L, L->top, L->top - 1);  /* move argument */
+
    setobjs2s(L, L->top - 1, errfunc);  /* push function */
+
    L->top++;  /* assume EXTRA_STACK */
+
    luaD_callnoyield(L, L->top - 2, 1);  /* call it */
+
  }
+
  luaD_throw(L, LUA_ERRRUN);
+
}
+

+

+
l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
+
  CallInfo *ci = L->ci;
+
  const char *msg;
+
  va_list argp;
+
  luaC_checkGC(L);  /* error message uses memory */
+
  va_start(argp, fmt);
+
  msg = luaO_pushvfstring(L, fmt, argp);  /* format message */
+
  va_end(argp);
+
  if (isLua(ci))  /* if Lua function, add source:line information */
+
    luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
+
  luaG_errormsg(L);
+
}
+

+

+
void luaG_traceexec (lua_State *L) {
+
  CallInfo *ci = L->ci;
+
  lu_byte mask = L->hookmask;
+
  int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
+
  if (counthook)
+
    resethookcount(L);  /* reset count */
+
  else if (!(mask & LUA_MASKLINE))
+
    return;  /* no line hook and count != 0; nothing to be done */
+
  if (ci->callstatus & CIST_HOOKYIELD) {  /* called hook last time? */
+
    ci->callstatus &= ~CIST_HOOKYIELD;  /* erase mark */
+
    return;  /* do not call hook again (VM yielded, so it did not move) */
+
  }
+
  if (counthook)
+
    luaD_hook(L, LUA_HOOKCOUNT, -1);  /* call count hook */
+
  if (mask & LUA_MASKLINE) {
+
    Proto *p = ci_func(ci)->p;
+
    int npc = pcRel(ci->u.l.savedpc, p);
+
    int newline = getfuncline(p, npc);
+
    if (npc == 0 ||  /* call linehook when enter a new function, */
+
        ci->u.l.savedpc <= L->oldpc ||  /* when jump back (loop), or when */
+
        newline != getfuncline(p, pcRel(L->oldpc, p)))  /* enter a new line */
+
      luaD_hook(L, LUA_HOOKLINE, newline);  /* call line hook */
+
  }
+
  L->oldpc = ci->u.l.savedpc;
+
  if (L->status == LUA_YIELD) {  /* did hook yield? */
+
    if (counthook)
+
      L->hookcount = 1;  /* undo decrement to zero */
+
    ci->u.l.savedpc--;  /* undo increment (resume will increment it again) */
+
    ci->callstatus |= CIST_HOOKYIELD;  /* mark that it yielded */
+
    ci->func = L->top - 1;  /* protect stack below results */
+
    luaD_throw(L, LUA_YIELD);
+
  }
+
}
+

added external/lua/src/ldebug.h
@@ -0,0 +1,39 @@
+
/*
+
** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Auxiliary functions from Debug Interface module
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef ldebug_h
+
#define ldebug_h
+

+

+
#include "lstate.h"
+

+

+
#define pcRel(pc, p)	(cast(int, (pc) - (p)->code) - 1)
+

+
#define getfuncline(f,pc)	(((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
+

+
#define resethookcount(L)	(L->hookcount = L->basehookcount)
+

+

+
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
+
                                                const char *opname);
+
LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1,
+
                                                  const TValue *p2);
+
LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1,
+
                                                 const TValue *p2,
+
                                                 const char *msg);
+
LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1,
+
                                                 const TValue *p2);
+
LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
+
                                                 const TValue *p2);
+
LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
+
LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
+
                                                  TString *src, int line);
+
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
+
LUAI_FUNC void luaG_traceexec (lua_State *L);
+

+

+
#endif
added external/lua/src/ldo.c
@@ -0,0 +1,802 @@
+
/*
+
** $Id: ldo.c,v 2.157.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Stack and Call structure of Lua
+
** See Copyright Notice in lua.h
+
*/
+

+
#define ldo_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <setjmp.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lapi.h"
+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lfunc.h"
+
#include "lgc.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lopcodes.h"
+
#include "lparser.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "ltm.h"
+
#include "lundump.h"
+
#include "lvm.h"
+
#include "lzio.h"
+

+

+

+
#define errorstatus(s)	((s) > LUA_YIELD)
+

+

+
/*
+
** {======================================================
+
** Error-recovery functions
+
** =======================================================
+
*/
+

+
/*
+
** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
+
** default, Lua handles errors with exceptions when compiling as
+
** C++ code, with _longjmp/_setjmp when asked to use them, and with
+
** longjmp/setjmp otherwise.
+
*/
+
#if !defined(LUAI_THROW)				/* { */
+

+
#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP)	/* { */
+

+
/* C++ exceptions */
+
#define LUAI_THROW(L,c)		throw(c)
+
#define LUAI_TRY(L,c,a) \
+
	try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
+
#define luai_jmpbuf		int  /* dummy variable */
+

+
#elif defined(LUA_USE_POSIX)				/* }{ */
+

+
/* in POSIX, try _longjmp/_setjmp (more efficient) */
+
#define LUAI_THROW(L,c)		_longjmp((c)->b, 1)
+
#define LUAI_TRY(L,c,a)		if (_setjmp((c)->b) == 0) { a }
+
#define luai_jmpbuf		jmp_buf
+

+
#else							/* }{ */
+

+
/* ISO C handling with long jumps */
+
#define LUAI_THROW(L,c)		longjmp((c)->b, 1)
+
#define LUAI_TRY(L,c,a)		if (setjmp((c)->b) == 0) { a }
+
#define luai_jmpbuf		jmp_buf
+

+
#endif							/* } */
+

+
#endif							/* } */
+

+

+

+
/* chain list of long jump buffers */
+
struct lua_longjmp {
+
  struct lua_longjmp *previous;
+
  luai_jmpbuf b;
+
  volatile int status;  /* error code */
+
};
+

+

+
static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
+
  switch (errcode) {
+
    case LUA_ERRMEM: {  /* memory error? */
+
      setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
+
      break;
+
    }
+
    case LUA_ERRERR: {
+
      setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
+
      break;
+
    }
+
    default: {
+
      setobjs2s(L, oldtop, L->top - 1);  /* error message on current top */
+
      break;
+
    }
+
  }
+
  L->top = oldtop + 1;
+
}
+

+

+
l_noret luaD_throw (lua_State *L, int errcode) {
+
  if (L->errorJmp) {  /* thread has an error handler? */
+
    L->errorJmp->status = errcode;  /* set status */
+
    LUAI_THROW(L, L->errorJmp);  /* jump to it */
+
  }
+
  else {  /* thread has no error handler */
+
    global_State *g = G(L);
+
    L->status = cast_byte(errcode);  /* mark it as dead */
+
    if (g->mainthread->errorJmp) {  /* main thread has a handler? */
+
      setobjs2s(L, g->mainthread->top++, L->top - 1);  /* copy error obj. */
+
      luaD_throw(g->mainthread, errcode);  /* re-throw in main thread */
+
    }
+
    else {  /* no handler at all; abort */
+
      if (g->panic) {  /* panic function? */
+
        seterrorobj(L, errcode, L->top);  /* assume EXTRA_STACK */
+
        if (L->ci->top < L->top)
+
          L->ci->top = L->top;  /* pushing msg. can break this invariant */
+
        lua_unlock(L);
+
        g->panic(L);  /* call panic function (last chance to jump out) */
+
      }
+
      abort();
+
    }
+
  }
+
}
+

+

+
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
+
  unsigned short oldnCcalls = L->nCcalls;
+
  struct lua_longjmp lj;
+
  lj.status = LUA_OK;
+
  lj.previous = L->errorJmp;  /* chain new error handler */
+
  L->errorJmp = &lj;
+
  LUAI_TRY(L, &lj,
+
    (*f)(L, ud);
+
  );
+
  L->errorJmp = lj.previous;  /* restore old error handler */
+
  L->nCcalls = oldnCcalls;
+
  return lj.status;
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {==================================================================
+
** Stack reallocation
+
** ===================================================================
+
*/
+
static void correctstack (lua_State *L, TValue *oldstack) {
+
  CallInfo *ci;
+
  UpVal *up;
+
  L->top = (L->top - oldstack) + L->stack;
+
  for (up = L->openupval; up != NULL; up = up->u.open.next)
+
    up->v = (up->v - oldstack) + L->stack;
+
  for (ci = L->ci; ci != NULL; ci = ci->previous) {
+
    ci->top = (ci->top - oldstack) + L->stack;
+
    ci->func = (ci->func - oldstack) + L->stack;
+
    if (isLua(ci))
+
      ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
+
  }
+
}
+

+

+
/* some space for error handling */
+
#define ERRORSTACKSIZE	(LUAI_MAXSTACK + 200)
+

+

+
void luaD_reallocstack (lua_State *L, int newsize) {
+
  TValue *oldstack = L->stack;
+
  int lim = L->stacksize;
+
  lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
+
  lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
+
  luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
+
  for (; lim < newsize; lim++)
+
    setnilvalue(L->stack + lim); /* erase new segment */
+
  L->stacksize = newsize;
+
  L->stack_last = L->stack + newsize - EXTRA_STACK;
+
  correctstack(L, oldstack);
+
}
+

+

+
void luaD_growstack (lua_State *L, int n) {
+
  int size = L->stacksize;
+
  if (size > LUAI_MAXSTACK)  /* error after extra size? */
+
    luaD_throw(L, LUA_ERRERR);
+
  else {
+
    int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
+
    int newsize = 2 * size;
+
    if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
+
    if (newsize < needed) newsize = needed;
+
    if (newsize > LUAI_MAXSTACK) {  /* stack overflow? */
+
      luaD_reallocstack(L, ERRORSTACKSIZE);
+
      luaG_runerror(L, "stack overflow");
+
    }
+
    else
+
      luaD_reallocstack(L, newsize);
+
  }
+
}
+

+

+
static int stackinuse (lua_State *L) {
+
  CallInfo *ci;
+
  StkId lim = L->top;
+
  for (ci = L->ci; ci != NULL; ci = ci->previous) {
+
    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 */
+
}
+

+

+
void luaD_shrinkstack (lua_State *L) {
+
  int inuse = stackinuse(L);
+
  int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
+
  if (goodsize > LUAI_MAXSTACK)
+
    goodsize = LUAI_MAXSTACK;  /* respect stack limit */
+
  if (L->stacksize > LUAI_MAXSTACK)  /* had been handling stack overflow? */
+
    luaE_freeCI(L);  /* free all CIs (list grew because of an error) */
+
  else
+
    luaE_shrinkCI(L);  /* shrink list */
+
  /* if thread is currently not handling a stack overflow and its
+
     good size is smaller than current size, shrink its stack */
+
  if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
+
      goodsize < L->stacksize)
+
    luaD_reallocstack(L, goodsize);
+
  else  /* don't change stack */
+
    condmovestack(L,{},{});  /* (change only for debugging) */
+
}
+

+

+
void luaD_inctop (lua_State *L) {
+
  luaD_checkstack(L, 1);
+
  L->top++;
+
}
+

+
/* }================================================================== */
+

+

+
/*
+
** Call a hook for the given event. Make sure there is a hook to be
+
** called. (Both 'L->hook' and 'L->hookmask', which triggers this
+
** function, can be changed asynchronously by signals.)
+
*/
+
void luaD_hook (lua_State *L, int event, int line) {
+
  lua_Hook hook = L->hook;
+
  if (hook && L->allowhook) {  /* make sure there is a hook */
+
    CallInfo *ci = L->ci;
+
    ptrdiff_t top = savestack(L, L->top);
+
    ptrdiff_t ci_top = savestack(L, ci->top);
+
    lua_Debug ar;
+
    ar.event = event;
+
    ar.currentline = line;
+
    ar.i_ci = ci;
+
    luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
+
    ci->top = L->top + LUA_MINSTACK;
+
    lua_assert(ci->top <= L->stack_last);
+
    L->allowhook = 0;  /* cannot call hooks inside a hook */
+
    ci->callstatus |= CIST_HOOKED;
+
    lua_unlock(L);
+
    (*hook)(L, &ar);
+
    lua_lock(L);
+
    lua_assert(!L->allowhook);
+
    L->allowhook = 1;
+
    ci->top = restorestack(L, ci_top);
+
    L->top = restorestack(L, top);
+
    ci->callstatus &= ~CIST_HOOKED;
+
  }
+
}
+

+

+
static void callhook (lua_State *L, CallInfo *ci) {
+
  int hook = LUA_HOOKCALL;
+
  ci->u.l.savedpc++;  /* hooks assume 'pc' is already incremented */
+
  if (isLua(ci->previous) &&
+
      GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
+
    ci->callstatus |= CIST_TAIL;
+
    hook = LUA_HOOKTAILCALL;
+
  }
+
  luaD_hook(L, hook, -1);
+
  ci->u.l.savedpc--;  /* correct 'pc' */
+
}
+

+

+
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
+
  int i;
+
  int nfixargs = p->numparams;
+
  StkId base, fixed;
+
  /* move fixed parameters to final position */
+
  fixed = L->top - actual;  /* first fixed argument */
+
  base = L->top;  /* final position of first argument */
+
  for (i = 0; i < nfixargs && i < actual; i++) {
+
    setobjs2s(L, L->top++, fixed + i);
+
    setnilvalue(fixed + i);  /* erase original copy (for GC) */
+
  }
+
  for (; i < nfixargs; i++)
+
    setnilvalue(L->top++);  /* complete missing arguments */
+
  return base;
+
}
+

+

+
/*
+
** Check whether __call metafield of 'func' is a function. If so, put
+
** it in stack below original 'func' so that 'luaD_precall' can call
+
** it. Raise an error if __call metafield is not a function.
+
*/
+
static void tryfuncTM (lua_State *L, StkId func) {
+
  const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
+
  StkId p;
+
  if (!ttisfunction(tm))
+
    luaG_typeerror(L, func, "call");
+
  /* Open a hole inside the stack at 'func' */
+
  for (p = L->top; p > func; p--)
+
    setobjs2s(L, p, p-1);
+
  L->top++;  /* slot ensured by caller */
+
  setobj2s(L, func, tm);  /* tag method is the new function to be called */
+
}
+

+

+
/*
+
** 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)))
+

+

+
/* macro to check stack size, preserving 'p' */
+
#define checkstackp(L,n,p)  \
+
  luaD_checkstackaux(L, n, \
+
    ptrdiff_t t__ = savestack(L, p);  /* save 'p' */ \
+
    luaC_checkGC(L),  /* stack grow uses memory */ \
+
    p = restorestack(L, t__))  /* 'pos' part: restore 'p' */
+

+

+
/*
+
** Prepares a function call: checks the stack, creates a new CallInfo
+
** entry, fills in the relevant information, calls hook if needed.
+
** If function is a C function, does the call, too. (Otherwise, leave
+
** the execution ('luaV_execute') to the caller, to allow stackless
+
** calls.) Returns true iff function has been executed (C function).
+
*/
+
int luaD_precall (lua_State *L, StkId func, int nresults) {
+
  lua_CFunction f;
+
  CallInfo *ci;
+
  switch (ttype(func)) {
+
    case LUA_TCCL:  /* C closure */
+
      f = clCvalue(func)->f;
+
      goto Cfunc;
+
    case LUA_TLCF:  /* light C function */
+
      f = fvalue(func);
+
     Cfunc: {
+
      int n;  /* number of returns */
+
      checkstackp(L, LUA_MINSTACK, func);  /* ensure minimum stack size */
+
      ci = next_ci(L);  /* now 'enter' new function */
+
      ci->nresults = nresults;
+
      ci->func = func;
+
      ci->top = L->top + LUA_MINSTACK;
+
      lua_assert(ci->top <= L->stack_last);
+
      ci->callstatus = 0;
+
      if (L->hookmask & LUA_MASKCALL)
+
        luaD_hook(L, LUA_HOOKCALL, -1);
+
      lua_unlock(L);
+
      n = (*f)(L);  /* do the actual call */
+
      lua_lock(L);
+
      api_checknelems(L, n);
+
      luaD_poscall(L, ci, L->top - n, n);
+
      return 1;
+
    }
+
    case LUA_TLCL: {  /* Lua function: prepare its call */
+
      StkId base;
+
      Proto *p = clLvalue(func)->p;
+
      int n = cast_int(L->top - func) - 1;  /* number of real arguments */
+
      int fsize = p->maxstacksize;  /* frame size */
+
      checkstackp(L, fsize, func);
+
      if (p->is_vararg)
+
        base = adjust_varargs(L, p, n);
+
      else {  /* non vararg function */
+
        for (; n < p->numparams; n++)
+
          setnilvalue(L->top++);  /* complete missing arguments */
+
        base = func + 1;
+
      }
+
      ci = next_ci(L);  /* now 'enter' new function */
+
      ci->nresults = nresults;
+
      ci->func = func;
+
      ci->u.l.base = base;
+
      L->top = ci->top = base + fsize;
+
      lua_assert(ci->top <= L->stack_last);
+
      ci->u.l.savedpc = p->code;  /* starting point */
+
      ci->callstatus = CIST_LUA;
+
      if (L->hookmask & LUA_MASKCALL)
+
        callhook(L, ci);
+
      return 0;
+
    }
+
    default: {  /* not a function */
+
      checkstackp(L, 1, func);  /* ensure space for metamethod */
+
      tryfuncTM(L, func);  /* try to get '__call' metamethod */
+
      return luaD_precall(L, func, nresults);  /* now it must be a function */
+
    }
+
  }
+
}
+

+

+
/*
+
** Check appropriate error for stack overflow ("regular" overflow or
+
** overflow while handling stack overflow). If 'nCalls' is larger than
+
** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but
+
** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to
+
** allow overflow handling to work)
+
*/
+
static void stackerror (lua_State *L) {
+
  if (L->nCcalls == LUAI_MAXCCALLS)
+
    luaG_runerror(L, "C stack overflow");
+
  else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
+
    luaD_throw(L, LUA_ERRERR);  /* error while handing stack error */
+
}
+

+

+
/*
+
** Call a function (C or Lua). The function to be called is at *func.
+
** The arguments are on the stack, right after the function.
+
** When returns, all the results are on the stack, starting at the original
+
** function position.
+
*/
+
void luaD_call (lua_State *L, StkId func, int nResults) {
+
  if (++L->nCcalls >= LUAI_MAXCCALLS)
+
    stackerror(L);
+
  if (!luaD_precall(L, func, nResults))  /* is a Lua function? */
+
    luaV_execute(L);  /* call it */
+
  L->nCcalls--;
+
}
+

+

+
/*
+
** Similar to 'luaD_call', but does not allow yields during the call
+
*/
+
void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
+
  L->nny++;
+
  luaD_call(L, func, nResults);
+
  L->nny--;
+
}
+

+

+
/*
+
** Completes the execution of an interrupted C function, calling its
+
** continuation function.
+
*/
+
static void finishCcall (lua_State *L, int status) {
+
  CallInfo *ci = L->ci;
+
  int n;
+
  /* must have a continuation and must be able to call it */
+
  lua_assert(ci->u.c.k != NULL && L->nny == 0);
+
  /* error status can only happen in a protected call */
+
  lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
+
  if (ci->callstatus & CIST_YPCALL) {  /* was inside a pcall? */
+
    ci->callstatus &= ~CIST_YPCALL;  /* continuation is also inside it */
+
    L->errfunc = ci->u.c.old_errfunc;  /* with the same error function */
+
  }
+
  /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
+
     handled */
+
  adjustresults(L, ci->nresults);
+
  lua_unlock(L);
+
  n = (*ci->u.c.k)(L, status, ci->u.c.ctx);  /* call continuation function */
+
  lua_lock(L);
+
  api_checknelems(L, n);
+
  luaD_poscall(L, ci, L->top - n, n);  /* finish 'luaD_precall' */
+
}
+

+

+
/*
+
** Executes "full continuation" (everything in the stack) of a
+
** previously interrupted coroutine until the stack is empty (or another
+
** interruption long-jumps out of the loop). If the coroutine is
+
** recovering from an error, 'ud' points to the error status, which must
+
** be passed to the first continuation function (otherwise the default
+
** status is LUA_YIELD).
+
*/
+
static void unroll (lua_State *L, void *ud) {
+
  if (ud != NULL)  /* error status? */
+
    finishCcall(L, *(int *)ud);  /* finish 'lua_pcallk' callee */
+
  while (L->ci != &L->base_ci) {  /* something in the stack */
+
    if (!isLua(L->ci))  /* C function? */
+
      finishCcall(L, LUA_YIELD);  /* complete its execution */
+
    else {  /* Lua function */
+
      luaV_finishOp(L);  /* finish interrupted instruction */
+
      luaV_execute(L);  /* execute down to higher C 'boundary' */
+
    }
+
  }
+
}
+

+

+
/*
+
** Try to find a suspended protected call (a "recover point") for the
+
** given thread.
+
*/
+
static CallInfo *findpcall (lua_State *L) {
+
  CallInfo *ci;
+
  for (ci = L->ci; ci != NULL; ci = ci->previous) {  /* search for a pcall */
+
    if (ci->callstatus & CIST_YPCALL)
+
      return ci;
+
  }
+
  return NULL;  /* no pending pcall */
+
}
+

+

+
/*
+
** Recovers from an error in a coroutine. Finds a recover point (if
+
** there is one) and completes the execution of the interrupted
+
** 'luaD_pcall'. If there is no recover point, returns zero.
+
*/
+
static int recover (lua_State *L, int status) {
+
  StkId oldtop;
+
  CallInfo *ci = findpcall(L);
+
  if (ci == NULL) return 0;  /* no recovery point */
+
  /* "finish" luaD_pcall */
+
  oldtop = restorestack(L, ci->extra);
+
  luaF_close(L, oldtop);
+
  seterrorobj(L, status, oldtop);
+
  L->ci = ci;
+
  L->allowhook = getoah(ci->callstatus);  /* restore original 'allowhook' */
+
  L->nny = 0;  /* should be zero to be yieldable */
+
  luaD_shrinkstack(L);
+
  L->errfunc = ci->u.c.old_errfunc;
+
  return 1;  /* continue running the coroutine */
+
}
+

+

+
/*
+
** Signal an error in the call to 'lua_resume', not in the execution
+
** of the coroutine itself. (Such errors should not be handled by any
+
** coroutine error handler and should not kill the coroutine.)
+
*/
+
static int resume_error (lua_State *L, const char *msg, int narg) {
+
  L->top -= narg;  /* remove args from the stack */
+
  setsvalue2s(L, L->top, luaS_new(L, msg));  /* push error message */
+
  api_incr_top(L);
+
  lua_unlock(L);
+
  return LUA_ERRRUN;
+
}
+

+

+
/*
+
** Do the work for 'lua_resume' in protected mode. Most of the work
+
** depends on the status of the coroutine: initial state, suspended
+
** inside a hook, or regularly suspended (optionally with a continuation
+
** function), plus erroneous cases: non-suspended coroutine or dead
+
** coroutine.
+
*/
+
static void resume (lua_State *L, void *ud) {
+
  int n = *(cast(int*, ud));  /* number of arguments */
+
  StkId firstArg = L->top - n;  /* first argument */
+
  CallInfo *ci = L->ci;
+
  if (L->status == LUA_OK) {  /* starting a coroutine? */
+
    if (!luaD_precall(L, firstArg - 1, LUA_MULTRET))  /* Lua function? */
+
      luaV_execute(L);  /* call it */
+
  }
+
  else {  /* resuming from previous yield */
+
    lua_assert(L->status == LUA_YIELD);
+
    L->status = LUA_OK;  /* mark that it is running (again) */
+
    ci->func = restorestack(L, ci->extra);
+
    if (isLua(ci))  /* yielded inside a hook? */
+
      luaV_execute(L);  /* just continue running Lua code */
+
    else {  /* 'common' yield */
+
      if (ci->u.c.k != NULL) {  /* does it have a continuation function? */
+
        lua_unlock(L);
+
        n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
+
        lua_lock(L);
+
        api_checknelems(L, n);
+
        firstArg = L->top - n;  /* yield results come from continuation */
+
      }
+
      luaD_poscall(L, ci, firstArg, n);  /* finish 'luaD_precall' */
+
    }
+
    unroll(L, NULL);  /* run continuation */
+
  }
+
}
+

+

+
LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
+
  int status;
+
  unsigned short oldnny = L->nny;  /* save "number of non-yieldable" calls */
+
  lua_lock(L);
+
  if (L->status == LUA_OK) {  /* may be starting a coroutine */
+
    if (L->ci != &L->base_ci)  /* not in base level? */
+
      return resume_error(L, "cannot resume non-suspended coroutine", nargs);
+
  }
+
  else if (L->status != LUA_YIELD)
+
    return resume_error(L, "cannot resume dead coroutine", nargs);
+
  L->nCcalls = (from) ? from->nCcalls + 1 : 1;
+
  if (L->nCcalls >= LUAI_MAXCCALLS)
+
    return resume_error(L, "C stack overflow", nargs);
+
  luai_userstateresume(L, nargs);
+
  L->nny = 0;  /* allow yields */
+
  api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
+
  status = luaD_rawrunprotected(L, resume, &nargs);
+
  if (status == -1)  /* error calling 'lua_resume'? */
+
    status = LUA_ERRRUN;
+
  else {  /* continue running after recoverable errors */
+
    while (errorstatus(status) && recover(L, status)) {
+
      /* unroll continuation */
+
      status = luaD_rawrunprotected(L, unroll, &status);
+
    }
+
    if (errorstatus(status)) {  /* unrecoverable error? */
+
      L->status = cast_byte(status);  /* mark thread as 'dead' */
+
      seterrorobj(L, status, L->top);  /* push error message */
+
      L->ci->top = L->top;
+
    }
+
    else lua_assert(status == L->status);  /* normal end or yield */
+
  }
+
  L->nny = oldnny;  /* restore 'nny' */
+
  L->nCcalls--;
+
  lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
+
  lua_unlock(L);
+
  return status;
+
}
+

+

+
LUA_API int lua_isyieldable (lua_State *L) {
+
  return (L->nny == 0);
+
}
+

+

+
LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
+
                        lua_KFunction k) {
+
  CallInfo *ci = L->ci;
+
  luai_userstateyield(L, nresults);
+
  lua_lock(L);
+
  api_checknelems(L, nresults);
+
  if (L->nny > 0) {
+
    if (L != G(L)->mainthread)
+
      luaG_runerror(L, "attempt to yield across a C-call boundary");
+
    else
+
      luaG_runerror(L, "attempt to yield from outside a coroutine");
+
  }
+
  L->status = LUA_YIELD;
+
  ci->extra = savestack(L, ci->func);  /* save current 'func' */
+
  if (isLua(ci)) {  /* inside a hook? */
+
    api_check(L, k == NULL, "hooks cannot continue after yielding");
+
  }
+
  else {
+
    if ((ci->u.c.k = k) != NULL)  /* is there a continuation? */
+
      ci->u.c.ctx = ctx;  /* save context */
+
    ci->func = L->top - nresults - 1;  /* protect stack below results */
+
    luaD_throw(L, LUA_YIELD);
+
  }
+
  lua_assert(ci->callstatus & CIST_HOOKED);  /* must be inside a hook */
+
  lua_unlock(L);
+
  return 0;  /* return to 'luaD_hook' */
+
}
+

+

+
int luaD_pcall (lua_State *L, Pfunc func, void *u,
+
                ptrdiff_t old_top, ptrdiff_t ef) {
+
  int status;
+
  CallInfo *old_ci = L->ci;
+
  lu_byte old_allowhooks = L->allowhook;
+
  unsigned short old_nny = L->nny;
+
  ptrdiff_t old_errfunc = L->errfunc;
+
  L->errfunc = ef;
+
  status = luaD_rawrunprotected(L, func, u);
+
  if (status != LUA_OK) {  /* an error occurred? */
+
    StkId oldtop = restorestack(L, old_top);
+
    luaF_close(L, oldtop);  /* close possible pending closures */
+
    seterrorobj(L, status, oldtop);
+
    L->ci = old_ci;
+
    L->allowhook = old_allowhooks;
+
    L->nny = old_nny;
+
    luaD_shrinkstack(L);
+
  }
+
  L->errfunc = old_errfunc;
+
  return status;
+
}
+

+

+

+
/*
+
** Execute a protected parser.
+
*/
+
struct SParser {  /* data to 'f_parser' */
+
  ZIO *z;
+
  Mbuffer buff;  /* dynamic structure used by the scanner */
+
  Dyndata dyd;  /* dynamic structures used by the parser */
+
  const char *mode;
+
  const char *name;
+
};
+

+

+
static void checkmode (lua_State *L, const char *mode, const char *x) {
+
  if (mode && strchr(mode, x[0]) == NULL) {
+
    luaO_pushfstring(L,
+
       "attempt to load a %s chunk (mode is '%s')", x, mode);
+
    luaD_throw(L, LUA_ERRSYNTAX);
+
  }
+
}
+

+

+
static void f_parser (lua_State *L, void *ud) {
+
  LClosure *cl;
+
  struct SParser *p = cast(struct SParser *, ud);
+
  int c = zgetc(p->z);  /* read first character */
+
  if (c == LUA_SIGNATURE[0]) {
+
    checkmode(L, p->mode, "binary");
+
    cl = luaU_undump(L, p->z, p->name);
+
  }
+
  else {
+
    checkmode(L, p->mode, "text");
+
    cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
+
  }
+
  lua_assert(cl->nupvalues == cl->p->sizeupvalues);
+
  luaF_initupvals(L, cl);
+
}
+

+

+
int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
+
                                        const char *mode) {
+
  struct SParser p;
+
  int status;
+
  L->nny++;  /* cannot yield during parsing */
+
  p.z = z; p.name = name; p.mode = mode;
+
  p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
+
  p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
+
  p.dyd.label.arr = NULL; p.dyd.label.size = 0;
+
  luaZ_initbuffer(L, &p.buff);
+
  status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
+
  luaZ_freebuffer(L, &p.buff);
+
  luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
+
  luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
+
  luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
+
  L->nny--;
+
  return status;
+
}
+

+

added external/lua/src/ldo.h
@@ -0,0 +1,58 @@
+
/*
+
** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Stack and Call structure of Lua
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef ldo_h
+
#define ldo_h
+

+

+
#include "lobject.h"
+
#include "lstate.h"
+
#include "lzio.h"
+

+

+
/*
+
** Macro to check stack size and grow stack if needed.  Parameters
+
** 'pre'/'pos' allow the macro to preserve a pointer into the
+
** stack across reallocations, doing the work only when needed.
+
** 'condmovestack' is used in heavy tests to force a stack reallocation
+
** at every check.
+
*/
+
#define luaD_checkstackaux(L,n,pre,pos)  \
+
	if (L->stack_last - L->top <= (n)) \
+
	  { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); }
+

+
/* In general, 'pre'/'pos' are empty (nothing to save) */
+
#define luaD_checkstack(L,n)	luaD_checkstackaux(L,n,(void)0,(void)0)
+

+

+

+
#define savestack(L,p)		((char *)(p) - (char *)L->stack)
+
#define restorestack(L,n)	((TValue *)((char *)L->stack + (n)))
+

+

+
/* type of protected functions, to be ran by 'runprotected' */
+
typedef void (*Pfunc) (lua_State *L, void *ud);
+

+
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
+
                                                  const char *mode);
+
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
+
LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
+
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
+
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
+
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
+
                                        ptrdiff_t oldtop, ptrdiff_t ef);
+
LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult,
+
                                          int nres);
+
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
+
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
+
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
+
LUAI_FUNC void luaD_inctop (lua_State *L);
+

+
LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
+
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
+

+
#endif
+

added external/lua/src/ldump.c
@@ -0,0 +1,215 @@
+
/*
+
** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $
+
** save precompiled Lua chunks
+
** See Copyright Notice in lua.h
+
*/
+

+
#define ldump_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <stddef.h>
+

+
#include "lua.h"
+

+
#include "lobject.h"
+
#include "lstate.h"
+
#include "lundump.h"
+

+

+
typedef struct {
+
  lua_State *L;
+
  lua_Writer writer;
+
  void *data;
+
  int strip;
+
  int status;
+
} DumpState;
+

+

+
/*
+
** All high-level dumps go through DumpVector; you can change it to
+
** change the endianness of the result
+
*/
+
#define DumpVector(v,n,D)	DumpBlock(v,(n)*sizeof((v)[0]),D)
+

+
#define DumpLiteral(s,D)	DumpBlock(s, sizeof(s) - sizeof(char), D)
+

+

+
static void DumpBlock (const void *b, size_t size, DumpState *D) {
+
  if (D->status == 0 && size > 0) {
+
    lua_unlock(D->L);
+
    D->status = (*D->writer)(D->L, b, size, D->data);
+
    lua_lock(D->L);
+
  }
+
}
+

+

+
#define DumpVar(x,D)		DumpVector(&x,1,D)
+

+

+
static void DumpByte (int y, DumpState *D) {
+
  lu_byte x = (lu_byte)y;
+
  DumpVar(x, D);
+
}
+

+

+
static void DumpInt (int x, DumpState *D) {
+
  DumpVar(x, D);
+
}
+

+

+
static void DumpNumber (lua_Number x, DumpState *D) {
+
  DumpVar(x, D);
+
}
+

+

+
static void DumpInteger (lua_Integer x, DumpState *D) {
+
  DumpVar(x, D);
+
}
+

+

+
static void DumpString (const TString *s, DumpState *D) {
+
  if (s == NULL)
+
    DumpByte(0, D);
+
  else {
+
    size_t size = tsslen(s) + 1;  /* include trailing '\0' */
+
    const char *str = getstr(s);
+
    if (size < 0xFF)
+
      DumpByte(cast_int(size), D);
+
    else {
+
      DumpByte(0xFF, D);
+
      DumpVar(size, D);
+
    }
+
    DumpVector(str, size - 1, D);  /* no need to save '\0' */
+
  }
+
}
+

+

+
static void DumpCode (const Proto *f, DumpState *D) {
+
  DumpInt(f->sizecode, D);
+
  DumpVector(f->code, f->sizecode, D);
+
}
+

+

+
static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
+

+
static void DumpConstants (const Proto *f, DumpState *D) {
+
  int i;
+
  int n = f->sizek;
+
  DumpInt(n, D);
+
  for (i = 0; i < n; i++) {
+
    const TValue *o = &f->k[i];
+
    DumpByte(ttype(o), D);
+
    switch (ttype(o)) {
+
    case LUA_TNIL:
+
      break;
+
    case LUA_TBOOLEAN:
+
      DumpByte(bvalue(o), D);
+
      break;
+
    case LUA_TNUMFLT:
+
      DumpNumber(fltvalue(o), D);
+
      break;
+
    case LUA_TNUMINT:
+
      DumpInteger(ivalue(o), D);
+
      break;
+
    case LUA_TSHRSTR:
+
    case LUA_TLNGSTR:
+
      DumpString(tsvalue(o), D);
+
      break;
+
    default:
+
      lua_assert(0);
+
    }
+
  }
+
}
+

+

+
static void DumpProtos (const Proto *f, DumpState *D) {
+
  int i;
+
  int n = f->sizep;
+
  DumpInt(n, D);
+
  for (i = 0; i < n; i++)
+
    DumpFunction(f->p[i], f->source, D);
+
}
+

+

+
static void DumpUpvalues (const Proto *f, DumpState *D) {
+
  int i, n = f->sizeupvalues;
+
  DumpInt(n, D);
+
  for (i = 0; i < n; i++) {
+
    DumpByte(f->upvalues[i].instack, D);
+
    DumpByte(f->upvalues[i].idx, D);
+
  }
+
}
+

+

+
static void DumpDebug (const Proto *f, DumpState *D) {
+
  int i, n;
+
  n = (D->strip) ? 0 : f->sizelineinfo;
+
  DumpInt(n, D);
+
  DumpVector(f->lineinfo, n, D);
+
  n = (D->strip) ? 0 : f->sizelocvars;
+
  DumpInt(n, D);
+
  for (i = 0; i < n; i++) {
+
    DumpString(f->locvars[i].varname, D);
+
    DumpInt(f->locvars[i].startpc, D);
+
    DumpInt(f->locvars[i].endpc, D);
+
  }
+
  n = (D->strip) ? 0 : f->sizeupvalues;
+
  DumpInt(n, D);
+
  for (i = 0; i < n; i++)
+
    DumpString(f->upvalues[i].name, D);
+
}
+

+

+
static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
+
  if (D->strip || f->source == psource)
+
    DumpString(NULL, D);  /* no debug info or same source as its parent */
+
  else
+
    DumpString(f->source, D);
+
  DumpInt(f->linedefined, D);
+
  DumpInt(f->lastlinedefined, D);
+
  DumpByte(f->numparams, D);
+
  DumpByte(f->is_vararg, D);
+
  DumpByte(f->maxstacksize, D);
+
  DumpCode(f, D);
+
  DumpConstants(f, D);
+
  DumpUpvalues(f, D);
+
  DumpProtos(f, D);
+
  DumpDebug(f, D);
+
}
+

+

+
static void DumpHeader (DumpState *D) {
+
  DumpLiteral(LUA_SIGNATURE, D);
+
  DumpByte(LUAC_VERSION, D);
+
  DumpByte(LUAC_FORMAT, D);
+
  DumpLiteral(LUAC_DATA, D);
+
  DumpByte(sizeof(int), D);
+
  DumpByte(sizeof(size_t), D);
+
  DumpByte(sizeof(Instruction), D);
+
  DumpByte(sizeof(lua_Integer), D);
+
  DumpByte(sizeof(lua_Number), D);
+
  DumpInteger(LUAC_INT, D);
+
  DumpNumber(LUAC_NUM, D);
+
}
+

+

+
/*
+
** dump Lua function as precompiled chunk
+
*/
+
int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
+
              int strip) {
+
  DumpState D;
+
  D.L = L;
+
  D.writer = w;
+
  D.data = data;
+
  D.strip = strip;
+
  D.status = 0;
+
  DumpHeader(&D);
+
  DumpByte(f->sizeupvalues, &D);
+
  DumpFunction(f, NULL, &D);
+
  return D.status;
+
}
+

added external/lua/src/lfunc.c
@@ -0,0 +1,151 @@
+
/*
+
** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $
+
** Auxiliary functions to manipulate prototypes and closures
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lfunc_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <stddef.h>
+

+
#include "lua.h"
+

+
#include "lfunc.h"
+
#include "lgc.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lstate.h"
+

+

+

+
CClosure *luaF_newCclosure (lua_State *L, int n) {
+
  GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n));
+
  CClosure *c = gco2ccl(o);
+
  c->nupvalues = cast_byte(n);
+
  return c;
+
}
+

+

+
LClosure *luaF_newLclosure (lua_State *L, int n) {
+
  GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n));
+
  LClosure *c = gco2lcl(o);
+
  c->p = NULL;
+
  c->nupvalues = cast_byte(n);
+
  while (n--) c->upvals[n] = NULL;
+
  return c;
+
}
+

+
/*
+
** fill a closure with new closed upvalues
+
*/
+
void luaF_initupvals (lua_State *L, LClosure *cl) {
+
  int i;
+
  for (i = 0; i < cl->nupvalues; i++) {
+
    UpVal *uv = luaM_new(L, UpVal);
+
    uv->refcount = 1;
+
    uv->v = &uv->u.value;  /* make it closed */
+
    setnilvalue(uv->v);
+
    cl->upvals[i] = uv;
+
  }
+
}
+

+

+
UpVal *luaF_findupval (lua_State *L, StkId level) {
+
  UpVal **pp = &L->openupval;
+
  UpVal *p;
+
  UpVal *uv;
+
  lua_assert(isintwups(L) || L->openupval == NULL);
+
  while (*pp != NULL && (p = *pp)->v >= level) {
+
    lua_assert(upisopen(p));
+
    if (p->v == level)  /* found a corresponding upvalue? */
+
      return p;  /* return it */
+
    pp = &p->u.open.next;
+
  }
+
  /* not found: create a new upvalue */
+
  uv = luaM_new(L, UpVal);
+
  uv->refcount = 0;
+
  uv->u.open.next = *pp;  /* link it to list of open upvalues */
+
  uv->u.open.touched = 1;
+
  *pp = uv;
+
  uv->v = level;  /* current value lives in the stack */
+
  if (!isintwups(L)) {  /* thread not in list of threads with upvalues? */
+
    L->twups = G(L)->twups;  /* link it to the list */
+
    G(L)->twups = L;
+
  }
+
  return uv;
+
}
+

+

+
void luaF_close (lua_State *L, StkId level) {
+
  UpVal *uv;
+
  while (L->openupval != NULL && (uv = L->openupval)->v >= level) {
+
    lua_assert(upisopen(uv));
+
    L->openupval = uv->u.open.next;  /* remove from 'open' list */
+
    if (uv->refcount == 0)  /* no references? */
+
      luaM_free(L, uv);  /* free upvalue */
+
    else {
+
      setobj(L, &uv->u.value, uv->v);  /* move value to upvalue slot */
+
      uv->v = &uv->u.value;  /* now current value lives here */
+
      luaC_upvalbarrier(L, uv);
+
    }
+
  }
+
}
+

+

+
Proto *luaF_newproto (lua_State *L) {
+
  GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
+
  Proto *f = gco2p(o);
+
  f->k = NULL;
+
  f->sizek = 0;
+
  f->p = NULL;
+
  f->sizep = 0;
+
  f->code = NULL;
+
  f->cache = NULL;
+
  f->sizecode = 0;
+
  f->lineinfo = NULL;
+
  f->sizelineinfo = 0;
+
  f->upvalues = NULL;
+
  f->sizeupvalues = 0;
+
  f->numparams = 0;
+
  f->is_vararg = 0;
+
  f->maxstacksize = 0;
+
  f->locvars = NULL;
+
  f->sizelocvars = 0;
+
  f->linedefined = 0;
+
  f->lastlinedefined = 0;
+
  f->source = NULL;
+
  return f;
+
}
+

+

+
void luaF_freeproto (lua_State *L, Proto *f) {
+
  luaM_freearray(L, f->code, f->sizecode);
+
  luaM_freearray(L, f->p, f->sizep);
+
  luaM_freearray(L, f->k, f->sizek);
+
  luaM_freearray(L, f->lineinfo, f->sizelineinfo);
+
  luaM_freearray(L, f->locvars, f->sizelocvars);
+
  luaM_freearray(L, f->upvalues, f->sizeupvalues);
+
  luaM_free(L, f);
+
}
+

+

+
/*
+
** Look for n-th local variable at line 'line' in function 'func'.
+
** Returns NULL if not found.
+
*/
+
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
+
  int i;
+
  for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
+
    if (pc < f->locvars[i].endpc) {  /* is variable active? */
+
      local_number--;
+
      if (local_number == 0)
+
        return getstr(f->locvars[i].varname);
+
    }
+
  }
+
  return NULL;  /* not found */
+
}
+

added external/lua/src/lfunc.h
@@ -0,0 +1,61 @@
+
/*
+
** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $
+
** Auxiliary functions to manipulate prototypes and closures
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lfunc_h
+
#define lfunc_h
+

+

+
#include "lobject.h"
+

+

+
#define sizeCclosure(n)	(cast(int, sizeof(CClosure)) + \
+
                         cast(int, sizeof(TValue)*((n)-1)))
+

+
#define sizeLclosure(n)	(cast(int, sizeof(LClosure)) + \
+
                         cast(int, sizeof(TValue *)*((n)-1)))
+

+

+
/* test whether thread is in 'twups' list */
+
#define isintwups(L)	(L->twups != L)
+

+

+
/*
+
** maximum number of upvalues in a closure (both C and Lua). (Value
+
** must fit in a VM register.)
+
*/
+
#define MAXUPVAL	255
+

+

+
/*
+
** Upvalues for Lua closures
+
*/
+
struct UpVal {
+
  TValue *v;  /* points to stack or to its own value */
+
  lu_mem refcount;  /* reference counter */
+
  union {
+
    struct {  /* (when open) */
+
      UpVal *next;  /* linked list */
+
      int touched;  /* mark to avoid cycles with dead threads */
+
    } open;
+
    TValue value;  /* the value (when closed) */
+
  } u;
+
};
+

+
#define upisopen(up)	((up)->v != &(up)->u.value)
+

+

+
LUAI_FUNC Proto *luaF_newproto (lua_State *L);
+
LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
+
LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
+
LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
+
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
+
LUAI_FUNC void luaF_close (lua_State *L, StkId level);
+
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
+
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
+
                                         int pc);
+

+

+
#endif
added external/lua/src/lgc.c
@@ -0,0 +1,1179 @@
+
/*
+
** $Id: lgc.c,v 2.215.1.2 2017/08/31 16:15:27 roberto Exp $
+
** Garbage Collector
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lgc_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lfunc.h"
+
#include "lgc.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "ltm.h"
+

+

+
/*
+
** internal state for collector while inside the atomic phase. The
+
** collector should never be in this state while running regular code.
+
*/
+
#define GCSinsideatomic		(GCSpause + 1)
+

+
/*
+
** cost of sweeping one element (the size of a small object divided
+
** by some adjust for the sweep speed)
+
*/
+
#define GCSWEEPCOST	((sizeof(TString) + 4) / 4)
+

+
/* maximum number of elements to sweep in each single step */
+
#define GCSWEEPMAX	(cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))
+

+
/* cost of calling one finalizer */
+
#define GCFINALIZECOST	GCSWEEPCOST
+

+

+
/*
+
** macro to adjust 'stepmul': 'stepmul' is actually used like
+
** 'stepmul / STEPMULADJ' (value chosen by tests)
+
*/
+
#define STEPMULADJ		200
+

+

+
/*
+
** macro to adjust 'pause': 'pause' is actually used like
+
** 'pause / PAUSEADJ' (value chosen by tests)
+
*/
+
#define PAUSEADJ		100
+

+

+
/*
+
** 'makewhite' erases all color bits then sets only the current white
+
** bit
+
*/
+
#define maskcolors	(~(bitmask(BLACKBIT) | WHITEBITS))
+
#define makewhite(g,x)	\
+
 (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g)))
+

+
#define white2gray(x)	resetbits(x->marked, WHITEBITS)
+
#define black2gray(x)	resetbit(x->marked, BLACKBIT)
+

+

+
#define valiswhite(x)   (iscollectable(x) && iswhite(gcvalue(x)))
+

+
#define checkdeadkey(n)	lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
+

+

+
#define checkconsistency(obj)  \
+
  lua_longassert(!iscollectable(obj) || righttt(obj))
+

+

+
#define markvalue(g,o) { checkconsistency(o); \
+
  if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
+

+
#define markobject(g,t)	{ if (iswhite(t)) reallymarkobject(g, obj2gco(t)); }
+

+
/*
+
** mark an object that can be NULL (either because it is really optional,
+
** or it was stripped as debug info, or inside an uncompleted structure)
+
*/
+
#define markobjectN(g,t)	{ if (t) markobject(g,t); }
+

+
static void reallymarkobject (global_State *g, GCObject *o);
+

+

+
/*
+
** {======================================================
+
** Generic functions
+
** =======================================================
+
*/
+

+

+
/*
+
** one after last element in a hash array
+
*/
+
#define gnodelast(h)	gnode(h, cast(size_t, sizenode(h)))
+

+

+
/*
+
** link collectable object 'o' into list pointed by 'p'
+
*/
+
#define linkgclist(o,p)	((o)->gclist = (p), (p) = obj2gco(o))
+

+

+
/*
+
** If key is not marked, mark its entry as dead. This allows key to be
+
** collected, but keeps its entry in the table.  A dead node is needed
+
** when Lua looks up for a key (it may be part of a chain) and when
+
** traversing a weak table (key might be removed from the table during
+
** traversal). Other places never manipulate dead keys, because its
+
** associated nil value is enough to signal that the entry is logically
+
** empty.
+
*/
+
static void removeentry (Node *n) {
+
  lua_assert(ttisnil(gval(n)));
+
  if (valiswhite(gkey(n)))
+
    setdeadvalue(wgkey(n));  /* unused and unmarked key; remove it */
+
}
+

+

+
/*
+
** tells whether a key or value can be cleared from a weak
+
** table. Non-collectable objects are never removed from weak
+
** tables. Strings behave as 'values', so are never removed too. for
+
** other objects: if really collected, cannot keep them; for objects
+
** being finalized, keep them in keys, but not in values
+
*/
+
static int iscleared (global_State *g, const TValue *o) {
+
  if (!iscollectable(o)) return 0;
+
  else if (ttisstring(o)) {
+
    markobject(g, tsvalue(o));  /* strings are 'values', so are never weak */
+
    return 0;
+
  }
+
  else return iswhite(gcvalue(o));
+
}
+

+

+
/*
+
** barrier that moves collector forward, that is, mark the white object
+
** being pointed by a black object. (If in sweep phase, clear the black
+
** object to white [sweep it] to avoid other barrier calls for this
+
** same object.)
+
*/
+
void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
+
  global_State *g = G(L);
+
  lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
+
  if (keepinvariant(g))  /* must keep invariant? */
+
    reallymarkobject(g, v);  /* restore invariant */
+
  else {  /* sweep phase */
+
    lua_assert(issweepphase(g));
+
    makewhite(g, o);  /* mark main obj. as white to avoid other barriers */
+
  }
+
}
+

+

+
/*
+
** barrier that moves collector backward, that is, mark the black object
+
** pointing to a white object as gray again.
+
*/
+
void luaC_barrierback_ (lua_State *L, Table *t) {
+
  global_State *g = G(L);
+
  lua_assert(isblack(t) && !isdead(g, t));
+
  black2gray(t);  /* make table gray (again) */
+
  linkgclist(t, g->grayagain);
+
}
+

+

+
/*
+
** barrier for assignments to closed upvalues. Because upvalues are
+
** shared among closures, it is impossible to know the color of all
+
** closures pointing to it. So, we assume that the object being assigned
+
** must be marked.
+
*/
+
void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) {
+
  global_State *g = G(L);
+
  GCObject *o = gcvalue(uv->v);
+
  lua_assert(!upisopen(uv));  /* ensured by macro luaC_upvalbarrier */
+
  if (keepinvariant(g))
+
    markobject(g, o);
+
}
+

+

+
void luaC_fix (lua_State *L, GCObject *o) {
+
  global_State *g = G(L);
+
  lua_assert(g->allgc == o);  /* object must be 1st in 'allgc' list! */
+
  white2gray(o);  /* they will be gray forever */
+
  g->allgc = o->next;  /* remove object from 'allgc' list */
+
  o->next = g->fixedgc;  /* link it to 'fixedgc' list */
+
  g->fixedgc = o;
+
}
+

+

+
/*
+
** create a new collectable object (with given type and size) and link
+
** it to 'allgc' list.
+
*/
+
GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
+
  global_State *g = G(L);
+
  GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz));
+
  o->marked = luaC_white(g);
+
  o->tt = tt;
+
  o->next = g->allgc;
+
  g->allgc = o;
+
  return o;
+
}
+

+
/* }====================================================== */
+

+

+

+
/*
+
** {======================================================
+
** Mark functions
+
** =======================================================
+
*/
+

+

+
/*
+
** mark an object. Userdata, strings, and closed upvalues are visited
+
** and turned black here. Other objects are marked gray and added
+
** to appropriate list to be visited (and turned black) later. (Open
+
** upvalues are already linked in 'headuv' list.)
+
*/
+
static void reallymarkobject (global_State *g, GCObject *o) {
+
 reentry:
+
  white2gray(o);
+
  switch (o->tt) {
+
    case LUA_TSHRSTR: {
+
      gray2black(o);
+
      g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
+
      break;
+
    }
+
    case LUA_TLNGSTR: {
+
      gray2black(o);
+
      g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
+
      break;
+
    }
+
    case LUA_TUSERDATA: {
+
      TValue uvalue;
+
      markobjectN(g, gco2u(o)->metatable);  /* mark its metatable */
+
      gray2black(o);
+
      g->GCmemtrav += sizeudata(gco2u(o));
+
      getuservalue(g->mainthread, gco2u(o), &uvalue);
+
      if (valiswhite(&uvalue)) {  /* markvalue(g, &uvalue); */
+
        o = gcvalue(&uvalue);
+
        goto reentry;
+
      }
+
      break;
+
    }
+
    case LUA_TLCL: {
+
      linkgclist(gco2lcl(o), g->gray);
+
      break;
+
    }
+
    case LUA_TCCL: {
+
      linkgclist(gco2ccl(o), g->gray);
+
      break;
+
    }
+
    case LUA_TTABLE: {
+
      linkgclist(gco2t(o), g->gray);
+
      break;
+
    }
+
    case LUA_TTHREAD: {
+
      linkgclist(gco2th(o), g->gray);
+
      break;
+
    }
+
    case LUA_TPROTO: {
+
      linkgclist(gco2p(o), g->gray);
+
      break;
+
    }
+
    default: lua_assert(0); break;
+
  }
+
}
+

+

+
/*
+
** mark metamethods for basic types
+
*/
+
static void markmt (global_State *g) {
+
  int i;
+
  for (i=0; i < LUA_NUMTAGS; i++)
+
    markobjectN(g, g->mt[i]);
+
}
+

+

+
/*
+
** mark all objects in list of being-finalized
+
*/
+
static void markbeingfnz (global_State *g) {
+
  GCObject *o;
+
  for (o = g->tobefnz; o != NULL; o = o->next)
+
    markobject(g, o);
+
}
+

+

+
/*
+
** Mark all values stored in marked open upvalues from non-marked threads.
+
** (Values from marked threads were already marked when traversing the
+
** thread.) Remove from the list threads that no longer have upvalues and
+
** not-marked threads.
+
*/
+
static void remarkupvals (global_State *g) {
+
  lua_State *thread;
+
  lua_State **p = &g->twups;
+
  while ((thread = *p) != NULL) {
+
    lua_assert(!isblack(thread));  /* threads are never black */
+
    if (isgray(thread) && thread->openupval != NULL)
+
      p = &thread->twups;  /* keep marked thread with upvalues in the list */
+
    else {  /* thread is not marked or without upvalues */
+
      UpVal *uv;
+
      *p = thread->twups;  /* remove thread from the list */
+
      thread->twups = thread;  /* mark that it is out of list */
+
      for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) {
+
        if (uv->u.open.touched) {
+
          markvalue(g, uv->v);  /* remark upvalue's value */
+
          uv->u.open.touched = 0;
+
        }
+
      }
+
    }
+
  }
+
}
+

+

+
/*
+
** mark root set and reset all gray lists, to start a new collection
+
*/
+
static void restartcollection (global_State *g) {
+
  g->gray = g->grayagain = NULL;
+
  g->weak = g->allweak = g->ephemeron = NULL;
+
  markobject(g, g->mainthread);
+
  markvalue(g, &g->l_registry);
+
  markmt(g);
+
  markbeingfnz(g);  /* mark any finalizing object left from previous cycle */
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** Traverse functions
+
** =======================================================
+
*/
+

+
/*
+
** Traverse a table with weak values and link it to proper list. During
+
** propagate phase, keep it in 'grayagain' list, to be revisited in the
+
** atomic phase. In the atomic phase, if table has any white value,
+
** put it in 'weak' list, to be cleared.
+
*/
+
static void traverseweakvalue (global_State *g, Table *h) {
+
  Node *n, *limit = gnodelast(h);
+
  /* if there is array part, assume it may have white values (it is not
+
     worth traversing it now just to check) */
+
  int hasclears = (h->sizearray > 0);
+
  for (n = gnode(h, 0); n < limit; n++) {  /* traverse hash part */
+
    checkdeadkey(n);
+
    if (ttisnil(gval(n)))  /* entry is empty? */
+
      removeentry(n);  /* remove it */
+
    else {
+
      lua_assert(!ttisnil(gkey(n)));
+
      markvalue(g, gkey(n));  /* mark key */
+
      if (!hasclears && iscleared(g, gval(n)))  /* is there a white value? */
+
        hasclears = 1;  /* table will have to be cleared */
+
    }
+
  }
+
  if (g->gcstate == GCSpropagate)
+
    linkgclist(h, g->grayagain);  /* must retraverse it in atomic phase */
+
  else if (hasclears)
+
    linkgclist(h, g->weak);  /* has to be cleared later */
+
}
+

+

+
/*
+
** Traverse an ephemeron table and link it to proper list. Returns true
+
** iff any object was marked during this traversal (which implies that
+
** convergence has to continue). During propagation phase, keep table
+
** in 'grayagain' list, to be visited again in the atomic phase. In
+
** the atomic phase, if table has any white->white entry, it has to
+
** be revisited during ephemeron convergence (as that key may turn
+
** black). Otherwise, if it has any white key, table has to be cleared
+
** (in the atomic phase).
+
*/
+
static int traverseephemeron (global_State *g, Table *h) {
+
  int marked = 0;  /* true if an object is marked in this traversal */
+
  int hasclears = 0;  /* true if table has white keys */
+
  int hasww = 0;  /* true if table has entry "white-key -> white-value" */
+
  Node *n, *limit = gnodelast(h);
+
  unsigned int i;
+
  /* traverse array part */
+
  for (i = 0; i < h->sizearray; i++) {
+
    if (valiswhite(&h->array[i])) {
+
      marked = 1;
+
      reallymarkobject(g, gcvalue(&h->array[i]));
+
    }
+
  }
+
  /* traverse hash part */
+
  for (n = gnode(h, 0); n < limit; n++) {
+
    checkdeadkey(n);
+
    if (ttisnil(gval(n)))  /* entry is empty? */
+
      removeentry(n);  /* remove it */
+
    else if (iscleared(g, gkey(n))) {  /* key is not marked (yet)? */
+
      hasclears = 1;  /* table must be cleared */
+
      if (valiswhite(gval(n)))  /* value not marked yet? */
+
        hasww = 1;  /* white-white entry */
+
    }
+
    else if (valiswhite(gval(n))) {  /* value not marked yet? */
+
      marked = 1;
+
      reallymarkobject(g, gcvalue(gval(n)));  /* mark it now */
+
    }
+
  }
+
  /* link table into proper list */
+
  if (g->gcstate == GCSpropagate)
+
    linkgclist(h, g->grayagain);  /* must retraverse it in atomic phase */
+
  else if (hasww)  /* table has white->white entries? */
+
    linkgclist(h, g->ephemeron);  /* have to propagate again */
+
  else if (hasclears)  /* table has white keys? */
+
    linkgclist(h, g->allweak);  /* may have to clean white keys */
+
  return marked;
+
}
+

+

+
static void traversestrongtable (global_State *g, Table *h) {
+
  Node *n, *limit = gnodelast(h);
+
  unsigned int i;
+
  for (i = 0; i < h->sizearray; i++)  /* traverse array part */
+
    markvalue(g, &h->array[i]);
+
  for (n = gnode(h, 0); n < limit; n++) {  /* traverse hash part */
+
    checkdeadkey(n);
+
    if (ttisnil(gval(n)))  /* entry is empty? */
+
      removeentry(n);  /* remove it */
+
    else {
+
      lua_assert(!ttisnil(gkey(n)));
+
      markvalue(g, gkey(n));  /* mark key */
+
      markvalue(g, gval(n));  /* mark value */
+
    }
+
  }
+
}
+

+

+
static lu_mem traversetable (global_State *g, Table *h) {
+
  const char *weakkey, *weakvalue;
+
  const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
+
  markobjectN(g, h->metatable);
+
  if (mode && ttisstring(mode) &&  /* is there a weak mode? */
+
      ((weakkey = strchr(svalue(mode), 'k')),
+
       (weakvalue = strchr(svalue(mode), 'v')),
+
       (weakkey || weakvalue))) {  /* is really weak? */
+
    black2gray(h);  /* keep table gray */
+
    if (!weakkey)  /* strong keys? */
+
      traverseweakvalue(g, h);
+
    else if (!weakvalue)  /* strong values? */
+
      traverseephemeron(g, h);
+
    else  /* all weak */
+
      linkgclist(h, g->allweak);  /* nothing to traverse now */
+
  }
+
  else  /* not weak */
+
    traversestrongtable(g, h);
+
  return sizeof(Table) + sizeof(TValue) * h->sizearray +
+
                         sizeof(Node) * cast(size_t, allocsizenode(h));
+
}
+

+

+
/*
+
** Traverse a prototype. (While a prototype is being build, its
+
** arrays can be larger than needed; the extra slots are filled with
+
** NULL, so the use of 'markobjectN')
+
*/
+
static int traverseproto (global_State *g, Proto *f) {
+
  int i;
+
  if (f->cache && iswhite(f->cache))
+
    f->cache = NULL;  /* allow cache to be collected */
+
  markobjectN(g, f->source);
+
  for (i = 0; i < f->sizek; i++)  /* mark literals */
+
    markvalue(g, &f->k[i]);
+
  for (i = 0; i < f->sizeupvalues; i++)  /* mark upvalue names */
+
    markobjectN(g, f->upvalues[i].name);
+
  for (i = 0; i < f->sizep; i++)  /* mark nested protos */
+
    markobjectN(g, f->p[i]);
+
  for (i = 0; i < f->sizelocvars; i++)  /* mark local-variable names */
+
    markobjectN(g, f->locvars[i].varname);
+
  return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
+
                         sizeof(Proto *) * f->sizep +
+
                         sizeof(TValue) * f->sizek +
+
                         sizeof(int) * f->sizelineinfo +
+
                         sizeof(LocVar) * f->sizelocvars +
+
                         sizeof(Upvaldesc) * f->sizeupvalues;
+
}
+

+

+
static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
+
  int i;
+
  for (i = 0; i < cl->nupvalues; i++)  /* mark its upvalues */
+
    markvalue(g, &cl->upvalue[i]);
+
  return sizeCclosure(cl->nupvalues);
+
}
+

+
/*
+
** open upvalues point to values in a thread, so those values should
+
** be marked when the thread is traversed except in the atomic phase
+
** (because then the value cannot be changed by the thread and the
+
** thread may not be traversed again)
+
*/
+
static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
+
  int i;
+
  markobjectN(g, cl->p);  /* mark its prototype */
+
  for (i = 0; i < cl->nupvalues; i++) {  /* mark its upvalues */
+
    UpVal *uv = cl->upvals[i];
+
    if (uv != NULL) {
+
      if (upisopen(uv) && g->gcstate != GCSinsideatomic)
+
        uv->u.open.touched = 1;  /* can be marked in 'remarkupvals' */
+
      else
+
        markvalue(g, uv->v);
+
    }
+
  }
+
  return sizeLclosure(cl->nupvalues);
+
}
+

+

+
static lu_mem traversethread (global_State *g, lua_State *th) {
+
  StkId o = th->stack;
+
  if (o == NULL)
+
    return 1;  /* stack not completely built yet */
+
  lua_assert(g->gcstate == GCSinsideatomic ||
+
             th->openupval == NULL || isintwups(th));
+
  for (; o < th->top; o++)  /* mark live elements in the stack */
+
    markvalue(g, o);
+
  if (g->gcstate == GCSinsideatomic) {  /* final traversal? */
+
    StkId lim = th->stack + th->stacksize;  /* real end of stack */
+
    for (; o < lim; o++)  /* clear not-marked stack slice */
+
      setnilvalue(o);
+
    /* 'remarkupvals' may have removed thread from 'twups' list */
+
    if (!isintwups(th) && th->openupval != NULL) {
+
      th->twups = g->twups;  /* link it back to the list */
+
      g->twups = th;
+
    }
+
  }
+
  else if (g->gckind != KGC_EMERGENCY)
+
    luaD_shrinkstack(th); /* do not change stack in emergency cycle */
+
  return (sizeof(lua_State) + sizeof(TValue) * th->stacksize +
+
          sizeof(CallInfo) * th->nci);
+
}
+

+

+
/*
+
** traverse one gray object, turning it to black (except for threads,
+
** which are always gray).
+
*/
+
static void propagatemark (global_State *g) {
+
  lu_mem size;
+
  GCObject *o = g->gray;
+
  lua_assert(isgray(o));
+
  gray2black(o);
+
  switch (o->tt) {
+
    case LUA_TTABLE: {
+
      Table *h = gco2t(o);
+
      g->gray = h->gclist;  /* remove from 'gray' list */
+
      size = traversetable(g, h);
+
      break;
+
    }
+
    case LUA_TLCL: {
+
      LClosure *cl = gco2lcl(o);
+
      g->gray = cl->gclist;  /* remove from 'gray' list */
+
      size = traverseLclosure(g, cl);
+
      break;
+
    }
+
    case LUA_TCCL: {
+
      CClosure *cl = gco2ccl(o);
+
      g->gray = cl->gclist;  /* remove from 'gray' list */
+
      size = traverseCclosure(g, cl);
+
      break;
+
    }
+
    case LUA_TTHREAD: {
+
      lua_State *th = gco2th(o);
+
      g->gray = th->gclist;  /* remove from 'gray' list */
+
      linkgclist(th, g->grayagain);  /* insert into 'grayagain' list */
+
      black2gray(o);
+
      size = traversethread(g, th);
+
      break;
+
    }
+
    case LUA_TPROTO: {
+
      Proto *p = gco2p(o);
+
      g->gray = p->gclist;  /* remove from 'gray' list */
+
      size = traverseproto(g, p);
+
      break;
+
    }
+
    default: lua_assert(0); return;
+
  }
+
  g->GCmemtrav += size;
+
}
+

+

+
static void propagateall (global_State *g) {
+
  while (g->gray) propagatemark(g);
+
}
+

+

+
static void convergeephemerons (global_State *g) {
+
  int changed;
+
  do {
+
    GCObject *w;
+
    GCObject *next = g->ephemeron;  /* get ephemeron list */
+
    g->ephemeron = NULL;  /* tables may return to this list when traversed */
+
    changed = 0;
+
    while ((w = next) != NULL) {
+
      next = gco2t(w)->gclist;
+
      if (traverseephemeron(g, gco2t(w))) {  /* traverse marked some value? */
+
        propagateall(g);  /* propagate changes */
+
        changed = 1;  /* will have to revisit all ephemeron tables */
+
      }
+
    }
+
  } while (changed);
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** Sweep Functions
+
** =======================================================
+
*/
+

+

+
/*
+
** clear entries with unmarked keys from all weaktables in list 'l' up
+
** to element 'f'
+
*/
+
static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
+
  for (; l != f; l = gco2t(l)->gclist) {
+
    Table *h = gco2t(l);
+
    Node *n, *limit = gnodelast(h);
+
    for (n = gnode(h, 0); n < limit; n++) {
+
      if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
+
        setnilvalue(gval(n));  /* remove value ... */
+
      }
+
      if (ttisnil(gval(n)))  /* is entry empty? */
+
        removeentry(n);  /* remove entry from table */
+
    }
+
  }
+
}
+

+

+
/*
+
** clear entries with unmarked values from all weaktables in list 'l' up
+
** to element 'f'
+
*/
+
static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
+
  for (; l != f; l = gco2t(l)->gclist) {
+
    Table *h = gco2t(l);
+
    Node *n, *limit = gnodelast(h);
+
    unsigned int i;
+
    for (i = 0; i < h->sizearray; i++) {
+
      TValue *o = &h->array[i];
+
      if (iscleared(g, o))  /* value was collected? */
+
        setnilvalue(o);  /* remove value */
+
    }
+
    for (n = gnode(h, 0); n < limit; n++) {
+
      if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
+
        setnilvalue(gval(n));  /* remove value ... */
+
        removeentry(n);  /* and remove entry from table */
+
      }
+
    }
+
  }
+
}
+

+

+
void luaC_upvdeccount (lua_State *L, UpVal *uv) {
+
  lua_assert(uv->refcount > 0);
+
  uv->refcount--;
+
  if (uv->refcount == 0 && !upisopen(uv))
+
    luaM_free(L, uv);
+
}
+

+

+
static void freeLclosure (lua_State *L, LClosure *cl) {
+
  int i;
+
  for (i = 0; i < cl->nupvalues; i++) {
+
    UpVal *uv = cl->upvals[i];
+
    if (uv)
+
      luaC_upvdeccount(L, uv);
+
  }
+
  luaM_freemem(L, cl, sizeLclosure(cl->nupvalues));
+
}
+

+

+
static void freeobj (lua_State *L, GCObject *o) {
+
  switch (o->tt) {
+
    case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
+
    case LUA_TLCL: {
+
      freeLclosure(L, gco2lcl(o));
+
      break;
+
    }
+
    case LUA_TCCL: {
+
      luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
+
      break;
+
    }
+
    case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
+
    case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
+
    case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
+
    case LUA_TSHRSTR:
+
      luaS_remove(L, gco2ts(o));  /* remove it from hash table */
+
      luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
+
      break;
+
    case LUA_TLNGSTR: {
+
      luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
+
      break;
+
    }
+
    default: lua_assert(0);
+
  }
+
}
+

+

+
#define sweepwholelist(L,p)	sweeplist(L,p,MAX_LUMEM)
+
static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
+

+

+
/*
+
** sweep at most 'count' elements from a list of GCObjects erasing dead
+
** objects, where a dead object is one marked with the old (non current)
+
** white; change all non-dead objects back to white, preparing for next
+
** collection cycle. Return where to continue the traversal or NULL if
+
** list is finished.
+
*/
+
static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
+
  global_State *g = G(L);
+
  int ow = otherwhite(g);
+
  int white = luaC_white(g);  /* current white */
+
  while (*p != NULL && count-- > 0) {
+
    GCObject *curr = *p;
+
    int marked = curr->marked;
+
    if (isdeadm(ow, marked)) {  /* is 'curr' dead? */
+
      *p = curr->next;  /* remove 'curr' from list */
+
      freeobj(L, curr);  /* erase 'curr' */
+
    }
+
    else {  /* change mark to 'white' */
+
      curr->marked = cast_byte((marked & maskcolors) | white);
+
      p = &curr->next;  /* go to next element */
+
    }
+
  }
+
  return (*p == NULL) ? NULL : p;
+
}
+

+

+
/*
+
** sweep a list until a live object (or end of list)
+
*/
+
static GCObject **sweeptolive (lua_State *L, GCObject **p) {
+
  GCObject **old = p;
+
  do {
+
    p = sweeplist(L, p, 1);
+
  } while (p == old);
+
  return p;
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** Finalization
+
** =======================================================
+
*/
+

+
/*
+
** If possible, shrink string table
+
*/
+
static void checkSizes (lua_State *L, global_State *g) {
+
  if (g->gckind != KGC_EMERGENCY) {
+
    l_mem olddebt = g->GCdebt;
+
    if (g->strt.nuse < g->strt.size / 4)  /* string table too big? */
+
      luaS_resize(L, g->strt.size / 2);  /* shrink it a little */
+
    g->GCestimate += g->GCdebt - olddebt;  /* update estimate */
+
  }
+
}
+

+

+
static GCObject *udata2finalize (global_State *g) {
+
  GCObject *o = g->tobefnz;  /* get first element */
+
  lua_assert(tofinalize(o));
+
  g->tobefnz = o->next;  /* remove it from 'tobefnz' list */
+
  o->next = g->allgc;  /* return it to 'allgc' list */
+
  g->allgc = o;
+
  resetbit(o->marked, FINALIZEDBIT);  /* object is "normal" again */
+
  if (issweepphase(g))
+
    makewhite(g, o);  /* "sweep" object */
+
  return o;
+
}
+

+

+
static void dothecall (lua_State *L, void *ud) {
+
  UNUSED(ud);
+
  luaD_callnoyield(L, L->top - 2, 0);
+
}
+

+

+
static void GCTM (lua_State *L, int propagateerrors) {
+
  global_State *g = G(L);
+
  const TValue *tm;
+
  TValue v;
+
  setgcovalue(L, &v, udata2finalize(g));
+
  tm = luaT_gettmbyobj(L, &v, TM_GC);
+
  if (tm != NULL && ttisfunction(tm)) {  /* is there a finalizer? */
+
    int status;
+
    lu_byte oldah = L->allowhook;
+
    int running  = g->gcrunning;
+
    L->allowhook = 0;  /* stop debug hooks during GC metamethod */
+
    g->gcrunning = 0;  /* avoid GC steps */
+
    setobj2s(L, L->top, tm);  /* push finalizer... */
+
    setobj2s(L, L->top + 1, &v);  /* ... and its argument */
+
    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);
+
    L->ci->callstatus &= ~CIST_FIN;  /* not running a finalizer anymore */
+
    L->allowhook = oldah;  /* restore hooks */
+
    g->gcrunning = running;  /* restore state */
+
    if (status != LUA_OK && propagateerrors) {  /* error while running __gc? */
+
      if (status == LUA_ERRRUN) {  /* is there an error object? */
+
        const char *msg = (ttisstring(L->top - 1))
+
                            ? svalue(L->top - 1)
+
                            : "no message";
+
        luaO_pushfstring(L, "error in __gc metamethod (%s)", msg);
+
        status = LUA_ERRGCMM;  /* error in __gc metamethod */
+
      }
+
      luaD_throw(L, status);  /* re-throw error */
+
    }
+
  }
+
}
+

+

+
/*
+
** call a few (up to 'g->gcfinnum') finalizers
+
*/
+
static int runafewfinalizers (lua_State *L) {
+
  global_State *g = G(L);
+
  unsigned int i;
+
  lua_assert(!g->tobefnz || g->gcfinnum > 0);
+
  for (i = 0; g->tobefnz && i < g->gcfinnum; i++)
+
    GCTM(L, 1);  /* call one finalizer */
+
  g->gcfinnum = (!g->tobefnz) ? 0  /* nothing more to finalize? */
+
                    : g->gcfinnum * 2;  /* else call a few more next time */
+
  return i;
+
}
+

+

+
/*
+
** call all pending finalizers
+
*/
+
static void callallpendingfinalizers (lua_State *L) {
+
  global_State *g = G(L);
+
  while (g->tobefnz)
+
    GCTM(L, 0);
+
}
+

+

+
/*
+
** find last 'next' field in list 'p' list (to add elements in its end)
+
*/
+
static GCObject **findlast (GCObject **p) {
+
  while (*p != NULL)
+
    p = &(*p)->next;
+
  return p;
+
}
+

+

+
/*
+
** move all unreachable objects (or 'all' objects) that need
+
** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
+
*/
+
static void separatetobefnz (global_State *g, int all) {
+
  GCObject *curr;
+
  GCObject **p = &g->finobj;
+
  GCObject **lastnext = findlast(&g->tobefnz);
+
  while ((curr = *p) != NULL) {  /* traverse all finalizable objects */
+
    lua_assert(tofinalize(curr));
+
    if (!(iswhite(curr) || all))  /* not being collected? */
+
      p = &curr->next;  /* don't bother with it */
+
    else {
+
      *p = curr->next;  /* remove 'curr' from 'finobj' list */
+
      curr->next = *lastnext;  /* link at the end of 'tobefnz' list */
+
      *lastnext = curr;
+
      lastnext = &curr->next;
+
    }
+
  }
+
}
+

+

+
/*
+
** if object 'o' has a finalizer, remove it from 'allgc' list (must
+
** search the list to find it) and link it in 'finobj' list.
+
*/
+
void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
+
  global_State *g = G(L);
+
  if (tofinalize(o) ||                 /* obj. is already marked... */
+
      gfasttm(g, mt, TM_GC) == NULL)   /* or has no finalizer? */
+
    return;  /* nothing to be done */
+
  else {  /* move 'o' to 'finobj' list */
+
    GCObject **p;
+
    if (issweepphase(g)) {
+
      makewhite(g, o);  /* "sweep" object 'o' */
+
      if (g->sweepgc == &o->next)  /* should not remove 'sweepgc' object */
+
        g->sweepgc = sweeptolive(L, g->sweepgc);  /* change 'sweepgc' */
+
    }
+
    /* search for pointer pointing to 'o' */
+
    for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
+
    *p = o->next;  /* remove 'o' from 'allgc' list */
+
    o->next = g->finobj;  /* link it in 'finobj' list */
+
    g->finobj = o;
+
    l_setbit(o->marked, FINALIZEDBIT);  /* mark it as such */
+
  }
+
}
+

+
/* }====================================================== */
+

+

+

+
/*
+
** {======================================================
+
** GC control
+
** =======================================================
+
*/
+

+

+
/*
+
** Set a reasonable "time" to wait before starting a new GC cycle; cycle
+
** will start when memory use hits threshold. (Division by 'estimate'
+
** should be OK: it cannot be zero (because Lua cannot even start with
+
** less than PAUSEADJ bytes).
+
*/
+
static void setpause (global_State *g) {
+
  l_mem threshold, debt;
+
  l_mem estimate = g->GCestimate / PAUSEADJ;  /* adjust 'estimate' */
+
  lua_assert(estimate > 0);
+
  threshold = (g->gcpause < MAX_LMEM / estimate)  /* overflow? */
+
            ? estimate * g->gcpause  /* no overflow */
+
            : MAX_LMEM;  /* overflow; truncate to maximum */
+
  debt = gettotalbytes(g) - threshold;
+
  luaE_setdebt(g, debt);
+
}
+

+

+
/*
+
** Enter first sweep phase.
+
** The call to 'sweeplist' tries to make pointer point to an object
+
** inside the list (instead of to the header), so that the real sweep do
+
** not need to skip objects created between "now" and the start of the
+
** real sweep.
+
*/
+
static void entersweep (lua_State *L) {
+
  global_State *g = G(L);
+
  g->gcstate = GCSswpallgc;
+
  lua_assert(g->sweepgc == NULL);
+
  g->sweepgc = sweeplist(L, &g->allgc, 1);
+
}
+

+

+
void luaC_freeallobjects (lua_State *L) {
+
  global_State *g = G(L);
+
  separatetobefnz(g, 1);  /* separate all objects with finalizers */
+
  lua_assert(g->finobj == NULL);
+
  callallpendingfinalizers(L);
+
  lua_assert(g->tobefnz == NULL);
+
  g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
+
  g->gckind = KGC_NORMAL;
+
  sweepwholelist(L, &g->finobj);
+
  sweepwholelist(L, &g->allgc);
+
  sweepwholelist(L, &g->fixedgc);  /* collect fixed objects */
+
  lua_assert(g->strt.nuse == 0);
+
}
+

+

+
static l_mem atomic (lua_State *L) {
+
  global_State *g = G(L);
+
  l_mem work;
+
  GCObject *origweak, *origall;
+
  GCObject *grayagain = g->grayagain;  /* save original list */
+
  lua_assert(g->ephemeron == NULL && g->weak == NULL);
+
  lua_assert(!iswhite(g->mainthread));
+
  g->gcstate = GCSinsideatomic;
+
  g->GCmemtrav = 0;  /* start counting work */
+
  markobject(g, L);  /* mark running thread */
+
  /* registry and global metatables may be changed by API */
+
  markvalue(g, &g->l_registry);
+
  markmt(g);  /* mark global metatables */
+
  /* remark occasional upvalues of (maybe) dead threads */
+
  remarkupvals(g);
+
  propagateall(g);  /* propagate changes */
+
  work = g->GCmemtrav;  /* stop counting (do not recount 'grayagain') */
+
  g->gray = grayagain;
+
  propagateall(g);  /* traverse 'grayagain' list */
+
  g->GCmemtrav = 0;  /* restart counting */
+
  convergeephemerons(g);
+
  /* at this point, all strongly accessible objects are marked. */
+
  /* Clear values from weak tables, before checking finalizers */
+
  clearvalues(g, g->weak, NULL);
+
  clearvalues(g, g->allweak, NULL);
+
  origweak = g->weak; origall = g->allweak;
+
  work += g->GCmemtrav;  /* stop counting (objects being finalized) */
+
  separatetobefnz(g, 0);  /* separate objects to be finalized */
+
  g->gcfinnum = 1;  /* there may be objects to be finalized */
+
  markbeingfnz(g);  /* mark objects that will be finalized */
+
  propagateall(g);  /* remark, to propagate 'resurrection' */
+
  g->GCmemtrav = 0;  /* restart counting */
+
  convergeephemerons(g);
+
  /* at this point, all resurrected objects are marked. */
+
  /* remove dead objects from weak tables */
+
  clearkeys(g, g->ephemeron, NULL);  /* clear keys from all ephemeron tables */
+
  clearkeys(g, g->allweak, NULL);  /* clear keys from all 'allweak' tables */
+
  /* clear values from resurrected weak tables */
+
  clearvalues(g, g->weak, origweak);
+
  clearvalues(g, g->allweak, origall);
+
  luaS_clearcache(g);
+
  g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
+
  work += g->GCmemtrav;  /* complete counting */
+
  return work;  /* estimate of memory marked by 'atomic' */
+
}
+

+

+
static lu_mem sweepstep (lua_State *L, global_State *g,
+
                         int nextstate, GCObject **nextlist) {
+
  if (g->sweepgc) {
+
    l_mem olddebt = g->GCdebt;
+
    g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
+
    g->GCestimate += g->GCdebt - olddebt;  /* update estimate */
+
    if (g->sweepgc)  /* is there still something to sweep? */
+
      return (GCSWEEPMAX * GCSWEEPCOST);
+
  }
+
  /* else enter next state */
+
  g->gcstate = nextstate;
+
  g->sweepgc = nextlist;
+
  return 0;
+
}
+

+

+
static lu_mem singlestep (lua_State *L) {
+
  global_State *g = G(L);
+
  switch (g->gcstate) {
+
    case GCSpause: {
+
      g->GCmemtrav = g->strt.size * sizeof(GCObject*);
+
      restartcollection(g);
+
      g->gcstate = GCSpropagate;
+
      return g->GCmemtrav;
+
    }
+
    case GCSpropagate: {
+
      g->GCmemtrav = 0;
+
      lua_assert(g->gray);
+
      propagatemark(g);
+
       if (g->gray == NULL)  /* no more gray objects? */
+
        g->gcstate = GCSatomic;  /* finish propagate phase */
+
      return g->GCmemtrav;  /* memory traversed in this step */
+
    }
+
    case GCSatomic: {
+
      lu_mem work;
+
      propagateall(g);  /* make sure gray list is empty */
+
      work = atomic(L);  /* work is what was traversed by 'atomic' */
+
      entersweep(L);
+
      g->GCestimate = gettotalbytes(g);  /* first estimate */;
+
      return work;
+
    }
+
    case GCSswpallgc: {  /* sweep "regular" objects */
+
      return sweepstep(L, g, GCSswpfinobj, &g->finobj);
+
    }
+
    case GCSswpfinobj: {  /* sweep objects with finalizers */
+
      return sweepstep(L, g, GCSswptobefnz, &g->tobefnz);
+
    }
+
    case GCSswptobefnz: {  /* sweep objects to be finalized */
+
      return sweepstep(L, g, GCSswpend, NULL);
+
    }
+
    case GCSswpend: {  /* finish sweeps */
+
      makewhite(g, g->mainthread);  /* sweep main thread */
+
      checkSizes(L, g);
+
      g->gcstate = GCScallfin;
+
      return 0;
+
    }
+
    case GCScallfin: {  /* call remaining finalizers */
+
      if (g->tobefnz && g->gckind != KGC_EMERGENCY) {
+
        int n = runafewfinalizers(L);
+
        return (n * GCFINALIZECOST);
+
      }
+
      else {  /* emergency mode or no more finalizers */
+
        g->gcstate = GCSpause;  /* finish collection */
+
        return 0;
+
      }
+
    }
+
    default: lua_assert(0); return 0;
+
  }
+
}
+

+

+
/*
+
** advances the garbage collector until it reaches a state allowed
+
** by 'statemask'
+
*/
+
void luaC_runtilstate (lua_State *L, int statesmask) {
+
  global_State *g = G(L);
+
  while (!testbit(statesmask, g->gcstate))
+
    singlestep(L);
+
}
+

+

+
/*
+
** get GC debt and convert it from Kb to 'work units' (avoid zero debt
+
** and overflows)
+
*/
+
static l_mem getdebt (global_State *g) {
+
  l_mem debt = g->GCdebt;
+
  int stepmul = g->gcstepmul;
+
  if (debt <= 0) return 0;  /* minimal debt */
+
  else {
+
    debt = (debt / STEPMULADJ) + 1;
+
    debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
+
    return debt;
+
  }
+
}
+

+
/*
+
** performs a basic GC step when collector is running
+
*/
+
void luaC_step (lua_State *L) {
+
  global_State *g = G(L);
+
  l_mem debt = getdebt(g);  /* GC deficit (be paid now) */
+
  if (!g->gcrunning) {  /* not running? */
+
    luaE_setdebt(g, -GCSTEPSIZE * 10);  /* avoid being called too often */
+
    return;
+
  }
+
  do {  /* repeat until pause or enough "credit" (negative debt) */
+
    lu_mem work = singlestep(L);  /* perform one single step */
+
    debt -= work;
+
  } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
+
  if (g->gcstate == GCSpause)
+
    setpause(g);  /* pause until next cycle */
+
  else {
+
    debt = (debt / g->gcstepmul) * STEPMULADJ;  /* convert 'work units' to Kb */
+
    luaE_setdebt(g, debt);
+
    runafewfinalizers(L);
+
  }
+
}
+

+

+
/*
+
** Performs a full GC cycle; if 'isemergency', set a flag to avoid
+
** some operations which could change the interpreter state in some
+
** unexpected ways (running finalizers and shrinking some structures).
+
** Before running the collection, check 'keepinvariant'; if it is true,
+
** there may be some objects marked as black, so the collector has
+
** to sweep all objects to turn them back to white (as white has not
+
** changed, nothing will be collected).
+
*/
+
void luaC_fullgc (lua_State *L, int isemergency) {
+
  global_State *g = G(L);
+
  lua_assert(g->gckind == KGC_NORMAL);
+
  if (isemergency) g->gckind = KGC_EMERGENCY;  /* set flag */
+
  if (keepinvariant(g)) {  /* black objects? */
+
    entersweep(L); /* sweep everything to turn them back to white */
+
  }
+
  /* finish any pending sweep phase to start a new cycle */
+
  luaC_runtilstate(L, bitmask(GCSpause));
+
  luaC_runtilstate(L, ~bitmask(GCSpause));  /* start new collection */
+
  luaC_runtilstate(L, bitmask(GCScallfin));  /* run up to finalizers */
+
  /* estimate must be correct after a full GC cycle */
+
  lua_assert(g->GCestimate == gettotalbytes(g));
+
  luaC_runtilstate(L, bitmask(GCSpause));  /* finish collection */
+
  g->gckind = KGC_NORMAL;
+
  setpause(g);
+
}
+

+
/* }====================================================== */
+

+

added external/lua/src/lgc.h
@@ -0,0 +1,147 @@
+
/*
+
** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $
+
** Garbage Collector
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lgc_h
+
#define lgc_h
+

+

+
#include "lobject.h"
+
#include "lstate.h"
+

+
/*
+
** Collectable objects may have one of three colors: white, which
+
** means the object is not marked; gray, which means the
+
** object is marked, but its references may be not marked; and
+
** black, which means that the object and all its references are marked.
+
** The main invariant of the garbage collector, while marking objects,
+
** is that a black object can never point to a white one. Moreover,
+
** any gray object must be in a "gray list" (gray, grayagain, weak,
+
** allweak, ephemeron) so that it can be visited again before finishing
+
** the collection cycle. These lists have no meaning when the invariant
+
** is not being enforced (e.g., sweep phase).
+
*/
+

+

+

+
/* how much to allocate before next GC step */
+
#if !defined(GCSTEPSIZE)
+
/* ~100 small strings */
+
#define GCSTEPSIZE	(cast_int(100 * sizeof(TString)))
+
#endif
+

+

+
/*
+
** Possible states of the Garbage Collector
+
*/
+
#define GCSpropagate	0
+
#define GCSatomic	1
+
#define GCSswpallgc	2
+
#define GCSswpfinobj	3
+
#define GCSswptobefnz	4
+
#define GCSswpend	5
+
#define GCScallfin	6
+
#define GCSpause	7
+

+

+
#define issweepphase(g)  \
+
	(GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
+

+

+
/*
+
** macro to tell when main invariant (white objects cannot point to black
+
** ones) must be kept. During a collection, the sweep
+
** phase may break the invariant, as objects turned white may point to
+
** still-black objects. The invariant is restored when sweep ends and
+
** all objects are white again.
+
*/
+

+
#define keepinvariant(g)	((g)->gcstate <= GCSatomic)
+

+

+
/*
+
** some useful bit tricks
+
*/
+
#define resetbits(x,m)		((x) &= cast(lu_byte, ~(m)))
+
#define setbits(x,m)		((x) |= (m))
+
#define testbits(x,m)		((x) & (m))
+
#define bitmask(b)		(1<<(b))
+
#define bit2mask(b1,b2)		(bitmask(b1) | bitmask(b2))
+
#define l_setbit(x,b)		setbits(x, bitmask(b))
+
#define resetbit(x,b)		resetbits(x, bitmask(b))
+
#define testbit(x,b)		testbits(x, bitmask(b))
+

+

+
/* Layout for bit use in 'marked' field: */
+
#define WHITE0BIT	0  /* object is white (type 0) */
+
#define WHITE1BIT	1  /* object is white (type 1) */
+
#define BLACKBIT	2  /* object is black */
+
#define FINALIZEDBIT	3  /* object has been marked for finalization */
+
/* bit 7 is currently used by tests (luaL_checkmemory) */
+

+
#define WHITEBITS	bit2mask(WHITE0BIT, WHITE1BIT)
+

+

+
#define iswhite(x)      testbits((x)->marked, WHITEBITS)
+
#define isblack(x)      testbit((x)->marked, BLACKBIT)
+
#define isgray(x)  /* neither white nor black */  \
+
	(!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
+

+
#define tofinalize(x)	testbit((x)->marked, FINALIZEDBIT)
+

+
#define otherwhite(g)	((g)->currentwhite ^ WHITEBITS)
+
#define isdeadm(ow,m)	(!(((m) ^ WHITEBITS) & (ow)))
+
#define isdead(g,v)	isdeadm(otherwhite(g), (v)->marked)
+

+
#define changewhite(x)	((x)->marked ^= WHITEBITS)
+
#define gray2black(x)	l_setbit((x)->marked, BLACKBIT)
+

+
#define luaC_white(g)	cast(lu_byte, (g)->currentwhite & WHITEBITS)
+

+

+
/*
+
** Does one step of collection when debt becomes positive. 'pre'/'pos'
+
** allows some adjustments to be done only when needed. macro
+
** 'condchangemem' is used only for heavy tests (forcing a full
+
** GC cycle on every opportunity)
+
*/
+
#define luaC_condGC(L,pre,pos) \
+
	{ if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \
+
	  condchangemem(L,pre,pos); }
+

+
/* more often than not, 'pre'/'pos' are empty */
+
#define luaC_checkGC(L)		luaC_condGC(L,(void)0,(void)0)
+

+

+
#define luaC_barrier(L,p,v) (  \
+
	(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ?  \
+
	luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0))
+

+
#define luaC_barrierback(L,p,v) (  \
+
	(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
+
	luaC_barrierback_(L,p) : cast_void(0))
+

+
#define luaC_objbarrier(L,p,o) (  \
+
	(isblack(p) && iswhite(o)) ? \
+
	luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
+

+
#define luaC_upvalbarrier(L,uv) ( \
+
	(iscollectable((uv)->v) && !upisopen(uv)) ? \
+
         luaC_upvalbarrier_(L,uv) : cast_void(0))
+

+
LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
+
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
+
LUAI_FUNC void luaC_step (lua_State *L);
+
LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
+
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
+
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
+
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
+
LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o);
+
LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv);
+
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
+
LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
+

+

+
#endif
added external/lua/src/linit.c
@@ -0,0 +1,68 @@
+
/*
+
** $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
+
** See Copyright Notice in lua.h
+
*/
+

+

+
#define linit_c
+
#define LUA_LIB
+

+
/*
+
** If you embed Lua in your program and need to open the standard
+
** libraries, call luaL_openlibs in your program. If you need a
+
** different set of libraries, copy this file to your project and edit
+
** it to suit your needs.
+
**
+
** You can also *preload* libraries, so that a later 'require' can
+
** open the library, which is already linked to the application.
+
** For that, do the following code:
+
**
+
**  luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
+
**  lua_pushcfunction(L, luaopen_modname);
+
**  lua_setfield(L, -2, modname);
+
**  lua_pop(L, 1);  // remove PRELOAD table
+
*/
+

+
#include "lprefix.h"
+

+

+
#include <stddef.h>
+

+
#include "lua.h"
+

+
#include "lualib.h"
+
#include "lauxlib.h"
+

+

+
/*
+
** these libs are loaded by lua.c and are readily available to any Lua
+
** program
+
*/
+
static const luaL_Reg loadedlibs[] = {
+
  {"_G", luaopen_base},
+
  {LUA_LOADLIBNAME, luaopen_package},
+
  {LUA_COLIBNAME, luaopen_coroutine},
+
  {LUA_TABLIBNAME, luaopen_table},
+
  {LUA_IOLIBNAME, luaopen_io},
+
  {LUA_OSLIBNAME, luaopen_os},
+
  {LUA_STRLIBNAME, luaopen_string},
+
  {LUA_MATHLIBNAME, luaopen_math},
+
  {LUA_UTF8LIBNAME, luaopen_utf8},
+
  {LUA_DBLIBNAME, luaopen_debug},
+
#if defined(LUA_COMPAT_BITLIB)
+
  {LUA_BITLIBNAME, luaopen_bit32},
+
#endif
+
  {NULL, NULL}
+
};
+

+

+
LUALIB_API void luaL_openlibs (lua_State *L) {
+
  const luaL_Reg *lib;
+
  /* "require" functions from 'loadedlibs' and set results to global table */
+
  for (lib = loadedlibs; lib->func; lib++) {
+
    luaL_requiref(L, lib->name, lib->func, 1);
+
    lua_pop(L, 1);  /* remove lib */
+
  }
+
}
+

added external/lua/src/liolib.c
@@ -0,0 +1,776 @@
+
/*
+
** $Id: liolib.c,v 2.151.1.1 2017/04/19 17:29:57 roberto Exp $
+
** Standard I/O (and system) library
+
** See Copyright Notice in lua.h
+
*/
+

+
#define liolib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <ctype.h>
+
#include <errno.h>
+
#include <locale.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+

+

+
/*
+
** Change this macro to accept other modes for 'fopen' besides
+
** the standard ones.
+
*/
+
#if !defined(l_checkmode)
+

+
/* accepted extensions to 'mode' in 'fopen' */
+
#if !defined(L_MODEEXT)
+
#define L_MODEEXT	"b"
+
#endif
+

+
/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
+
static int l_checkmode (const char *mode) {
+
  return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
+
         (*mode != '+' || (++mode, 1)) &&  /* skip if char is '+' */
+
         (strspn(mode, L_MODEEXT) == strlen(mode)));  /* check extensions */
+
}
+

+
#endif
+

+
/*
+
** {======================================================
+
** l_popen spawns a new process connected to the current
+
** one through the file streams.
+
** =======================================================
+
*/
+

+
#if !defined(l_popen)		/* { */
+

+
#if defined(LUA_USE_POSIX)	/* { */
+

+
#define l_popen(L,c,m)		(fflush(NULL), popen(c,m))
+
#define l_pclose(L,file)	(pclose(file))
+

+
#elif defined(LUA_USE_WINDOWS)	/* }{ */
+

+
#define l_popen(L,c,m)		(_popen(c,m))
+
#define l_pclose(L,file)	(_pclose(file))
+

+
#else				/* }{ */
+

+
/* ISO C definitions */
+
#define l_popen(L,c,m)  \
+
	  ((void)((void)c, m), \
+
	  luaL_error(L, "'popen' not supported"), \
+
	  (FILE*)0)
+
#define l_pclose(L,file)		((void)L, (void)file, -1)
+

+
#endif				/* } */
+

+
#endif				/* } */
+

+
/* }====================================================== */
+

+

+
#if !defined(l_getc)		/* { */
+

+
#if defined(LUA_USE_POSIX)
+
#define l_getc(f)		getc_unlocked(f)
+
#define l_lockfile(f)		flockfile(f)
+
#define l_unlockfile(f)		funlockfile(f)
+
#else
+
#define l_getc(f)		getc(f)
+
#define l_lockfile(f)		((void)0)
+
#define l_unlockfile(f)		((void)0)
+
#endif
+

+
#endif				/* } */
+

+

+
/*
+
** {======================================================
+
** l_fseek: configuration for longer offsets
+
** =======================================================
+
*/
+

+
#if !defined(l_fseek)		/* { */
+

+
#if defined(LUA_USE_POSIX)	/* { */
+

+
#include <sys/types.h>
+

+
#define l_fseek(f,o,w)		fseeko(f,o,w)
+
#define l_ftell(f)		ftello(f)
+
#define l_seeknum		off_t
+

+
#elif defined(LUA_USE_WINDOWS) && !defined(_CRTIMP_TYPEINFO) \
+
   && defined(_MSC_VER) && (_MSC_VER >= 1400)	/* }{ */
+

+
/* Windows (but not DDK) and Visual C++ 2005 or higher */
+
#define l_fseek(f,o,w)		_fseeki64(f,o,w)
+
#define l_ftell(f)		_ftelli64(f)
+
#define l_seeknum		__int64
+

+
#else				/* }{ */
+

+
/* ISO C definitions */
+
#define l_fseek(f,o,w)		fseek(f,o,w)
+
#define l_ftell(f)		ftell(f)
+
#define l_seeknum		long
+

+
#endif				/* } */
+

+
#endif				/* } */
+

+
/* }====================================================== */
+

+

+
#define IO_PREFIX	"_IO_"
+
#define IOPREF_LEN	(sizeof(IO_PREFIX)/sizeof(char) - 1)
+
#define IO_INPUT	(IO_PREFIX "input")
+
#define IO_OUTPUT	(IO_PREFIX "output")
+

+

+
typedef luaL_Stream LStream;
+

+

+
#define tolstream(L)	((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
+

+
#define isclosed(p)	((p)->closef == NULL)
+

+

+
static int io_type (lua_State *L) {
+
  LStream *p;
+
  luaL_checkany(L, 1);
+
  p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
+
  if (p == NULL)
+
    lua_pushnil(L);  /* not a file */
+
  else if (isclosed(p))
+
    lua_pushliteral(L, "closed file");
+
  else
+
    lua_pushliteral(L, "file");
+
  return 1;
+
}
+

+

+
static int f_tostring (lua_State *L) {
+
  LStream *p = tolstream(L);
+
  if (isclosed(p))
+
    lua_pushliteral(L, "file (closed)");
+
  else
+
    lua_pushfstring(L, "file (%p)", p->f);
+
  return 1;
+
}
+

+

+
static FILE *tofile (lua_State *L) {
+
  LStream *p = tolstream(L);
+
  if (isclosed(p))
+
    luaL_error(L, "attempt to use a closed file");
+
  lua_assert(p->f);
+
  return p->f;
+
}
+

+

+
/*
+
** When creating file handles, always creates a 'closed' file handle
+
** before opening the actual file; so, if there is a memory error, the
+
** handle is in a consistent state.
+
*/
+
static LStream *newprefile (lua_State *L) {
+
  LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
+
  p->closef = NULL;  /* mark file handle as 'closed' */
+
  luaL_setmetatable(L, LUA_FILEHANDLE);
+
  return p;
+
}
+

+

+
/*
+
** Calls the 'close' function from a file handle. The 'volatile' avoids
+
** a bug in some versions of the Clang compiler (e.g., clang 3.0 for
+
** 32 bits).
+
*/
+
static int aux_close (lua_State *L) {
+
  LStream *p = tolstream(L);
+
  volatile lua_CFunction cf = p->closef;
+
  p->closef = NULL;  /* mark stream as closed */
+
  return (*cf)(L);  /* close it */
+
}
+

+

+
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) {
+
  if (lua_isnone(L, 1))  /* no argument? */
+
    lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT);  /* use standard output */
+
  return f_close(L);
+
}
+

+

+
static int f_gc (lua_State *L) {
+
  LStream *p = tolstream(L);
+
  if (!isclosed(p) && p->f != NULL)
+
    aux_close(L);  /* ignore closed and incompletely open files */
+
  return 0;
+
}
+

+

+
/*
+
** function to close regular files
+
*/
+
static int io_fclose (lua_State *L) {
+
  LStream *p = tolstream(L);
+
  int res = fclose(p->f);
+
  return luaL_fileresult(L, (res == 0), NULL);
+
}
+

+

+
static LStream *newfile (lua_State *L) {
+
  LStream *p = newprefile(L);
+
  p->f = NULL;
+
  p->closef = &io_fclose;
+
  return p;
+
}
+

+

+
static void opencheck (lua_State *L, const char *fname, const char *mode) {
+
  LStream *p = newfile(L);
+
  p->f = fopen(fname, mode);
+
  if (p->f == NULL)
+
    luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno));
+
}
+

+

+
static int io_open (lua_State *L) {
+
  const char *filename = luaL_checkstring(L, 1);
+
  const char *mode = luaL_optstring(L, 2, "r");
+
  LStream *p = newfile(L);
+
  const char *md = mode;  /* to traverse/check mode */
+
  luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
+
  p->f = fopen(filename, mode);
+
  return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
+
}
+

+

+
/*
+
** function to close 'popen' files
+
*/
+
static int io_pclose (lua_State *L) {
+
  LStream *p = tolstream(L);
+
  return luaL_execresult(L, l_pclose(L, p->f));
+
}
+

+

+
static int io_popen (lua_State *L) {
+
  const char *filename = luaL_checkstring(L, 1);
+
  const char *mode = luaL_optstring(L, 2, "r");
+
  LStream *p = newprefile(L);
+
  p->f = l_popen(L, filename, mode);
+
  p->closef = &io_pclose;
+
  return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
+
}
+

+

+
static int io_tmpfile (lua_State *L) {
+
  LStream *p = newfile(L);
+
  p->f = tmpfile();
+
  return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
+
}
+

+

+
static FILE *getiofile (lua_State *L, const char *findex) {
+
  LStream *p;
+
  lua_getfield(L, LUA_REGISTRYINDEX, findex);
+
  p = (LStream *)lua_touserdata(L, -1);
+
  if (isclosed(p))
+
    luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN);
+
  return p->f;
+
}
+

+

+
static int g_iofile (lua_State *L, const char *f, const char *mode) {
+
  if (!lua_isnoneornil(L, 1)) {
+
    const char *filename = lua_tostring(L, 1);
+
    if (filename)
+
      opencheck(L, filename, mode);
+
    else {
+
      tofile(L);  /* check that it's a valid file handle */
+
      lua_pushvalue(L, 1);
+
    }
+
    lua_setfield(L, LUA_REGISTRYINDEX, f);
+
  }
+
  /* return current value */
+
  lua_getfield(L, LUA_REGISTRYINDEX, f);
+
  return 1;
+
}
+

+

+
static int io_input (lua_State *L) {
+
  return g_iofile(L, IO_INPUT, "r");
+
}
+

+

+
static int io_output (lua_State *L) {
+
  return g_iofile(L, IO_OUTPUT, "w");
+
}
+

+

+
static int io_readline (lua_State *L);
+

+

+
/*
+
** maximum number of arguments to 'f:lines'/'io.lines' (it + 3 must fit
+
** in the limit for upvalues of a closure)
+
*/
+
#define MAXARGLINE	250
+

+
static void aux_lines (lua_State *L, int toclose) {
+
  int n = lua_gettop(L) - 1;  /* number of arguments to read */
+
  luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments");
+
  lua_pushinteger(L, n);  /* number of arguments to read */
+
  lua_pushboolean(L, toclose);  /* close/not close file when finished */
+
  lua_rotate(L, 2, 2);  /* move 'n' and 'toclose' to their positions */
+
  lua_pushcclosure(L, io_readline, 3 + n);
+
}
+

+

+
static int f_lines (lua_State *L) {
+
  tofile(L);  /* check that it's a valid file handle */
+
  aux_lines(L, 0);
+
  return 1;
+
}
+

+

+
static int io_lines (lua_State *L) {
+
  int toclose;
+
  if (lua_isnone(L, 1)) lua_pushnil(L);  /* at least one argument */
+
  if (lua_isnil(L, 1)) {  /* no file name? */
+
    lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT);  /* get default input */
+
    lua_replace(L, 1);  /* put it at index 1 */
+
    tofile(L);  /* check that it's a valid file handle */
+
    toclose = 0;  /* do not close it after iteration */
+
  }
+
  else {  /* open a new file */
+
    const char *filename = luaL_checkstring(L, 1);
+
    opencheck(L, filename, "r");
+
    lua_replace(L, 1);  /* put file at index 1 */
+
    toclose = 1;  /* close it after iteration */
+
  }
+
  aux_lines(L, toclose);
+
  return 1;
+
}
+

+

+
/*
+
** {======================================================
+
** READ
+
** =======================================================
+
*/
+

+

+
/* 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 {
+
    rn->buff[rn->n++] = rn->c;  /* save current char */
+
    rn->c = l_getc(rn->f);  /* read next one */
+
    return 1;
+
  }
+
}
+

+

+
/*
+
** 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 */
+
  }
+
}
+

+

+
static int test_eof (lua_State *L, FILE *f) {
+
  int c = getc(f);
+
  ungetc(c, f);  /* no-op when c == EOF */
+
  lua_pushliteral(L, "");
+
  return (c != EOF);
+
}
+

+

+
static int read_line (lua_State *L, FILE *f, int chop) {
+
  luaL_Buffer b;
+
  int c = '\0';
+
  luaL_buffinit(L, &b);
+
  while (c != EOF && c != '\n') {  /* repeat until end of line */
+
    char *buff = luaL_prepbuffer(&b);  /* preallocate buffer */
+
    int i = 0;
+
    l_lockfile(f);  /* no memory errors can happen inside the lock */
+
    while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n')
+
      buff[i++] = c;
+
    l_unlockfile(f);
+
    luaL_addsize(&b, i);
+
  }
+
  if (!chop && c == '\n')  /* want a newline and have one? */
+
    luaL_addchar(&b, c);  /* add ending newline to result */
+
  luaL_pushresult(&b);  /* close buffer */
+
  /* return ok if read something (either a newline or something else) */
+
  return (c == '\n' || lua_rawlen(L, -1) > 0);
+
}
+

+

+
static void read_all (lua_State *L, FILE *f) {
+
  size_t nr;
+
  luaL_Buffer b;
+
  luaL_buffinit(L, &b);
+
  do {  /* read file in chunks of LUAL_BUFFERSIZE bytes */
+
    char *p = luaL_prepbuffer(&b);
+
    nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f);
+
    luaL_addsize(&b, nr);
+
  } while (nr == LUAL_BUFFERSIZE);
+
  luaL_pushresult(&b);  /* close buffer */
+
}
+

+

+
static int read_chars (lua_State *L, FILE *f, size_t n) {
+
  size_t nr;  /* number of chars actually read */
+
  char *p;
+
  luaL_Buffer b;
+
  luaL_buffinit(L, &b);
+
  p = luaL_prepbuffsize(&b, n);  /* prepare buffer to read whole block */
+
  nr = fread(p, sizeof(char), n, f);  /* try to read 'n' chars */
+
  luaL_addsize(&b, nr);
+
  luaL_pushresult(&b);  /* close buffer */
+
  return (nr > 0);  /* true iff read something */
+
}
+

+

+
static int g_read (lua_State *L, FILE *f, int first) {
+
  int nargs = lua_gettop(L) - 1;
+
  int success;
+
  int n;
+
  clearerr(f);
+
  if (nargs == 0) {  /* no arguments? */
+
    success = read_line(L, f, 1);
+
    n = first+1;  /* to return 1 result */
+
  }
+
  else {  /* ensure stack space for all results and for auxlib's buffer */
+
    luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
+
    success = 1;
+
    for (n = first; nargs-- && success; n++) {
+
      if (lua_type(L, n) == LUA_TNUMBER) {
+
        size_t l = (size_t)luaL_checkinteger(L, n);
+
        success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
+
      }
+
      else {
+
        const char *p = luaL_checkstring(L, n);
+
        if (*p == '*') p++;  /* skip optional '*' (for compatibility) */
+
        switch (*p) {
+
          case 'n':  /* number */
+
            success = read_number(L, f);
+
            break;
+
          case 'l':  /* line */
+
            success = read_line(L, f, 1);
+
            break;
+
          case 'L':  /* line with end-of-line */
+
            success = read_line(L, f, 0);
+
            break;
+
          case 'a':  /* file */
+
            read_all(L, f);  /* read entire file */
+
            success = 1; /* always success */
+
            break;
+
          default:
+
            return luaL_argerror(L, n, "invalid format");
+
        }
+
      }
+
    }
+
  }
+
  if (ferror(f))
+
    return luaL_fileresult(L, 0, NULL);
+
  if (!success) {
+
    lua_pop(L, 1);  /* remove last result */
+
    lua_pushnil(L);  /* push nil instead */
+
  }
+
  return n - first;
+
}
+

+

+
static int io_read (lua_State *L) {
+
  return g_read(L, getiofile(L, IO_INPUT), 1);
+
}
+

+

+
static int f_read (lua_State *L) {
+
  return g_read(L, tofile(L), 2);
+
}
+

+

+
static int io_readline (lua_State *L) {
+
  LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
+
  int i;
+
  int n = (int)lua_tointeger(L, lua_upvalueindex(2));
+
  if (isclosed(p))  /* file is already closed? */
+
    return luaL_error(L, "file is already closed");
+
  lua_settop(L , 1);
+
  luaL_checkstack(L, n, "too many arguments");
+
  for (i = 1; i <= n; i++)  /* push arguments to 'g_read' */
+
    lua_pushvalue(L, lua_upvalueindex(3 + i));
+
  n = g_read(L, p->f, 2);  /* 'n' is number of results */
+
  lua_assert(n > 0);  /* should return at least a nil */
+
  if (lua_toboolean(L, -n))  /* read at least one value? */
+
    return n;  /* return them */
+
  else {  /* first result is nil: EOF or error */
+
    if (n > 1) {  /* is there error information? */
+
      /* 2nd result is error message */
+
      return luaL_error(L, "%s", lua_tostring(L, -n + 1));
+
    }
+
    if (lua_toboolean(L, lua_upvalueindex(3))) {  /* generator created file? */
+
      lua_settop(L, 0);
+
      lua_pushvalue(L, lua_upvalueindex(1));
+
      aux_close(L);  /* close it */
+
    }
+
    return 0;
+
  }
+
}
+

+
/* }====================================================== */
+

+

+
static int g_write (lua_State *L, FILE *f, int arg) {
+
  int nargs = lua_gettop(L) - arg;
+
  int status = 1;
+
  for (; nargs--; arg++) {
+
    if (lua_type(L, arg) == LUA_TNUMBER) {
+
      /* optimization: could be done exactly as for strings */
+
      int len = lua_isinteger(L, arg)
+
                ? fprintf(f, LUA_INTEGER_FMT,
+
                             (LUAI_UACINT)lua_tointeger(L, arg))
+
                : fprintf(f, LUA_NUMBER_FMT,
+
                             (LUAI_UACNUMBER)lua_tonumber(L, arg));
+
      status = status && (len > 0);
+
    }
+
    else {
+
      size_t l;
+
      const char *s = luaL_checklstring(L, arg, &l);
+
      status = status && (fwrite(s, sizeof(char), l, f) == l);
+
    }
+
  }
+
  if (status) return 1;  /* file handle already on stack top */
+
  else return luaL_fileresult(L, status, NULL);
+
}
+

+

+
static int io_write (lua_State *L) {
+
  return g_write(L, getiofile(L, IO_OUTPUT), 1);
+
}
+

+

+
static int f_write (lua_State *L) {
+
  FILE *f = tofile(L);
+
  lua_pushvalue(L, 1);  /* push file at the stack top (to be returned) */
+
  return g_write(L, f, 2);
+
}
+

+

+
static int f_seek (lua_State *L) {
+
  static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
+
  static const char *const modenames[] = {"set", "cur", "end", NULL};
+
  FILE *f = tofile(L);
+
  int op = luaL_checkoption(L, 2, "cur", modenames);
+
  lua_Integer p3 = luaL_optinteger(L, 3, 0);
+
  l_seeknum offset = (l_seeknum)p3;
+
  luaL_argcheck(L, (lua_Integer)offset == p3, 3,
+
                  "not an integer in proper range");
+
  op = l_fseek(f, offset, mode[op]);
+
  if (op)
+
    return luaL_fileresult(L, 0, NULL);  /* error */
+
  else {
+
    lua_pushinteger(L, (lua_Integer)l_ftell(f));
+
    return 1;
+
  }
+
}
+

+

+
static int f_setvbuf (lua_State *L) {
+
  static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
+
  static const char *const modenames[] = {"no", "full", "line", NULL};
+
  FILE *f = tofile(L);
+
  int op = luaL_checkoption(L, 2, NULL, modenames);
+
  lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
+
  int res = setvbuf(f, NULL, mode[op], (size_t)sz);
+
  return luaL_fileresult(L, res == 0, NULL);
+
}
+

+

+

+
static int io_flush (lua_State *L) {
+
  return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
+
}
+

+

+
static int f_flush (lua_State *L) {
+
  return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
+
}
+

+

+
/*
+
** functions for 'io' library
+
*/
+
static const luaL_Reg iolib[] = {
+
  {"close", io_close},
+
  {"flush", io_flush},
+
  {"input", io_input},
+
  {"lines", io_lines},
+
  {"open", io_open},
+
  {"output", io_output},
+
  {"popen", io_popen},
+
  {"read", io_read},
+
  {"tmpfile", io_tmpfile},
+
  {"type", io_type},
+
  {"write", io_write},
+
  {NULL, NULL}
+
};
+

+

+
/*
+
** methods for file handles
+
*/
+
static const luaL_Reg flib[] = {
+
  {"close", f_close},
+
  {"flush", f_flush},
+
  {"lines", f_lines},
+
  {"read", f_read},
+
  {"seek", f_seek},
+
  {"setvbuf", f_setvbuf},
+
  {"write", f_write},
+
  {"__gc", f_gc},
+
  {"__tostring", f_tostring},
+
  {NULL, NULL}
+
};
+

+

+
static void createmeta (lua_State *L) {
+
  luaL_newmetatable(L, LUA_FILEHANDLE);  /* create metatable for file handles */
+
  lua_pushvalue(L, -1);  /* push metatable */
+
  lua_setfield(L, -2, "__index");  /* metatable.__index = metatable */
+
  luaL_setfuncs(L, flib, 0);  /* add file methods to new metatable */
+
  lua_pop(L, 1);  /* pop new metatable */
+
}
+

+

+
/*
+
** function to (not) close the standard files stdin, stdout, and stderr
+
*/
+
static int io_noclose (lua_State *L) {
+
  LStream *p = tolstream(L);
+
  p->closef = &io_noclose;  /* keep file opened */
+
  lua_pushnil(L);
+
  lua_pushliteral(L, "cannot close standard file");
+
  return 2;
+
}
+

+

+
static void createstdfile (lua_State *L, FILE *f, const char *k,
+
                           const char *fname) {
+
  LStream *p = newprefile(L);
+
  p->f = f;
+
  p->closef = &io_noclose;
+
  if (k != NULL) {
+
    lua_pushvalue(L, -1);
+
    lua_setfield(L, LUA_REGISTRYINDEX, k);  /* add file to registry */
+
  }
+
  lua_setfield(L, -2, fname);  /* add file to module */
+
}
+

+

+
LUAMOD_API int luaopen_io (lua_State *L) {
+
  luaL_newlib(L, iolib);  /* new module */
+
  createmeta(L);
+
  /* create (and set) default files */
+
  createstdfile(L, stdin, IO_INPUT, "stdin");
+
  createstdfile(L, stdout, IO_OUTPUT, "stdout");
+
  createstdfile(L, stderr, NULL, "stderr");
+
  return 1;
+
}
+

added external/lua/src/llex.c
@@ -0,0 +1,565 @@
+
/*
+
** $Id: llex.c,v 2.96.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Lexical Analyzer
+
** See Copyright Notice in lua.h
+
*/
+

+
#define llex_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <locale.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lctype.h"
+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lgc.h"
+
#include "llex.h"
+
#include "lobject.h"
+
#include "lparser.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "lzio.h"
+

+

+

+
#define next(ls) (ls->current = zgetc(ls->z))
+

+

+

+
#define currIsNewline(ls)	(ls->current == '\n' || ls->current == '\r')
+

+

+
/* ORDER RESERVED */
+
static const char *const luaX_tokens [] = {
+
    "and", "break", "do", "else", "elseif",
+
    "end", "false", "for", "function", "goto", "if",
+
    "in", "local", "nil", "not", "or", "repeat",
+
    "return", "then", "true", "until", "while",
+
    "//", "..", "...", "==", ">=", "<=", "~=",
+
    "<<", ">>", "::", "<eof>",
+
    "<number>", "<integer>", "<name>", "<string>"
+
};
+

+

+
#define save_and_next(ls) (save(ls, ls->current), next(ls))
+

+

+
static l_noret lexerror (LexState *ls, const char *msg, int token);
+

+

+
static void save (LexState *ls, int c) {
+
  Mbuffer *b = ls->buff;
+
  if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
+
    size_t newsize;
+
    if (luaZ_sizebuffer(b) >= MAX_SIZE/2)
+
      lexerror(ls, "lexical element too long", 0);
+
    newsize = luaZ_sizebuffer(b) * 2;
+
    luaZ_resizebuffer(ls->L, b, newsize);
+
  }
+
  b->buffer[luaZ_bufflen(b)++] = cast(char, c);
+
}
+

+

+
void luaX_init (lua_State *L) {
+
  int i;
+
  TString *e = luaS_newliteral(L, LUA_ENV);  /* create env name */
+
  luaC_fix(L, obj2gco(e));  /* never collect this name */
+
  for (i=0; i<NUM_RESERVED; i++) {
+
    TString *ts = luaS_new(L, luaX_tokens[i]);
+
    luaC_fix(L, obj2gco(ts));  /* reserved words are never collected */
+
    ts->extra = cast_byte(i+1);  /* reserved word */
+
  }
+
}
+

+

+
const char *luaX_token2str (LexState *ls, int token) {
+
  if (token < FIRST_RESERVED) {  /* single-byte symbols? */
+
    lua_assert(token == cast_uchar(token));
+
    return luaO_pushfstring(ls->L, "'%c'", token);
+
  }
+
  else {
+
    const char *s = luaX_tokens[token - FIRST_RESERVED];
+
    if (token < TK_EOS)  /* fixed format (symbols and reserved words)? */
+
      return luaO_pushfstring(ls->L, "'%s'", s);
+
    else  /* names, strings, and numerals */
+
      return s;
+
  }
+
}
+

+

+
static const char *txtToken (LexState *ls, int token) {
+
  switch (token) {
+
    case TK_NAME: case TK_STRING:
+
    case TK_FLT: case TK_INT:
+
      save(ls, '\0');
+
      return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff));
+
    default:
+
      return luaX_token2str(ls, token);
+
  }
+
}
+

+

+
static l_noret lexerror (LexState *ls, const char *msg, int token) {
+
  msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber);
+
  if (token)
+
    luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
+
  luaD_throw(ls->L, LUA_ERRSYNTAX);
+
}
+

+

+
l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
+
  lexerror(ls, msg, ls->t.token);
+
}
+

+

+
/*
+
** 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;
+
  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;
+
}
+

+

+
/*
+
** increment line number and skips newline sequence (any of
+
** \n, \r, \n\r, or \r\n)
+
*/
+
static void inclinenumber (LexState *ls) {
+
  int old = ls->current;
+
  lua_assert(currIsNewline(ls));
+
  next(ls);  /* skip '\n' or '\r' */
+
  if (currIsNewline(ls) && ls->current != old)
+
    next(ls);  /* skip '\n\r' or '\r\n' */
+
  if (++ls->linenumber >= MAX_INT)
+
    lexerror(ls, "chunk has too many lines", 0);
+
}
+

+

+
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
+
                    int firstchar) {
+
  ls->t.token = 0;
+
  ls->L = L;
+
  ls->current = firstchar;
+
  ls->lookahead.token = TK_EOS;  /* no look-ahead token */
+
  ls->z = z;
+
  ls->fs = NULL;
+
  ls->linenumber = 1;
+
  ls->lastline = 1;
+
  ls->source = source;
+
  ls->envn = luaS_newliteral(L, LUA_ENV);  /* get env name */
+
  luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
+
}
+

+

+

+
/*
+
** =======================================================
+
** LEXICAL ANALYZER
+
** =======================================================
+
*/
+

+

+
static int check_next1 (LexState *ls, int c) {
+
  if (ls->current == c) {
+
    next(ls);
+
    return 1;
+
  }
+
  else return 0;
+
}
+

+

+
/*
+
** Check whether current char is in set 'set' (with two chars) and
+
** saves it
+
*/
+
static int check_next2 (LexState *ls, const char *set) {
+
  lua_assert(set[2] == '\0');
+
  if (ls->current == set[0] || ls->current == set[1]) {
+
    save_and_next(ls);
+
    return 1;
+
  }
+
  else return 0;
+
}
+

+

+
/* LUA_NUMBER */
+
/*
+
** this function is quite liberal in what it accepts, as 'luaO_str2num'
+
** will reject ill-formed numerals.
+
*/
+
static int read_numeral (LexState *ls, SemInfo *seminfo) {
+
  TValue obj;
+
  const char *expo = "Ee";
+
  int first = ls->current;
+
  lua_assert(lisdigit(ls->current));
+
  save_and_next(ls);
+
  if (first == '0' && check_next2(ls, "xX"))  /* hexadecimal? */
+
    expo = "Pp";
+
  for (;;) {
+
    if (check_next2(ls, expo))  /* exponent part? */
+
      check_next2(ls, "-+");  /* optional exponent sign */
+
    if (lisxdigit(ls->current))
+
      save_and_next(ls);
+
    else if (ls->current == '.')
+
      save_and_next(ls);
+
    else break;
+
  }
+
  save(ls, '\0');
+
  if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0)  /* format error? */
+
    lexerror(ls, "malformed number", TK_FLT);
+
  if (ttisinteger(&obj)) {
+
    seminfo->i = ivalue(&obj);
+
    return TK_INT;
+
  }
+
  else {
+
    lua_assert(ttisfloat(&obj));
+
    seminfo->r = fltvalue(&obj);
+
    return TK_FLT;
+
  }
+
}
+

+

+
/*
+
** skip a sequence '[=*[' or ']=*]'; if sequence is well formed, return
+
** its number of '='s; otherwise, return a negative number (-1 iff there
+
** are no '='s after initial bracket)
+
*/
+
static int skip_sep (LexState *ls) {
+
  int count = 0;
+
  int s = ls->current;
+
  lua_assert(s == '[' || s == ']');
+
  save_and_next(ls);
+
  while (ls->current == '=') {
+
    save_and_next(ls);
+
    count++;
+
  }
+
  return (ls->current == s) ? count : (-count) - 1;
+
}
+

+

+
static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
+
  int line = ls->linenumber;  /* initial line (for error message) */
+
  save_and_next(ls);  /* skip 2nd '[' */
+
  if (currIsNewline(ls))  /* string starts with a newline? */
+
    inclinenumber(ls);  /* skip it */
+
  for (;;) {
+
    switch (ls->current) {
+
      case EOZ: {  /* error */
+
        const char *what = (seminfo ? "string" : "comment");
+
        const char *msg = luaO_pushfstring(ls->L,
+
                     "unfinished long %s (starting at line %d)", what, line);
+
        lexerror(ls, msg, TK_EOS);
+
        break;  /* to avoid warnings */
+
      }
+
      case ']': {
+
        if (skip_sep(ls) == sep) {
+
          save_and_next(ls);  /* skip 2nd ']' */
+
          goto endloop;
+
        }
+
        break;
+
      }
+
      case '\n': case '\r': {
+
        save(ls, '\n');
+
        inclinenumber(ls);
+
        if (!seminfo) luaZ_resetbuffer(ls->buff);  /* avoid wasting space */
+
        break;
+
      }
+
      default: {
+
        if (seminfo) save_and_next(ls);
+
        else next(ls);
+
      }
+
    }
+
  } endloop:
+
  if (seminfo)
+
    seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
+
                                     luaZ_bufflen(ls->buff) - 2*(2 + sep));
+
}
+

+

+
static void esccheck (LexState *ls, int c, const char *msg) {
+
  if (!c) {
+
    if (ls->current != EOZ)
+
      save_and_next(ls);  /* add current to buffer for error message */
+
    lexerror(ls, msg, TK_STRING);
+
  }
+
}
+

+

+
static int gethexa (LexState *ls) {
+
  save_and_next(ls);
+
  esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected");
+
  return luaO_hexavalue(ls->current);
+
}
+

+

+
static int readhexaesc (LexState *ls) {
+
  int r = gethexa(ls);
+
  r = (r << 4) + gethexa(ls);
+
  luaZ_buffremove(ls->buff, 2);  /* remove saved chars from buffer */
+
  return r;
+
}
+

+

+
static unsigned long readutf8esc (LexState *ls) {
+
  unsigned long r;
+
  int i = 4;  /* chars to be removed: '\', 'u', '{', and first digit */
+
  save_and_next(ls);  /* skip 'u' */
+
  esccheck(ls, ls->current == '{', "missing '{'");
+
  r = gethexa(ls);  /* must have at least one digit */
+
  while ((save_and_next(ls), lisxdigit(ls->current))) {
+
    i++;
+
    r = (r << 4) + luaO_hexavalue(ls->current);
+
    esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large");
+
  }
+
  esccheck(ls, ls->current == '}', "missing '}'");
+
  next(ls);  /* skip '}' */
+
  luaZ_buffremove(ls->buff, i);  /* remove saved chars from buffer */
+
  return r;
+
}
+

+

+
static void utf8esc (LexState *ls) {
+
  char buff[UTF8BUFFSZ];
+
  int n = luaO_utf8esc(buff, readutf8esc(ls));
+
  for (; n > 0; n--)  /* add 'buff' to string */
+
    save(ls, buff[UTF8BUFFSZ - n]);
+
}
+

+

+
static int readdecesc (LexState *ls) {
+
  int i;
+
  int r = 0;  /* result accumulator */
+
  for (i = 0; i < 3 && lisdigit(ls->current); i++) {  /* read up to 3 digits */
+
    r = 10*r + ls->current - '0';
+
    save_and_next(ls);
+
  }
+
  esccheck(ls, r <= UCHAR_MAX, "decimal escape too large");
+
  luaZ_buffremove(ls->buff, i);  /* remove read digits from buffer */
+
  return r;
+
}
+

+

+
static void read_string (LexState *ls, int del, SemInfo *seminfo) {
+
  save_and_next(ls);  /* keep delimiter (for error messages) */
+
  while (ls->current != del) {
+
    switch (ls->current) {
+
      case EOZ:
+
        lexerror(ls, "unfinished string", TK_EOS);
+
        break;  /* to avoid warnings */
+
      case '\n':
+
      case '\r':
+
        lexerror(ls, "unfinished string", TK_STRING);
+
        break;  /* to avoid warnings */
+
      case '\\': {  /* escape sequences */
+
        int c;  /* final character to be saved */
+
        save_and_next(ls);  /* keep '\\' for error messages */
+
        switch (ls->current) {
+
          case 'a': c = '\a'; goto read_save;
+
          case 'b': c = '\b'; goto read_save;
+
          case 'f': c = '\f'; goto read_save;
+
          case 'n': c = '\n'; goto read_save;
+
          case 'r': c = '\r'; goto read_save;
+
          case 't': c = '\t'; goto read_save;
+
          case 'v': c = '\v'; goto read_save;
+
          case 'x': c = readhexaesc(ls); goto read_save;
+
          case 'u': utf8esc(ls);  goto no_save;
+
          case '\n': case '\r':
+
            inclinenumber(ls); c = '\n'; goto only_save;
+
          case '\\': case '\"': case '\'':
+
            c = ls->current; goto read_save;
+
          case EOZ: goto no_save;  /* will raise an error next loop */
+
          case 'z': {  /* zap following span of spaces */
+
            luaZ_buffremove(ls->buff, 1);  /* remove '\\' */
+
            next(ls);  /* skip the 'z' */
+
            while (lisspace(ls->current)) {
+
              if (currIsNewline(ls)) inclinenumber(ls);
+
              else next(ls);
+
            }
+
            goto no_save;
+
          }
+
          default: {
+
            esccheck(ls, lisdigit(ls->current), "invalid escape sequence");
+
            c = readdecesc(ls);  /* digital escape '\ddd' */
+
            goto only_save;
+
          }
+
        }
+
       read_save:
+
         next(ls);
+
         /* go through */
+
       only_save:
+
         luaZ_buffremove(ls->buff, 1);  /* remove '\\' */
+
         save(ls, c);
+
         /* go through */
+
       no_save: break;
+
      }
+
      default:
+
        save_and_next(ls);
+
    }
+
  }
+
  save_and_next(ls);  /* skip delimiter */
+
  seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
+
                                   luaZ_bufflen(ls->buff) - 2);
+
}
+

+

+
static int llex (LexState *ls, SemInfo *seminfo) {
+
  luaZ_resetbuffer(ls->buff);
+
  for (;;) {
+
    switch (ls->current) {
+
      case '\n': case '\r': {  /* line breaks */
+
        inclinenumber(ls);
+
        break;
+
      }
+
      case ' ': case '\f': case '\t': case '\v': {  /* spaces */
+
        next(ls);
+
        break;
+
      }
+
      case '-': {  /* '-' or '--' (comment) */
+
        next(ls);
+
        if (ls->current != '-') return '-';
+
        /* else is a comment */
+
        next(ls);
+
        if (ls->current == '[') {  /* long comment? */
+
          int sep = skip_sep(ls);
+
          luaZ_resetbuffer(ls->buff);  /* 'skip_sep' may dirty the buffer */
+
          if (sep >= 0) {
+
            read_long_string(ls, NULL, sep);  /* skip long comment */
+
            luaZ_resetbuffer(ls->buff);  /* previous call may dirty the buff. */
+
            break;
+
          }
+
        }
+
        /* else short comment */
+
        while (!currIsNewline(ls) && ls->current != EOZ)
+
          next(ls);  /* skip until end of line (or end of file) */
+
        break;
+
      }
+
      case '[': {  /* long string or simply '[' */
+
        int sep = skip_sep(ls);
+
        if (sep >= 0) {
+
          read_long_string(ls, seminfo, sep);
+
          return TK_STRING;
+
        }
+
        else if (sep != -1)  /* '[=...' missing second bracket */
+
          lexerror(ls, "invalid long string delimiter", TK_STRING);
+
        return '[';
+
      }
+
      case '=': {
+
        next(ls);
+
        if (check_next1(ls, '=')) return TK_EQ;
+
        else return '=';
+
      }
+
      case '<': {
+
        next(ls);
+
        if (check_next1(ls, '=')) return TK_LE;
+
        else if (check_next1(ls, '<')) return TK_SHL;
+
        else return '<';
+
      }
+
      case '>': {
+
        next(ls);
+
        if (check_next1(ls, '=')) return TK_GE;
+
        else if (check_next1(ls, '>')) return TK_SHR;
+
        else return '>';
+
      }
+
      case '/': {
+
        next(ls);
+
        if (check_next1(ls, '/')) return TK_IDIV;
+
        else return '/';
+
      }
+
      case '~': {
+
        next(ls);
+
        if (check_next1(ls, '=')) return TK_NE;
+
        else return '~';
+
      }
+
      case ':': {
+
        next(ls);
+
        if (check_next1(ls, ':')) return TK_DBCOLON;
+
        else return ':';
+
      }
+
      case '"': case '\'': {  /* short literal strings */
+
        read_string(ls, ls->current, seminfo);
+
        return TK_STRING;
+
      }
+
      case '.': {  /* '.', '..', '...', or number */
+
        save_and_next(ls);
+
        if (check_next1(ls, '.')) {
+
          if (check_next1(ls, '.'))
+
            return TK_DOTS;   /* '...' */
+
          else return TK_CONCAT;   /* '..' */
+
        }
+
        else if (!lisdigit(ls->current)) return '.';
+
        else return read_numeral(ls, seminfo);
+
      }
+
      case '0': case '1': case '2': case '3': case '4':
+
      case '5': case '6': case '7': case '8': case '9': {
+
        return read_numeral(ls, seminfo);
+
      }
+
      case EOZ: {
+
        return TK_EOS;
+
      }
+
      default: {
+
        if (lislalpha(ls->current)) {  /* identifier or reserved word? */
+
          TString *ts;
+
          do {
+
            save_and_next(ls);
+
          } while (lislalnum(ls->current));
+
          ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
+
                                  luaZ_bufflen(ls->buff));
+
          seminfo->ts = ts;
+
          if (isreserved(ts))  /* reserved word? */
+
            return ts->extra - 1 + FIRST_RESERVED;
+
          else {
+
            return TK_NAME;
+
          }
+
        }
+
        else {  /* single-char tokens (+ - / ...) */
+
          int c = ls->current;
+
          next(ls);
+
          return c;
+
        }
+
      }
+
    }
+
  }
+
}
+

+

+
void luaX_next (LexState *ls) {
+
  ls->lastline = ls->linenumber;
+
  if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
+
    ls->t = ls->lookahead;  /* use this one */
+
    ls->lookahead.token = TK_EOS;  /* and discharge it */
+
  }
+
  else
+
    ls->t.token = llex(ls, &ls->t.seminfo);  /* read next token */
+
}
+

+

+
int luaX_lookahead (LexState *ls) {
+
  lua_assert(ls->lookahead.token == TK_EOS);
+
  ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
+
  return ls->lookahead.token;
+
}
+

added external/lua/src/llex.h
@@ -0,0 +1,85 @@
+
/*
+
** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Lexical Analyzer
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef llex_h
+
#define llex_h
+

+
#include "lobject.h"
+
#include "lzio.h"
+

+

+
#define FIRST_RESERVED	257
+

+

+
#if !defined(LUA_ENV)
+
#define LUA_ENV		"_ENV"
+
#endif
+

+

+
/*
+
* WARNING: if you change the order of this enumeration,
+
* grep "ORDER RESERVED"
+
*/
+
enum RESERVED {
+
  /* terminal symbols denoted by reserved words */
+
  TK_AND = FIRST_RESERVED, TK_BREAK,
+
  TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
+
  TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
+
  TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
+
  /* other terminal symbols */
+
  TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
+
  TK_SHL, TK_SHR,
+
  TK_DBCOLON, TK_EOS,
+
  TK_FLT, TK_INT, TK_NAME, TK_STRING
+
};
+

+
/* number of reserved words */
+
#define NUM_RESERVED	(cast(int, TK_WHILE-FIRST_RESERVED+1))
+

+

+
typedef union {
+
  lua_Number r;
+
  lua_Integer i;
+
  TString *ts;
+
} SemInfo;  /* semantics information */
+

+

+
typedef struct Token {
+
  int token;
+
  SemInfo seminfo;
+
} Token;
+

+

+
/* state of the lexer plus state of the parser when shared by all
+
   functions */
+
typedef struct LexState {
+
  int current;  /* current character (charint) */
+
  int linenumber;  /* input line counter */
+
  int lastline;  /* line of last token 'consumed' */
+
  Token t;  /* current token */
+
  Token lookahead;  /* look ahead token */
+
  struct FuncState *fs;  /* current function (parser) */
+
  struct lua_State *L;
+
  ZIO *z;  /* input stream */
+
  Mbuffer *buff;  /* buffer for tokens */
+
  Table *h;  /* to avoid collection/reuse strings */
+
  struct Dyndata *dyd;  /* dynamic structures used by the parser */
+
  TString *source;  /* current source name */
+
  TString *envn;  /* environment variable name */
+
} LexState;
+

+

+
LUAI_FUNC void luaX_init (lua_State *L);
+
LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
+
                              TString *source, int firstchar);
+
LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
+
LUAI_FUNC void luaX_next (LexState *ls);
+
LUAI_FUNC int luaX_lookahead (LexState *ls);
+
LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s);
+
LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
+

+

+
#endif
added external/lua/src/llimits.h
@@ -0,0 +1,323 @@
+
/*
+
** $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
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef llimits_h
+
#define llimits_h
+

+

+
#include <limits.h>
+
#include <stddef.h>
+

+

+
#include "lua.h"
+

+
/*
+
** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count
+
** the total memory used by Lua (in bytes). Usually, 'size_t' and
+
** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines.
+
*/
+
#if defined(LUAI_MEM)		/* { external definitions? */
+
typedef LUAI_UMEM lu_mem;
+
typedef LUAI_MEM l_mem;
+
#elif LUAI_BITSINT >= 32	/* }{ */
+
typedef size_t lu_mem;
+
typedef ptrdiff_t l_mem;
+
#else  /* 16-bit ints */	/* }{ */
+
typedef unsigned long lu_mem;
+
typedef long l_mem;
+
#endif				/* } */
+

+

+
/* chars used as small naturals (so that 'char' is reserved for characters) */
+
typedef unsigned char lu_byte;
+

+

+
/* maximum value for size_t */
+
#define MAX_SIZET	((size_t)(~(size_t)0))
+

+
/* maximum size visible for Lua (must be representable in a lua_Integer */
+
#define MAX_SIZE	(sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \
+
                          : (size_t)(LUA_MAXINTEGER))
+

+

+
#define MAX_LUMEM	((lu_mem)(~(lu_mem)0))
+

+
#define MAX_LMEM	((l_mem)(MAX_LUMEM >> 1))
+

+

+
#define MAX_INT		INT_MAX  /* maximum value of an int */
+

+

+
/*
+
** conversion of pointer to unsigned integer:
+
** this is for hashing only; there is no problem if the integer
+
** cannot hold the whole pointer value
+
*/
+
#define point2uint(p)	((unsigned int)((size_t)(p) & UINT_MAX))
+

+

+

+
/* type to ensure maximum alignment */
+
#if defined(LUAI_USER_ALIGNMENT_T)
+
typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
+
#else
+
typedef union {
+
  lua_Number n;
+
  double u;
+
  void *s;
+
  lua_Integer i;
+
  long l;
+
} L_Umaxalign;
+
#endif
+

+

+

+
/* types of 'usual argument conversions' for lua_Number and lua_Integer */
+
typedef LUAI_UACNUMBER l_uacNumber;
+
typedef LUAI_UACINT l_uacInt;
+

+

+
/* internal assertions for in-house debugging */
+
#if defined(lua_assert)
+
#define check_exp(c,e)		(lua_assert(c), (e))
+
/* to avoid problems with conditions too long */
+
#define lua_longassert(c)	((c) ? (void)0 : lua_assert(0))
+
#else
+
#define lua_assert(c)		((void)0)
+
#define check_exp(c,e)		(e)
+
#define lua_longassert(c)	((void)0)
+
#endif
+

+
/*
+
** assertion for checking API calls
+
*/
+
#if !defined(luai_apicheck)
+
#define luai_apicheck(l,e)	lua_assert(e)
+
#endif
+

+
#define api_check(l,e,msg)	luai_apicheck(l,(e) && msg)
+

+

+
/* macro to avoid warnings about unused variables */
+
#if !defined(UNUSED)
+
#define UNUSED(x)	((void)(x))
+
#endif
+

+

+
/* type casts (a macro highlights casts in the code) */
+
#define cast(t, exp)	((t)(exp))
+

+
#define cast_void(i)	cast(void, (i))
+
#define cast_byte(i)	cast(lu_byte, (i))
+
#define cast_num(i)	cast(lua_Number, (i))
+
#define cast_int(i)	cast(int, (i))
+
#define cast_uchar(i)	cast(unsigned char, (i))
+

+

+
/* cast a signed lua_Integer to lua_Unsigned */
+
#if !defined(l_castS2U)
+
#define l_castS2U(i)	((lua_Unsigned)(i))
+
#endif
+

+
/*
+
** cast a lua_Unsigned to a signed lua_Integer; this cast is
+
** not strict ISO C, but two-complement architectures should
+
** work fine.
+
*/
+
#if !defined(l_castU2S)
+
#define l_castU2S(i)	((lua_Integer)(i))
+
#endif
+

+

+
/*
+
** non-return type
+
*/
+
#if defined(__GNUC__)
+
#define l_noret		void __attribute__((noreturn))
+
#elif defined(_MSC_VER) && _MSC_VER >= 1200
+
#define l_noret		void __declspec(noreturn)
+
#else
+
#define l_noret		void
+
#endif
+

+

+

+
/*
+
** maximum depth for nested C calls and syntactical nested non-terminals
+
** in a program. (Value must fit in an unsigned short int.)
+
*/
+
#if !defined(LUAI_MAXCCALLS)
+
#define LUAI_MAXCCALLS		200
+
#endif
+

+

+

+
/*
+
** type for virtual-machine instructions;
+
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
+
*/
+
#if LUAI_BITSINT >= 32
+
typedef unsigned int Instruction;
+
#else
+
typedef unsigned long Instruction;
+
#endif
+

+

+

+
/*
+
** Maximum length for short strings, that is, strings that are
+
** internalized. (Cannot be smaller than reserved words or tags for
+
** metamethods, as these strings must be internalized;
+
** #("function") = 8, #("__newindex") = 10.)
+
*/
+
#if !defined(LUAI_MAXSHORTLEN)
+
#define LUAI_MAXSHORTLEN	40
+
#endif
+

+

+
/*
+
** Initial size for the string table (must be power of 2).
+
** The Lua core alone registers ~50 strings (reserved words +
+
** metaevent keys + a few others). Libraries would typically add
+
** a few dozens more.
+
*/
+
#if !defined(MINSTRTABSIZE)
+
#define MINSTRTABSIZE	128
+
#endif
+

+

+
/*
+
** Size of cache for strings in the API. 'N' is the number of
+
** sets (better be a prime) and "M" is the size of each set (M == 1
+
** makes a direct cache.)
+
*/
+
#if !defined(STRCACHE_N)
+
#define STRCACHE_N		53
+
#define STRCACHE_M		2
+
#endif
+

+

+
/* minimum size for string buffer */
+
#if !defined(LUA_MINBUFFER)
+
#define LUA_MINBUFFER	32
+
#endif
+

+

+
/*
+
** macros that are executed whenever program enters the Lua core
+
** ('lua_lock') and leaves the core ('lua_unlock')
+
*/
+
#if !defined(lua_lock)
+
#define lua_lock(L)	((void) 0)
+
#define lua_unlock(L)	((void) 0)
+
#endif
+

+
/*
+
** macro executed during Lua functions at points where the
+
** function can yield.
+
*/
+
#if !defined(luai_threadyield)
+
#define luai_threadyield(L)	{lua_unlock(L); lua_lock(L);}
+
#endif
+

+

+
/*
+
** these macros allow user-specific actions on threads when you defined
+
** LUAI_EXTRASPACE and need to do something extra when a thread is
+
** created/deleted/resumed/yielded.
+
*/
+
#if !defined(luai_userstateopen)
+
#define luai_userstateopen(L)		((void)L)
+
#endif
+

+
#if !defined(luai_userstateclose)
+
#define luai_userstateclose(L)		((void)L)
+
#endif
+

+
#if !defined(luai_userstatethread)
+
#define luai_userstatethread(L,L1)	((void)L)
+
#endif
+

+
#if !defined(luai_userstatefree)
+
#define luai_userstatefree(L,L1)	((void)L)
+
#endif
+

+
#if !defined(luai_userstateresume)
+
#define luai_userstateresume(L,n)	((void)L)
+
#endif
+

+
#if !defined(luai_userstateyield)
+
#define luai_userstateyield(L,n)	((void)L)
+
#endif
+

+

+

+
/*
+
** The luai_num* macros define the primitive operations over numbers.
+
*/
+

+
/* floor division (defined as 'floor(a/b)') */
+
#if !defined(luai_numidiv)
+
#define luai_numidiv(L,a,b)     ((void)L, l_floor(luai_numdiv(L,a,b)))
+
#endif
+

+
/* float division */
+
#if !defined(luai_numdiv)
+
#define luai_numdiv(L,a,b)      ((a)/(b))
+
#endif
+

+
/*
+
** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when
+
** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of
+
** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b)
+
** ~= floor(a/b)'. That happens when the division has a non-integer
+
** negative result, which is equivalent to the test below.
+
*/
+
#if !defined(luai_nummod)
+
#define luai_nummod(L,a,b,m)  \
+
  { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
+
#endif
+

+
/* exponentiation */
+
#if !defined(luai_numpow)
+
#define luai_numpow(L,a,b)      ((void)L, l_mathop(pow)(a,b))
+
#endif
+

+
/* the others are quite standard operations */
+
#if !defined(luai_numadd)
+
#define luai_numadd(L,a,b)      ((a)+(b))
+
#define luai_numsub(L,a,b)      ((a)-(b))
+
#define luai_nummul(L,a,b)      ((a)*(b))
+
#define luai_numunm(L,a)        (-(a))
+
#define luai_numeq(a,b)         ((a)==(b))
+
#define luai_numlt(a,b)         ((a)<(b))
+
#define luai_numle(a,b)         ((a)<=(b))
+
#define luai_numisnan(a)        (!luai_numeq((a), (a)))
+
#endif
+

+

+

+

+

+
/*
+
** macro to control inclusion of some hard tests on stack reallocation
+
*/
+
#if !defined(HARDSTACKTESTS)
+
#define condmovestack(L,pre,pos)	((void)0)
+
#else
+
/* realloc stack keeping its size */
+
#define condmovestack(L,pre,pos)  \
+
	{ int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_); pos; }
+
#endif
+

+
#if !defined(HARDMEMTESTS)
+
#define condchangemem(L,pre,pos)	((void)0)
+
#else
+
#define condchangemem(L,pre,pos)  \
+
	{ if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } }
+
#endif
+

+
#endif
added external/lua/src/lmathlib.c
@@ -0,0 +1,410 @@
+
/*
+
** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Standard mathematical library
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lmathlib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <stdlib.h>
+
#include <math.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+
#undef PI
+
#define PI	(l_mathop(3.141592653589793238462643383279502884))
+

+

+
#if !defined(l_rand)		/* { */
+
#if defined(LUA_USE_POSIX)
+
#define l_rand()	random()
+
#define l_srand(x)	srandom(x)
+
#define L_RANDMAX	2147483647	/* (2^31 - 1), following POSIX */
+
#else
+
#define l_rand()	rand()
+
#define l_srand(x)	srand(x)
+
#define L_RANDMAX	RAND_MAX
+
#endif
+
#endif				/* } */
+

+

+
static int math_abs (lua_State *L) {
+
  if (lua_isinteger(L, 1)) {
+
    lua_Integer n = lua_tointeger(L, 1);
+
    if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n);
+
    lua_pushinteger(L, n);
+
  }
+
  else
+
    lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_sin (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_cos (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_tan (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_asin (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_acos (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_atan (lua_State *L) {
+
  lua_Number y = luaL_checknumber(L, 1);
+
  lua_Number x = luaL_optnumber(L, 2, 1);
+
  lua_pushnumber(L, l_mathop(atan2)(y, x));
+
  return 1;
+
}
+

+

+
static int math_toint (lua_State *L) {
+
  int valid;
+
  lua_Integer n = lua_tointegerx(L, 1, &valid);
+
  if (valid)
+
    lua_pushinteger(L, n);
+
  else {
+
    luaL_checkany(L, 1);
+
    lua_pushnil(L);  /* value is not convertible to integer */
+
  }
+
  return 1;
+
}
+

+

+
static void pushnumint (lua_State *L, lua_Number d) {
+
  lua_Integer n;
+
  if (lua_numbertointeger(d, &n))  /* does 'd' fit in an integer? */
+
    lua_pushinteger(L, n);  /* result is integer */
+
  else
+
    lua_pushnumber(L, d);  /* result is float */
+
}
+

+

+
static int math_floor (lua_State *L) {
+
  if (lua_isinteger(L, 1))
+
    lua_settop(L, 1);  /* integer is its own floor */
+
  else {
+
    lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1));
+
    pushnumint(L, d);
+
  }
+
  return 1;
+
}
+

+

+
static int math_ceil (lua_State *L) {
+
  if (lua_isinteger(L, 1))
+
    lua_settop(L, 1);  /* integer is its own ceil */
+
  else {
+
    lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1));
+
    pushnumint(L, d);
+
  }
+
  return 1;
+
}
+

+

+
static int math_fmod (lua_State *L) {
+
  if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) {
+
    lua_Integer d = lua_tointeger(L, 2);
+
    if ((lua_Unsigned)d + 1u <= 1u) {  /* special cases: -1 or 0 */
+
      luaL_argcheck(L, d != 0, 2, "zero");
+
      lua_pushinteger(L, 0);  /* avoid overflow with 0x80000... / -1 */
+
    }
+
    else
+
      lua_pushinteger(L, lua_tointeger(L, 1) % d);
+
  }
+
  else
+
    lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
+
                                     luaL_checknumber(L, 2)));
+
  return 1;
+
}
+

+

+
/*
+
** next function does not use 'modf', avoiding problems with 'double*'
+
** (which is not compatible with 'float*') when lua_Number is not
+
** 'double'.
+
*/
+
static int math_modf (lua_State *L) {
+
  if (lua_isinteger(L ,1)) {
+
    lua_settop(L, 1);  /* number is its own integer part */
+
    lua_pushnumber(L, 0);  /* no fractional part */
+
  }
+
  else {
+
    lua_Number n = luaL_checknumber(L, 1);
+
    /* integer part (rounds toward zero) */
+
    lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n);
+
    pushnumint(L, ip);
+
    /* fractional part (test needed for inf/-inf) */
+
    lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
+
  }
+
  return 2;
+
}
+

+

+
static int math_sqrt (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+

+
static int math_ult (lua_State *L) {
+
  lua_Integer a = luaL_checkinteger(L, 1);
+
  lua_Integer b = luaL_checkinteger(L, 2);
+
  lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b);
+
  return 1;
+
}
+

+
static int math_log (lua_State *L) {
+
  lua_Number x = luaL_checknumber(L, 1);
+
  lua_Number res;
+
  if (lua_isnoneornil(L, 2))
+
    res = l_mathop(log)(x);
+
  else {
+
    lua_Number base = luaL_checknumber(L, 2);
+
#if !defined(LUA_USE_C89)
+
    if (base == l_mathop(2.0))
+
      res = l_mathop(log2)(x); else
+
#endif
+
    if (base == l_mathop(10.0))
+
      res = l_mathop(log10)(x);
+
    else
+
      res = l_mathop(log)(x)/l_mathop(log)(base);
+
  }
+
  lua_pushnumber(L, res);
+
  return 1;
+
}
+

+
static int math_exp (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_deg (lua_State *L) {
+
  lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
+
  return 1;
+
}
+

+
static int math_rad (lua_State *L) {
+
  lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
+
  return 1;
+
}
+

+

+
static int math_min (lua_State *L) {
+
  int n = lua_gettop(L);  /* number of arguments */
+
  int imin = 1;  /* index of current minimum value */
+
  int i;
+
  luaL_argcheck(L, n >= 1, 1, "value expected");
+
  for (i = 2; i <= n; i++) {
+
    if (lua_compare(L, i, imin, LUA_OPLT))
+
      imin = i;
+
  }
+
  lua_pushvalue(L, imin);
+
  return 1;
+
}
+

+

+
static int math_max (lua_State *L) {
+
  int n = lua_gettop(L);  /* number of arguments */
+
  int imax = 1;  /* index of current maximum value */
+
  int i;
+
  luaL_argcheck(L, n >= 1, 1, "value expected");
+
  for (i = 2; i <= n; i++) {
+
    if (lua_compare(L, imax, i, LUA_OPLT))
+
      imax = i;
+
  }
+
  lua_pushvalue(L, imax);
+
  return 1;
+
}
+

+
/*
+
** This function uses 'double' (instead of 'lua_Number') to ensure that
+
** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0'
+
** will keep full precision (ensuring that 'r' is always less than 1.0.)
+
*/
+
static int math_random (lua_State *L) {
+
  lua_Integer low, up;
+
  double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0));
+
  switch (lua_gettop(L)) {  /* check number of arguments */
+
    case 0: {  /* no arguments */
+
      lua_pushnumber(L, (lua_Number)r);  /* Number between 0 and 1 */
+
      return 1;
+
    }
+
    case 1: {  /* only upper limit */
+
      low = 1;
+
      up = luaL_checkinteger(L, 1);
+
      break;
+
    }
+
    case 2: {  /* lower and upper limits */
+
      low = luaL_checkinteger(L, 1);
+
      up = luaL_checkinteger(L, 2);
+
      break;
+
    }
+
    default: return luaL_error(L, "wrong number of arguments");
+
  }
+
  /* random integer in the interval [low, up] */
+
  luaL_argcheck(L, low <= up, 1, "interval is empty");
+
  luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1,
+
                   "interval too large");
+
  r *= (double)(up - low) + 1.0;
+
  lua_pushinteger(L, (lua_Integer)r + low);
+
  return 1;
+
}
+

+

+
static int math_randomseed (lua_State *L) {
+
  l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1));
+
  (void)l_rand(); /* discard first value to avoid undesirable correlations */
+
  return 0;
+
}
+

+

+
static int math_type (lua_State *L) {
+
  if (lua_type(L, 1) == LUA_TNUMBER) {
+
      if (lua_isinteger(L, 1))
+
        lua_pushliteral(L, "integer");
+
      else
+
        lua_pushliteral(L, "float");
+
  }
+
  else {
+
    luaL_checkany(L, 1);
+
    lua_pushnil(L);
+
  }
+
  return 1;
+
}
+

+

+
/*
+
** {==================================================================
+
** Deprecated functions (for compatibility only)
+
** ===================================================================
+
*/
+
#if defined(LUA_COMPAT_MATHLIB)
+

+
static int math_cosh (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_sinh (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_tanh (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
static int math_pow (lua_State *L) {
+
  lua_Number x = luaL_checknumber(L, 1);
+
  lua_Number y = luaL_checknumber(L, 2);
+
  lua_pushnumber(L, l_mathop(pow)(x, y));
+
  return 1;
+
}
+

+
static int math_frexp (lua_State *L) {
+
  int e;
+
  lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
+
  lua_pushinteger(L, e);
+
  return 2;
+
}
+

+
static int math_ldexp (lua_State *L) {
+
  lua_Number x = luaL_checknumber(L, 1);
+
  int ep = (int)luaL_checkinteger(L, 2);
+
  lua_pushnumber(L, l_mathop(ldexp)(x, ep));
+
  return 1;
+
}
+

+
static int math_log10 (lua_State *L) {
+
  lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
+
  return 1;
+
}
+

+
#endif
+
/* }================================================================== */
+

+

+

+
static const luaL_Reg mathlib[] = {
+
  {"abs",   math_abs},
+
  {"acos",  math_acos},
+
  {"asin",  math_asin},
+
  {"atan",  math_atan},
+
  {"ceil",  math_ceil},
+
  {"cos",   math_cos},
+
  {"deg",   math_deg},
+
  {"exp",   math_exp},
+
  {"tointeger", math_toint},
+
  {"floor", math_floor},
+
  {"fmod",   math_fmod},
+
  {"ult",   math_ult},
+
  {"log",   math_log},
+
  {"max",   math_max},
+
  {"min",   math_min},
+
  {"modf",   math_modf},
+
  {"rad",   math_rad},
+
  {"random",     math_random},
+
  {"randomseed", math_randomseed},
+
  {"sin",   math_sin},
+
  {"sqrt",  math_sqrt},
+
  {"tan",   math_tan},
+
  {"type", math_type},
+
#if defined(LUA_COMPAT_MATHLIB)
+
  {"atan2", math_atan},
+
  {"cosh",   math_cosh},
+
  {"sinh",   math_sinh},
+
  {"tanh",   math_tanh},
+
  {"pow",   math_pow},
+
  {"frexp", math_frexp},
+
  {"ldexp", math_ldexp},
+
  {"log10", math_log10},
+
#endif
+
  /* placeholders */
+
  {"pi", NULL},
+
  {"huge", NULL},
+
  {"maxinteger", NULL},
+
  {"mininteger", NULL},
+
  {NULL, NULL}
+
};
+

+

+
/*
+
** Open math library
+
*/
+
LUAMOD_API int luaopen_math (lua_State *L) {
+
  luaL_newlib(L, mathlib);
+
  lua_pushnumber(L, PI);
+
  lua_setfield(L, -2, "pi");
+
  lua_pushnumber(L, (lua_Number)HUGE_VAL);
+
  lua_setfield(L, -2, "huge");
+
  lua_pushinteger(L, LUA_MAXINTEGER);
+
  lua_setfield(L, -2, "maxinteger");
+
  lua_pushinteger(L, LUA_MININTEGER);
+
  lua_setfield(L, -2, "mininteger");
+
  return 1;
+
}
+

added external/lua/src/lmem.c
@@ -0,0 +1,100 @@
+
/*
+
** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Interface to Memory Manager
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lmem_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <stddef.h>
+

+
#include "lua.h"
+

+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lgc.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lstate.h"
+

+

+

+
/*
+
** About the realloc function:
+
** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
+
** ('osize' is the old size, 'nsize' is the new size)
+
**
+
** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no
+
** matter 'x').
+
**
+
** * frealloc(ud, p, x, 0) frees the block 'p'
+
** (in this specific case, frealloc must return NULL);
+
** particularly, frealloc(ud, NULL, 0, 0) does nothing
+
** (which is equivalent to free(NULL) in ISO C)
+
**
+
** frealloc returns NULL if it cannot create or reallocate the area
+
** (any reallocation to an equal or smaller size cannot fail!)
+
*/
+

+

+

+
#define MINSIZEARRAY	4
+

+

+
void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
+
                     int limit, const char *what) {
+
  void *newblock;
+
  int newsize;
+
  if (*size >= limit/2) {  /* cannot double it? */
+
    if (*size >= limit)  /* cannot grow even a little? */
+
      luaG_runerror(L, "too many %s (limit is %d)", what, limit);
+
    newsize = limit;  /* still have at least one free place */
+
  }
+
  else {
+
    newsize = (*size)*2;
+
    if (newsize < MINSIZEARRAY)
+
      newsize = MINSIZEARRAY;  /* minimum size */
+
  }
+
  newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
+
  *size = newsize;  /* update only when everything else is OK */
+
  return newblock;
+
}
+

+

+
l_noret luaM_toobig (lua_State *L) {
+
  luaG_runerror(L, "memory allocation error: block too big");
+
}
+

+

+

+
/*
+
** generic allocation routine.
+
*/
+
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
+
  void *newblock;
+
  global_State *g = G(L);
+
  size_t realosize = (block) ? osize : 0;
+
  lua_assert((realosize == 0) == (block == NULL));
+
#if defined(HARDMEMTESTS)
+
  if (nsize > realosize && g->gcrunning)
+
    luaC_fullgc(L, 1);  /* force a GC whenever possible */
+
#endif
+
  newblock = (*g->frealloc)(g->ud, block, osize, nsize);
+
  if (newblock == NULL && nsize > 0) {
+
    lua_assert(nsize > realosize);  /* cannot fail when shrinking a block */
+
    if (g->version) {  /* is state fully built? */
+
      luaC_fullgc(L, 1);  /* try to free some memory... */
+
      newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
+
    }
+
    if (newblock == NULL)
+
      luaD_throw(L, LUA_ERRMEM);
+
  }
+
  lua_assert((nsize == 0) == (newblock == NULL));
+
  g->GCdebt = (g->GCdebt + nsize) - realosize;
+
  return newblock;
+
}
+

added external/lua/src/lmem.h
@@ -0,0 +1,69 @@
+
/*
+
** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Interface to Memory Manager
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lmem_h
+
#define lmem_h
+

+

+
#include <stddef.h>
+

+
#include "llimits.h"
+
#include "lua.h"
+

+

+
/*
+
** This macro reallocs a vector 'b' from 'on' to 'n' elements, where
+
** each element has size 'e'. In case of arithmetic overflow of the
+
** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because
+
** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e).
+
**
+
** (The macro is somewhat complex to avoid warnings:  The 'sizeof'
+
** comparison avoids a runtime comparison when overflow cannot occur.
+
** The compiler should be able to optimize the real test by itself, but
+
** when it does it, it may give a warning about "comparison is always
+
** false due to limited range of data type"; the +1 tricks the compiler,
+
** avoiding this warning but also this optimization.)
+
*/
+
#define luaM_reallocv(L,b,on,n,e) \
+
  (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \
+
      ? luaM_toobig(L) : cast_void(0)) , \
+
   luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
+

+
/*
+
** Arrays of chars do not need any test
+
*/
+
#define luaM_reallocvchar(L,b,on,n)  \
+
    cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char)))
+

+
#define luaM_freemem(L, b, s)	luaM_realloc_(L, (b), (s), 0)
+
#define luaM_free(L, b)		luaM_realloc_(L, (b), sizeof(*(b)), 0)
+
#define luaM_freearray(L, b, n)   luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0)
+

+
#define luaM_malloc(L,s)	luaM_realloc_(L, NULL, 0, (s))
+
#define luaM_new(L,t)		cast(t *, luaM_malloc(L, sizeof(t)))
+
#define luaM_newvector(L,n,t) \
+
		cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
+

+
#define luaM_newobject(L,tag,s)	luaM_realloc_(L, NULL, tag, (s))
+

+
#define luaM_growvector(L,v,nelems,size,t,limit,e) \
+
          if ((nelems)+1 > (size)) \
+
            ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
+

+
#define luaM_reallocvector(L, v,oldn,n,t) \
+
   ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
+

+
LUAI_FUNC l_noret luaM_toobig (lua_State *L);
+

+
/* not to be called directly */
+
LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
+
                                                          size_t size);
+
LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
+
                               size_t size_elem, int limit,
+
                               const char *what);
+

+
#endif
+

added external/lua/src/loadlib.c
@@ -0,0 +1,790 @@
+
/*
+
** $Id: loadlib.c,v 1.130.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Dynamic library loader for Lua
+
** See Copyright Notice in lua.h
+
**
+
** This module contains an implementation of loadlib for Unix systems
+
** that have dlfcn, an implementation for Windows, and a stub for other
+
** systems.
+
*/
+

+
#define loadlib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+
/*
+
** LUA_IGMARK is a mark to ignore all before it when building the
+
** luaopen_ function name.
+
*/
+
#if !defined (LUA_IGMARK)
+
#define LUA_IGMARK		"-"
+
#endif
+

+

+
/*
+
** LUA_CSUBSEP is the character that replaces dots in submodule names
+
** when searching for a C loader.
+
** LUA_LSUBSEP is the character that replaces dots in submodule names
+
** when searching for a Lua loader.
+
*/
+
#if !defined(LUA_CSUBSEP)
+
#define LUA_CSUBSEP		LUA_DIRSEP
+
#endif
+

+
#if !defined(LUA_LSUBSEP)
+
#define LUA_LSUBSEP		LUA_DIRSEP
+
#endif
+

+

+
/* prefix for open functions in C libraries */
+
#define LUA_POF		"luaopen_"
+

+
/* separator for open functions in C libraries */
+
#define LUA_OFSEP	"_"
+

+

+
/*
+
** unique key for table in the registry that keeps handles
+
** for all loaded C libraries
+
*/
+
static const int CLIBS = 0;
+

+
#define LIB_FAIL	"open"
+

+

+
#define setprogdir(L)           ((void)0)
+

+

+
/*
+
** system-dependent functions
+
*/
+

+
/*
+
** unload library 'lib'
+
*/
+
static void lsys_unloadlib (void *lib);
+

+
/*
+
** load C library in file 'path'. If 'seeglb', load with all names in
+
** the library global.
+
** Returns the library; in case of error, returns NULL plus an
+
** error string in the stack.
+
*/
+
static void *lsys_load (lua_State *L, const char *path, int seeglb);
+

+
/*
+
** Try to find a function named 'sym' in library 'lib'.
+
** Returns the function; in case of error, returns NULL plus an
+
** error string in the stack.
+
*/
+
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
+

+

+

+

+
#if defined(LUA_USE_DLOPEN)	/* { */
+
/*
+
** {========================================================================
+
** This is an implementation of loadlib based on the dlfcn interface.
+
** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
+
** NetBSD, AIX 4.2, HPUX 11, and  probably most other Unix flavors, at least
+
** as an emulation layer on top of native functions.
+
** =========================================================================
+
*/
+

+
#include <dlfcn.h>
+

+
/*
+
** Macro to convert pointer-to-void* to pointer-to-function. This cast
+
** is undefined according to ISO C, but POSIX assumes that it works.
+
** (The '__extension__' in gnu compilers is only to avoid warnings.)
+
*/
+
#if defined(__GNUC__)
+
#define cast_func(p) (__extension__ (lua_CFunction)(p))
+
#else
+
#define cast_func(p) ((lua_CFunction)(p))
+
#endif
+

+

+
static void lsys_unloadlib (void *lib) {
+
  dlclose(lib);
+
}
+

+

+
static void *lsys_load (lua_State *L, const char *path, int seeglb) {
+
  void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
+
  if (lib == NULL) lua_pushstring(L, dlerror());
+
  return lib;
+
}
+

+

+
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
+
  lua_CFunction f = cast_func(dlsym(lib, sym));
+
  if (f == NULL) lua_pushstring(L, dlerror());
+
  return f;
+
}
+

+
/* }====================================================== */
+

+

+

+
#elif defined(LUA_DL_DLL)	/* }{ */
+
/*
+
** {======================================================================
+
** This is an implementation of loadlib for Windows using native functions.
+
** =======================================================================
+
*/
+

+
#include <windows.h>
+

+

+
/*
+
** optional flags for LoadLibraryEx
+
*/
+
#if !defined(LUA_LLE_FLAGS)
+
#define LUA_LLE_FLAGS	0
+
#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) {
+
  char buff[MAX_PATH + 1];
+
  char *lb;
+
  DWORD nsize = sizeof(buff)/sizeof(char);
+
  DWORD n = GetModuleFileNameA(NULL, buff, nsize);  /* get exec. name */
+
  if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
+
    luaL_error(L, "unable to get ModuleFileName");
+
  else {
+
    *lb = '\0';  /* cut name on the last '\\' to get the path */
+
    luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
+
    lua_remove(L, -2);  /* remove original string */
+
  }
+
}
+

+

+

+

+
static void pusherror (lua_State *L) {
+
  int error = GetLastError();
+
  char buffer[128];
+
  if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
+
      NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
+
    lua_pushstring(L, buffer);
+
  else
+
    lua_pushfstring(L, "system error %d\n", error);
+
}
+

+
static void lsys_unloadlib (void *lib) {
+
  FreeLibrary((HMODULE)lib);
+
}
+

+

+
static void *lsys_load (lua_State *L, const char *path, int seeglb) {
+
  HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
+
  (void)(seeglb);  /* not used: symbols are 'global' by default */
+
  if (lib == NULL) pusherror(L);
+
  return lib;
+
}
+

+

+
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
+
  lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
+
  if (f == NULL) pusherror(L);
+
  return f;
+
}
+

+
/* }====================================================== */
+

+

+
#else				/* }{ */
+
/*
+
** {======================================================
+
** Fallback for other systems
+
** =======================================================
+
*/
+

+
#undef LIB_FAIL
+
#define LIB_FAIL	"absent"
+

+

+
#define DLMSG	"dynamic libraries not enabled; check your Lua installation"
+

+

+
static void lsys_unloadlib (void *lib) {
+
  (void)(lib);  /* not used */
+
}
+

+

+
static void *lsys_load (lua_State *L, const char *path, int seeglb) {
+
  (void)(path); (void)(seeglb);  /* not used */
+
  lua_pushliteral(L, DLMSG);
+
  return NULL;
+
}
+

+

+
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
+
  (void)(lib); (void)(sym);  /* not used */
+
  lua_pushliteral(L, DLMSG);
+
  return NULL;
+
}
+

+
/* }====================================================== */
+
#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]
+
*/
+
static void *checkclib (lua_State *L, const char *path) {
+
  void *plib;
+
  lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS);
+
  lua_getfield(L, -1, path);
+
  plib = lua_touserdata(L, -1);  /* plib = CLIBS[path] */
+
  lua_pop(L, 2);  /* pop CLIBS table and 'plib' */
+
  return plib;
+
}
+

+

+
/*
+
** registry.CLIBS[path] = plib        -- for queries
+
** registry.CLIBS[#CLIBS + 1] = plib  -- also keep a list of all libraries
+
*/
+
static void addtoclib (lua_State *L, const char *path, void *plib) {
+
  lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS);
+
  lua_pushlightuserdata(L, plib);
+
  lua_pushvalue(L, -1);
+
  lua_setfield(L, -3, path);  /* CLIBS[path] = plib */
+
  lua_rawseti(L, -2, luaL_len(L, -2) + 1);  /* CLIBS[#CLIBS + 1] = plib */
+
  lua_pop(L, 1);  /* pop CLIBS table */
+
}
+

+

+
/*
+
** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
+
** handles in list CLIBS
+
*/
+
static int gctm (lua_State *L) {
+
  lua_Integer n = luaL_len(L, 1);
+
  for (; n >= 1; n--) {  /* for each handle, in reverse order */
+
    lua_rawgeti(L, 1, n);  /* get handle CLIBS[n] */
+
    lsys_unloadlib(lua_touserdata(L, -1));
+
    lua_pop(L, 1);  /* pop handle */
+
  }
+
  return 0;
+
}
+

+

+

+
/* error codes for 'lookforfunc' */
+
#define ERRLIB		1
+
#define ERRFUNC		2
+

+
/*
+
** Look for a C function named 'sym' in a dynamically loaded library
+
** 'path'.
+
** First, check whether the library is already loaded; if not, try
+
** to load it.
+
** Then, if 'sym' is '*', return true (as library has been loaded).
+
** Otherwise, look for symbol 'sym' in the library and push a
+
** C function with that symbol.
+
** Return 0 and 'true' or a function in the stack; in case of
+
** errors, return an error code and an error message in the stack.
+
*/
+
static int lookforfunc (lua_State *L, const char *path, const char *sym) {
+
  void *reg = checkclib(L, path);  /* check loaded C libraries */
+
  if (reg == NULL) {  /* must load library? */
+
    reg = lsys_load(L, path, *sym == '*');  /* global symbols if 'sym'=='*' */
+
    if (reg == NULL) return ERRLIB;  /* unable to load library */
+
    addtoclib(L, path, reg);
+
  }
+
  if (*sym == '*') {  /* loading only library (no function)? */
+
    lua_pushboolean(L, 1);  /* return 'true' */
+
    return 0;  /* no errors */
+
  }
+
  else {
+
    lua_CFunction f = lsys_sym(L, reg, sym);
+
    if (f == NULL)
+
      return ERRFUNC;  /* unable to find function */
+
    lua_pushcfunction(L, f);  /* else create new function */
+
    return 0;  /* no errors */
+
  }
+
}
+

+

+
static int ll_loadlib (lua_State *L) {
+
  const char *path = luaL_checkstring(L, 1);
+
  const char *init = luaL_checkstring(L, 2);
+
  int stat = lookforfunc(L, path, init);
+
  if (stat == 0)  /* no errors? */
+
    return 1;  /* return the loaded function */
+
  else {  /* error; error message is on stack top */
+
    lua_pushnil(L);
+
    lua_insert(L, -2);
+
    lua_pushstring(L, (stat == ERRLIB) ?  LIB_FAIL : "init");
+
    return 3;  /* return nil, error message, and where */
+
  }
+
}
+

+

+

+
/*
+
** {======================================================
+
** 'require' function
+
** =======================================================
+
*/
+

+

+
static int readable (const char *filename) {
+
  FILE *f = fopen(filename, "r");  /* try to open file */
+
  if (f == NULL) return 0;  /* open failed */
+
  fclose(f);
+
  return 1;
+
}
+

+

+
static const char *pushnexttemplate (lua_State *L, const char *path) {
+
  const char *l;
+
  while (*path == *LUA_PATH_SEP) path++;  /* skip separators */
+
  if (*path == '\0') return NULL;  /* no more templates */
+
  l = strchr(path, *LUA_PATH_SEP);  /* find next separator */
+
  if (l == NULL) l = path + strlen(path);
+
  lua_pushlstring(L, path, l - path);  /* template */
+
  return l;
+
}
+

+

+
static const char *searchpath (lua_State *L, const char *name,
+
                                             const char *path,
+
                                             const char *sep,
+
                                             const char *dirsep) {
+
  luaL_Buffer msg;  /* to build error message */
+
  luaL_buffinit(L, &msg);
+
  if (*sep != '\0')  /* non-empty separator? */
+
    name = luaL_gsub(L, name, sep, dirsep);  /* replace it by 'dirsep' */
+
  while ((path = pushnexttemplate(L, path)) != NULL) {
+
    const char *filename = luaL_gsub(L, lua_tostring(L, -1),
+
                                     LUA_PATH_MARK, name);
+
    lua_remove(L, -2);  /* remove path template */
+
    if (readable(filename))  /* does file exist and is readable? */
+
      return filename;  /* return that file name */
+
    lua_pushfstring(L, "\n\tno file '%s'", filename);
+
    lua_remove(L, -2);  /* remove file name */
+
    luaL_addvalue(&msg);  /* concatenate error msg. entry */
+
  }
+
  luaL_pushresult(&msg);  /* create error message */
+
  return NULL;  /* not found */
+
}
+

+

+
static int ll_searchpath (lua_State *L) {
+
  const char *f = searchpath(L, luaL_checkstring(L, 1),
+
                                luaL_checkstring(L, 2),
+
                                luaL_optstring(L, 3, "."),
+
                                luaL_optstring(L, 4, LUA_DIRSEP));
+
  if (f != NULL) return 1;
+
  else {  /* error message is on top of the stack */
+
    lua_pushnil(L);
+
    lua_insert(L, -2);
+
    return 2;  /* return nil + error message */
+
  }
+
}
+

+

+
static const char *findfile (lua_State *L, const char *name,
+
                                           const char *pname,
+
                                           const char *dirsep) {
+
  const char *path;
+
  lua_getfield(L, lua_upvalueindex(1), pname);
+
  path = lua_tostring(L, -1);
+
  if (path == NULL)
+
    luaL_error(L, "'package.%s' must be a string", pname);
+
  return searchpath(L, name, path, ".", dirsep);
+
}
+

+

+
static int checkload (lua_State *L, int stat, const char *filename) {
+
  if (stat) {  /* module loaded successfully? */
+
    lua_pushstring(L, filename);  /* will be 2nd argument to module */
+
    return 2;  /* return open function and file name */
+
  }
+
  else
+
    return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s",
+
                          lua_tostring(L, 1), filename, lua_tostring(L, -1));
+
}
+

+

+
static int searcher_Lua (lua_State *L) {
+
  const char *filename;
+
  const char *name = luaL_checkstring(L, 1);
+
  filename = findfile(L, name, "path", LUA_LSUBSEP);
+
  if (filename == NULL) return 1;  /* module not found in this path */
+
  return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
+
}
+

+

+
/*
+
** Try to find a load function for module 'modname' at file 'filename'.
+
** First, change '.' to '_' in 'modname'; then, if 'modname' has
+
** the form X-Y (that is, it has an "ignore mark"), build a function
+
** name "luaopen_X" and look for it. (For compatibility, if that
+
** fails, it also tries "luaopen_Y".) If there is no ignore mark,
+
** look for a function named "luaopen_modname".
+
*/
+
static int loadfunc (lua_State *L, const char *filename, const char *modname) {
+
  const char *openfunc;
+
  const char *mark;
+
  modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
+
  mark = strchr(modname, *LUA_IGMARK);
+
  if (mark) {
+
    int stat;
+
    openfunc = lua_pushlstring(L, modname, mark - modname);
+
    openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc);
+
    stat = lookforfunc(L, filename, openfunc);
+
    if (stat != ERRFUNC) return stat;
+
    modname = mark + 1;  /* else go ahead and try old-style name */
+
  }
+
  openfunc = lua_pushfstring(L, LUA_POF"%s", modname);
+
  return lookforfunc(L, filename, openfunc);
+
}
+

+

+
static int searcher_C (lua_State *L) {
+
  const char *name = luaL_checkstring(L, 1);
+
  const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
+
  if (filename == NULL) return 1;  /* module not found in this path */
+
  return checkload(L, (loadfunc(L, filename, name) == 0), filename);
+
}
+

+

+
static int searcher_Croot (lua_State *L) {
+
  const char *filename;
+
  const char *name = luaL_checkstring(L, 1);
+
  const char *p = strchr(name, '.');
+
  int stat;
+
  if (p == NULL) return 0;  /* is root */
+
  lua_pushlstring(L, name, p - name);
+
  filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
+
  if (filename == NULL) return 1;  /* root not found */
+
  if ((stat = loadfunc(L, filename, name)) != 0) {
+
    if (stat != ERRFUNC)
+
      return checkload(L, 0, filename);  /* real error */
+
    else {  /* open function not found */
+
      lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename);
+
      return 1;
+
    }
+
  }
+
  lua_pushstring(L, filename);  /* will be 2nd argument to module */
+
  return 2;
+
}
+

+

+
static int searcher_preload (lua_State *L) {
+
  const char *name = luaL_checkstring(L, 1);
+
  lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
+
  if (lua_getfield(L, -1, name) == LUA_TNIL)  /* not found? */
+
    lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
+
  return 1;
+
}
+

+

+
static void findloader (lua_State *L, const char *name) {
+
  int i;
+
  luaL_Buffer msg;  /* to build error message */
+
  luaL_buffinit(L, &msg);
+
  /* push 'package.searchers' to index 3 in the stack */
+
  if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE)
+
    luaL_error(L, "'package.searchers' must be a table");
+
  /*  iterate over available searchers to find a loader */
+
  for (i = 1; ; i++) {
+
    if (lua_rawgeti(L, 3, i) == LUA_TNIL) {  /* no more searchers? */
+
      lua_pop(L, 1);  /* remove nil */
+
      luaL_pushresult(&msg);  /* create error message */
+
      luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
+
    }
+
    lua_pushstring(L, name);
+
    lua_call(L, 1, 2);  /* call it */
+
    if (lua_isfunction(L, -2))  /* did it find a loader? */
+
      return;  /* module loader found */
+
    else if (lua_isstring(L, -2)) {  /* searcher returned error message? */
+
      lua_pop(L, 1);  /* remove extra return */
+
      luaL_addvalue(&msg);  /* concatenate error message */
+
    }
+
    else
+
      lua_pop(L, 2);  /* remove both returns */
+
  }
+
}
+

+

+
static int ll_require (lua_State *L) {
+
  const char *name = luaL_checkstring(L, 1);
+
  lua_settop(L, 1);  /* LOADED table will be at index 2 */
+
  lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
+
  lua_getfield(L, 2, name);  /* LOADED[name] */
+
  if (lua_toboolean(L, -1))  /* is it there? */
+
    return 1;  /* package is already loaded */
+
  /* else must load package */
+
  lua_pop(L, 1);  /* remove 'getfield' result */
+
  findloader(L, name);
+
  lua_pushstring(L, name);  /* pass name as argument to module loader */
+
  lua_insert(L, -2);  /* name is 1st argument (before search data) */
+
  lua_call(L, 2, 1);  /* run loader to load module */
+
  if (!lua_isnil(L, -1))  /* non-nil return? */
+
    lua_setfield(L, 2, name);  /* LOADED[name] = returned value */
+
  if (lua_getfield(L, 2, name) == LUA_TNIL) {   /* module set no value? */
+
    lua_pushboolean(L, 1);  /* use true as result */
+
    lua_pushvalue(L, -1);  /* extra copy to be returned */
+
    lua_setfield(L, 2, name);  /* LOADED[name] = true */
+
  }
+
  return 1;
+
}
+

+
/* }====================================================== */
+

+

+

+
/*
+
** {======================================================
+
** 'module' function
+
** =======================================================
+
*/
+
#if defined(LUA_COMPAT_MODULE)
+

+
/*
+
** changes the environment variable of calling function
+
*/
+
static void set_env (lua_State *L) {
+
  lua_Debug ar;
+
  if (lua_getstack(L, 1, &ar) == 0 ||
+
      lua_getinfo(L, "f", &ar) == 0 ||  /* get calling function */
+
      lua_iscfunction(L, -1))
+
    luaL_error(L, "'module' not called from a Lua function");
+
  lua_pushvalue(L, -2);  /* copy new environment table to top */
+
  lua_setupvalue(L, -2, 1);
+
  lua_pop(L, 1);  /* remove function */
+
}
+

+

+
static void dooptions (lua_State *L, int n) {
+
  int i;
+
  for (i = 2; i <= n; i++) {
+
    if (lua_isfunction(L, i)) {  /* avoid 'calling' extra info. */
+
      lua_pushvalue(L, i);  /* get option (a function) */
+
      lua_pushvalue(L, -2);  /* module */
+
      lua_call(L, 1, 0);
+
    }
+
  }
+
}
+

+

+
static void modinit (lua_State *L, const char *modname) {
+
  const char *dot;
+
  lua_pushvalue(L, -1);
+
  lua_setfield(L, -2, "_M");  /* module._M = module */
+
  lua_pushstring(L, modname);
+
  lua_setfield(L, -2, "_NAME");
+
  dot = strrchr(modname, '.');  /* look for last dot in module name */
+
  if (dot == NULL) dot = modname;
+
  else dot++;
+
  /* set _PACKAGE as package name (full module name minus last part) */
+
  lua_pushlstring(L, modname, dot - modname);
+
  lua_setfield(L, -2, "_PACKAGE");
+
}
+

+

+
static int ll_module (lua_State *L) {
+
  const char *modname = luaL_checkstring(L, 1);
+
  int lastarg = lua_gettop(L);  /* last parameter */
+
  luaL_pushmodule(L, modname, 1);  /* get/create module table */
+
  /* check whether table already has a _NAME field */
+
  if (lua_getfield(L, -1, "_NAME") != LUA_TNIL)
+
    lua_pop(L, 1);  /* table is an initialized module */
+
  else {  /* no; initialize it */
+
    lua_pop(L, 1);
+
    modinit(L, modname);
+
  }
+
  lua_pushvalue(L, -1);
+
  set_env(L);
+
  dooptions(L, lastarg);
+
  return 1;
+
}
+

+

+
static int ll_seeall (lua_State *L) {
+
  luaL_checktype(L, 1, LUA_TTABLE);
+
  if (!lua_getmetatable(L, 1)) {
+
    lua_createtable(L, 0, 1); /* create new metatable */
+
    lua_pushvalue(L, -1);
+
    lua_setmetatable(L, 1);
+
  }
+
  lua_pushglobaltable(L);
+
  lua_setfield(L, -2, "__index");  /* mt.__index = _G */
+
  return 0;
+
}
+

+
#endif
+
/* }====================================================== */
+

+

+

+
static const luaL_Reg pk_funcs[] = {
+
  {"loadlib", ll_loadlib},
+
  {"searchpath", ll_searchpath},
+
#if defined(LUA_COMPAT_MODULE)
+
  {"seeall", ll_seeall},
+
#endif
+
  /* placeholders */
+
  {"preload", NULL},
+
  {"cpath", NULL},
+
  {"path", NULL},
+
  {"searchers", NULL},
+
  {"loaded", NULL},
+
  {NULL, NULL}
+
};
+

+

+
static const luaL_Reg ll_funcs[] = {
+
#if defined(LUA_COMPAT_MODULE)
+
  {"module", ll_module},
+
#endif
+
  {"require", ll_require},
+
  {NULL, NULL}
+
};
+

+

+
static void createsearcherstable (lua_State *L) {
+
  static const lua_CFunction searchers[] =
+
    {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
+
  int 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);
+
  }
+
#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 paths */
+
  setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT);
+
  setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
+
  /* store config information */
+
  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_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
+
  lua_setfield(L, -2, "loaded");
+
  /* set field 'preload' */
+
  luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
+
  lua_setfield(L, -2, "preload");
+
  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 */
+
}
+

added external/lua/src/lobject.c
@@ -0,0 +1,522 @@
+
/*
+
** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $
+
** Some generic functions over Lua objects
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lobject_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <locale.h>
+
#include <math.h>
+
#include <stdarg.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lctype.h"
+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "lvm.h"
+

+

+

+
LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
+

+

+
/*
+
** converts an integer to a "floating point byte", represented as
+
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
+
** eeeee != 0 and (xxx) otherwise.
+
*/
+
int luaO_int2fb (unsigned int x) {
+
  int e = 0;  /* exponent */
+
  if (x < 8) return x;
+
  while (x >= (8 << 4)) {  /* coarse steps */
+
    x = (x + 0xf) >> 4;  /* x = ceil(x / 16) */
+
    e += 4;
+
  }
+
  while (x >= (8 << 1)) {  /* fine steps */
+
    x = (x + 1) >> 1;  /* x = ceil(x / 2) */
+
    e++;
+
  }
+
  return ((e+1) << 3) | (cast_int(x) - 8);
+
}
+

+

+
/* converts back */
+
int luaO_fb2int (int x) {
+
  return (x < 8) ? x : ((x & 7) + 8) << ((x >> 3) - 1);
+
}
+

+

+
/*
+
** Computes ceil(log2(x))
+
*/
+
int luaO_ceillog2 (unsigned int x) {
+
  static const lu_byte log_2[256] = {  /* log_2[i] = ceil(log2(i - 1)) */
+
    0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+
    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+
    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+
    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+
    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+
  };
+
  int l = 0;
+
  x--;
+
  while (x >= 256) { l += 8; x >>= 8; }
+
  return l + log_2[x];
+
}
+

+

+
static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
+
                                                   lua_Integer v2) {
+
  switch (op) {
+
    case LUA_OPADD: return intop(+, v1, v2);
+
    case LUA_OPSUB:return intop(-, v1, v2);
+
    case LUA_OPMUL:return intop(*, v1, v2);
+
    case LUA_OPMOD: return luaV_mod(L, v1, v2);
+
    case LUA_OPIDIV: return luaV_div(L, v1, v2);
+
    case LUA_OPBAND: return intop(&, v1, v2);
+
    case LUA_OPBOR: return intop(|, v1, v2);
+
    case LUA_OPBXOR: return intop(^, v1, v2);
+
    case LUA_OPSHL: return luaV_shiftl(v1, v2);
+
    case LUA_OPSHR: return luaV_shiftl(v1, -v2);
+
    case LUA_OPUNM: return intop(-, 0, v1);
+
    case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1);
+
    default: lua_assert(0); return 0;
+
  }
+
}
+

+

+
static lua_Number numarith (lua_State *L, int op, lua_Number v1,
+
                                                  lua_Number v2) {
+
  switch (op) {
+
    case LUA_OPADD: return luai_numadd(L, v1, v2);
+
    case LUA_OPSUB: return luai_numsub(L, v1, v2);
+
    case LUA_OPMUL: return luai_nummul(L, v1, v2);
+
    case LUA_OPDIV: return luai_numdiv(L, v1, v2);
+
    case LUA_OPPOW: return luai_numpow(L, v1, v2);
+
    case LUA_OPIDIV: return luai_numidiv(L, v1, v2);
+
    case LUA_OPUNM: return luai_numunm(L, v1);
+
    case LUA_OPMOD: {
+
      lua_Number m;
+
      luai_nummod(L, v1, v2, m);
+
      return m;
+
    }
+
    default: lua_assert(0); return 0;
+
  }
+
}
+

+

+
void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
+
                 TValue *res) {
+
  switch (op) {
+
    case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
+
    case LUA_OPSHL: case LUA_OPSHR:
+
    case LUA_OPBNOT: {  /* operate only on integers */
+
      lua_Integer i1; lua_Integer i2;
+
      if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
+
        setivalue(res, intarith(L, op, i1, i2));
+
        return;
+
      }
+
      else break;  /* go to the end */
+
    }
+
    case LUA_OPDIV: case LUA_OPPOW: {  /* operate only on floats */
+
      lua_Number n1; lua_Number n2;
+
      if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
+
        setfltvalue(res, numarith(L, op, n1, n2));
+
        return;
+
      }
+
      else break;  /* go to the end */
+
    }
+
    default: {  /* other operations */
+
      lua_Number n1; lua_Number n2;
+
      if (ttisinteger(p1) && ttisinteger(p2)) {
+
        setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
+
        return;
+
      }
+
      else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
+
        setfltvalue(res, numarith(L, op, n1, n2));
+
        return;
+
      }
+
      else break;  /* go to the end */
+
    }
+
  }
+
  /* could not perform raw operation; try metamethod */
+
  lua_assert(L != NULL);  /* should not fail when folding (compile time) */
+
  luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
+
}
+

+

+
int luaO_hexavalue (int c) {
+
  if (lisdigit(c)) return c - '0';
+
  else return (ltolower(c) - 'a') + 10;
+
}
+

+

+
static int isneg (const char **s) {
+
  if (**s == '-') { (*s)++; return 1; }
+
  else if (**s == '+') (*s)++;
+
  return 0;
+
}
+

+

+

+
/*
+
** {==================================================================
+
** Lua's implementation for 'lua_strx2number'
+
** ===================================================================
+
*/
+

+
#if !defined(lua_strx2number)
+

+
/* maximum number of significant digits to read (to avoid overflows
+
   even with single floats) */
+
#define MAXSIGDIG	30
+

+
/*
+
** convert an hexadecimal numeric string to a number, following
+
** C99 specification for 'strtod'
+
*/
+
static lua_Number lua_strx2number (const char *s, char **endptr) {
+
  int dot = lua_getlocaledecpoint();
+
  lua_Number r = 0.0;  /* result (accumulator) */
+
  int sigdig = 0;  /* number of significant digits */
+
  int nosigdig = 0;  /* number of non-significant digits */
+
  int e = 0;  /* exponent correction */
+
  int neg;  /* 1 if number is negative */
+
  int hasdot = 0;  /* true after seen a dot */
+
  *endptr = cast(char *, s);  /* nothing is valid yet */
+
  while (lisspace(cast_uchar(*s))) s++;  /* skip initial spaces */
+
  neg = isneg(&s);  /* check signal */
+
  if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')))  /* check '0x' */
+
    return 0.0;  /* invalid format (no '0x') */
+
  for (s += 2; ; s++) {  /* skip '0x' and read numeral */
+
    if (*s == dot) {
+
      if (hasdot) break;  /* second dot? stop loop */
+
      else hasdot = 1;
+
    }
+
    else if (lisxdigit(cast_uchar(*s))) {
+
      if (sigdig == 0 && *s == '0')  /* non-significant digit (zero)? */
+
        nosigdig++;
+
      else if (++sigdig <= MAXSIGDIG)  /* can read it without overflow? */
+
          r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
+
      else e++; /* too many digits; ignore, but still count for exponent */
+
      if (hasdot) e--;  /* decimal digit? correct exponent */
+
    }
+
    else break;  /* neither a dot nor a digit */
+
  }
+
  if (nosigdig + sigdig == 0)  /* no digits? */
+
    return 0.0;  /* invalid format */
+
  *endptr = cast(char *, s);  /* valid up to here */
+
  e *= 4;  /* each digit multiplies/divides value by 2^4 */
+
  if (*s == 'p' || *s == 'P') {  /* exponent part? */
+
    int exp1 = 0;  /* exponent value */
+
    int neg1;  /* exponent signal */
+
    s++;  /* skip 'p' */
+
    neg1 = isneg(&s);  /* signal */
+
    if (!lisdigit(cast_uchar(*s)))
+
      return 0.0;  /* invalid; must have at least one digit */
+
    while (lisdigit(cast_uchar(*s)))  /* read exponent */
+
      exp1 = exp1 * 10 + *(s++) - '0';
+
    if (neg1) exp1 = -exp1;
+
    e += exp1;
+
    *endptr = cast(char *, s);  /* valid up to here */
+
  }
+
  if (neg) r = -r;
+
  return l_mathop(ldexp)(r, e);
+
}
+

+
#endif
+
/* }====================================================== */
+

+

+
/* maximum length of a numeral */
+
#if !defined (L_MAXLENNUM)
+
#define L_MAXLENNUM	200
+
#endif
+

+
static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
+
  char *endptr;
+
  *result = (mode == 'x') ? lua_strx2number(s, &endptr)  /* try to convert */
+
                          : lua_str2number(s, &endptr);
+
  if (endptr == s) return NULL;  /* nothing recognized? */
+
  while (lisspace(cast_uchar(*endptr))) endptr++;  /* skip trailing spaces */
+
  return (*endptr == '\0') ? endptr : NULL;  /* OK if no trailing characters */
+
}
+

+

+
/*
+
** Convert string 's' to a Lua number (put in 'result'). Return NULL
+
** on fail or the address of the ending '\0' on success.
+
** 'pmode' points to (and 'mode' contains) special things in the string:
+
** - 'x'/'X' means an hexadecimal numeral
+
** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
+
** - '.' just optimizes the search for the common case (nothing special)
+
** 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
+
** locale accepts something else. In that case, the code copies 's'
+
** to a buffer (because 's' is read-only), changes the dot to the
+
** current locale radix mark, and tries to convert again.
+
*/
+
static const char *l_str2d (const char *s, lua_Number *result) {
+
  const char *endptr;
+
  const char *pmode = strpbrk(s, ".xXnN");
+
  int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
+
  if (mode == 'n')  /* reject 'inf' and 'nan' */
+
    return NULL;
+
  endptr = l_str2dloc(s, result, mode);  /* try to convert */
+
  if (endptr == NULL) {  /* failed? may be a different locale */
+
    char buff[L_MAXLENNUM + 1];
+
    const char *pdot = strchr(s, '.');
+
    if (strlen(s) > L_MAXLENNUM || pdot == NULL)
+
      return NULL;  /* string too long or no dot; fail */
+
    strcpy(buff, s);  /* copy string to buffer */
+
    buff[pdot - s] = lua_getlocaledecpoint();  /* correct decimal point */
+
    endptr = l_str2dloc(buff, result, mode);  /* try again */
+
    if (endptr != NULL)
+
      endptr = s + (endptr - buff);  /* make relative to 's' */
+
  }
+
  return endptr;
+
}
+

+

+
#define MAXBY10		cast(lua_Unsigned, LUA_MAXINTEGER / 10)
+
#define MAXLASTD	cast_int(LUA_MAXINTEGER % 10)
+

+
static const char *l_str2int (const char *s, lua_Integer *result) {
+
  lua_Unsigned a = 0;
+
  int empty = 1;
+
  int neg;
+
  while (lisspace(cast_uchar(*s))) s++;  /* skip initial spaces */
+
  neg = isneg(&s);
+
  if (s[0] == '0' &&
+
      (s[1] == 'x' || s[1] == 'X')) {  /* hex? */
+
    s += 2;  /* skip '0x' */
+
    for (; lisxdigit(cast_uchar(*s)); s++) {
+
      a = a * 16 + luaO_hexavalue(*s);
+
      empty = 0;
+
    }
+
  }
+
  else {  /* decimal */
+
    for (; lisdigit(cast_uchar(*s)); s++) {
+
      int d = *s - '0';
+
      if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg))  /* overflow? */
+
        return NULL;  /* do not accept it (as integer) */
+
      a = a * 10 + d;
+
      empty = 0;
+
    }
+
  }
+
  while (lisspace(cast_uchar(*s))) s++;  /* skip trailing spaces */
+
  if (empty || *s != '\0') return NULL;  /* something wrong in the numeral */
+
  else {
+
    *result = l_castU2S((neg) ? 0u - a : a);
+
    return s;
+
  }
+
}
+

+

+
size_t luaO_str2num (const char *s, TValue *o) {
+
  lua_Integer i; lua_Number n;
+
  const char *e;
+
  if ((e = l_str2int(s, &i)) != NULL) {  /* try as an integer */
+
    setivalue(o, i);
+
  }
+
  else if ((e = l_str2d(s, &n)) != NULL) {  /* else try as a float */
+
    setfltvalue(o, n);
+
  }
+
  else
+
    return 0;  /* conversion failed */
+
  return (e - s) + 1;  /* success; return string size */
+
}
+

+

+
int luaO_utf8esc (char *buff, unsigned long x) {
+
  int n = 1;  /* number of bytes put in buffer (backwards) */
+
  lua_assert(x <= 0x10FFFF);
+
  if (x < 0x80)  /* ascii? */
+
    buff[UTF8BUFFSZ - 1] = cast(char, x);
+
  else {  /* need continuation bytes */
+
    unsigned int mfb = 0x3f;  /* maximum that fits in first byte */
+
    do {  /* add continuation bytes */
+
      buff[UTF8BUFFSZ - (n++)] = cast(char, 0x80 | (x & 0x3f));
+
      x >>= 6;  /* remove added bits */
+
      mfb >>= 1;  /* now there is one less bit available in first byte */
+
    } while (x > mfb);  /* still needs continuation byte? */
+
    buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x);  /* add first byte */
+
  }
+
  return n;
+
}
+

+

+
/* maximum length of the conversion of a number to a string */
+
#define MAXNUMBER2STR	50
+

+

+
/*
+
** Convert a number object to a string
+
*/
+
void luaO_tostring (lua_State *L, StkId obj) {
+
  char buff[MAXNUMBER2STR];
+
  size_t len;
+
  lua_assert(ttisnumber(obj));
+
  if (ttisinteger(obj))
+
    len = lua_integer2str(buff, sizeof(buff), ivalue(obj));
+
  else {
+
    len = lua_number2str(buff, sizeof(buff), fltvalue(obj));
+
#if !defined(LUA_COMPAT_FLOATSTRING)
+
    if (buff[strspn(buff, "-0123456789")] == '\0') {  /* looks like an int? */
+
      buff[len++] = lua_getlocaledecpoint();
+
      buff[len++] = '0';  /* adds '.0' to result */
+
    }
+
#endif
+
  }
+
  setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
+
}
+

+

+
static void pushstr (lua_State *L, const char *str, size_t l) {
+
  setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
+
  luaD_inctop(L);
+
}
+

+

+
/*
+
** this function handles only '%d', '%c', '%f', '%p', and '%s'
+
   conventional formats, plus Lua-specific '%I' and '%U'
+
*/
+
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
+
  int n = 0;
+
  for (;;) {
+
    const char *e = strchr(fmt, '%');
+
    if (e == NULL) break;
+
    pushstr(L, fmt, e - fmt);
+
    switch (*(e+1)) {
+
      case 's': {  /* zero-terminated string */
+
        const char *s = va_arg(argp, char *);
+
        if (s == NULL) s = "(null)";
+
        pushstr(L, s, strlen(s));
+
        break;
+
      }
+
      case 'c': {  /* an 'int' as a character */
+
        char buff = cast(char, va_arg(argp, int));
+
        if (lisprint(cast_uchar(buff)))
+
          pushstr(L, &buff, 1);
+
        else  /* non-printable character; print its code */
+
          luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
+
        break;
+
      }
+
      case 'd': {  /* an 'int' */
+
        setivalue(L->top, va_arg(argp, int));
+
        goto top2str;
+
      }
+
      case 'I': {  /* a 'lua_Integer' */
+
        setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
+
        goto top2str;
+
      }
+
      case 'f': {  /* a 'lua_Number' */
+
        setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
+
      top2str:  /* convert the top element to a string */
+
        luaD_inctop(L);
+
        luaO_tostring(L, L->top - 1);
+
        break;
+
      }
+
      case 'p': {  /* a pointer */
+
        char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
+
        void *p = va_arg(argp, void *);
+
        int l = lua_pointer2str(buff, sizeof(buff), p);
+
        pushstr(L, buff, l);
+
        break;
+
      }
+
      case 'U': {  /* an 'int' as a UTF-8 sequence */
+
        char buff[UTF8BUFFSZ];
+
        int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
+
        pushstr(L, buff + UTF8BUFFSZ - l, l);
+
        break;
+
      }
+
      case '%': {
+
        pushstr(L, "%", 1);
+
        break;
+
      }
+
      default: {
+
        luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'",
+
                         *(e + 1));
+
      }
+
    }
+
    n += 2;
+
    fmt = e+2;
+
  }
+
  luaD_checkstack(L, 1);
+
  pushstr(L, fmt, strlen(fmt));
+
  if (n > 0) luaV_concat(L, n + 1);
+
  return svalue(L->top - 1);
+
}
+

+

+
const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
+
  const char *msg;
+
  va_list argp;
+
  va_start(argp, fmt);
+
  msg = luaO_pushvfstring(L, fmt, argp);
+
  va_end(argp);
+
  return msg;
+
}
+

+

+
/* number of chars of a literal string without the ending \0 */
+
#define LL(x)	(sizeof(x)/sizeof(char) - 1)
+

+
#define RETS	"..."
+
#define PRE	"[string \""
+
#define POS	"\"]"
+

+
#define addstr(a,b,l)	( memcpy(a,b,(l) * sizeof(char)), a += (l) )
+

+
void luaO_chunkid (char *out, const char *source, size_t bufflen) {
+
  size_t l = strlen(source);
+
  if (*source == '=') {  /* 'literal' source */
+
    if (l <= bufflen)  /* small enough? */
+
      memcpy(out, source + 1, l * sizeof(char));
+
    else {  /* truncate it */
+
      addstr(out, source + 1, bufflen - 1);
+
      *out = '\0';
+
    }
+
  }
+
  else if (*source == '@') {  /* file name */
+
    if (l <= bufflen)  /* small enough? */
+
      memcpy(out, source + 1, l * sizeof(char));
+
    else {  /* add '...' before rest of name */
+
      addstr(out, RETS, LL(RETS));
+
      bufflen -= LL(RETS);
+
      memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
+
    }
+
  }
+
  else {  /* string; format as [string "source"] */
+
    const char *nl = strchr(source, '\n');  /* find first new line (if any) */
+
    addstr(out, PRE, LL(PRE));  /* add prefix */
+
    bufflen -= LL(PRE RETS POS) + 1;  /* save space for prefix+suffix+'\0' */
+
    if (l < bufflen && nl == NULL) {  /* small one-line source? */
+
      addstr(out, source, l);  /* keep it */
+
    }
+
    else {
+
      if (nl != NULL) l = nl - source;  /* stop at first newline */
+
      if (l > bufflen) l = bufflen;
+
      addstr(out, source, l);
+
      addstr(out, RETS, LL(RETS));
+
    }
+
    memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
+
  }
+
}
+

added external/lua/src/lobject.h
@@ -0,0 +1,549 @@
+
/*
+
** $Id: lobject.h,v 2.117.1.1 2017/04/19 17:39:34 roberto Exp $
+
** Type definitions for Lua objects
+
** See Copyright Notice in lua.h
+
*/
+

+

+
#ifndef lobject_h
+
#define lobject_h
+

+

+
#include <stdarg.h>
+

+

+
#include "llimits.h"
+
#include "lua.h"
+

+

+
/*
+
** Extra tags for non-values
+
*/
+
#define LUA_TPROTO	LUA_NUMTAGS		/* function prototypes */
+
#define LUA_TDEADKEY	(LUA_NUMTAGS+1)		/* removed keys in tables */
+

+
/*
+
** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
+
*/
+
#define LUA_TOTALTAGS	(LUA_TPROTO + 2)
+

+

+
/*
+
** tags for Tagged Values have the following use of bits:
+
** bits 0-3: actual tag (a LUA_T* value)
+
** bits 4-5: variant bits
+
** bit 6: whether value is collectable
+
*/
+

+

+
/*
+
** LUA_TFUNCTION variants:
+
** 0 - Lua function
+
** 1 - light C function
+
** 2 - regular C function (closure)
+
*/
+

+
/* Variant tags for functions */
+
#define LUA_TLCL	(LUA_TFUNCTION | (0 << 4))  /* Lua closure */
+
#define LUA_TLCF	(LUA_TFUNCTION | (1 << 4))  /* light C function */
+
#define LUA_TCCL	(LUA_TFUNCTION | (2 << 4))  /* C closure */
+

+

+
/* Variant tags for strings */
+
#define LUA_TSHRSTR	(LUA_TSTRING | (0 << 4))  /* short strings */
+
#define LUA_TLNGSTR	(LUA_TSTRING | (1 << 4))  /* long strings */
+

+

+
/* Variant tags for numbers */
+
#define LUA_TNUMFLT	(LUA_TNUMBER | (0 << 4))  /* float numbers */
+
#define LUA_TNUMINT	(LUA_TNUMBER | (1 << 4))  /* integer numbers */
+

+

+
/* Bit mark for collectable types */
+
#define BIT_ISCOLLECTABLE	(1 << 6)
+

+
/* mark a tag as collectable */
+
#define ctb(t)			((t) | BIT_ISCOLLECTABLE)
+

+

+
/*
+
** Common type for all collectable objects
+
*/
+
typedef struct GCObject GCObject;
+

+

+
/*
+
** Common Header for all collectable objects (in macro form, to be
+
** included in other objects)
+
*/
+
#define CommonHeader	GCObject *next; lu_byte tt; lu_byte marked
+

+

+
/*
+
** Common type has only the common header
+
*/
+
struct GCObject {
+
  CommonHeader;
+
};
+

+

+

+

+
/*
+
** Tagged Values. This is the basic representation of values in Lua,
+
** an actual value plus a tag with its type.
+
*/
+

+
/*
+
** Union of all Lua values
+
*/
+
typedef union Value {
+
  GCObject *gc;    /* collectable objects */
+
  void *p;         /* light userdata */
+
  int b;           /* booleans */
+
  lua_CFunction f; /* light C functions */
+
  lua_Integer i;   /* integer numbers */
+
  lua_Number n;    /* float numbers */
+
} Value;
+

+

+
#define TValuefields	Value value_; int tt_
+

+

+
typedef struct lua_TValue {
+
  TValuefields;
+
} TValue;
+

+

+

+
/* macro defining a nil value */
+
#define NILCONSTANT	{NULL}, LUA_TNIL
+

+

+
#define val_(o)		((o)->value_)
+

+

+
/* raw type tag of a TValue */
+
#define rttype(o)	((o)->tt_)
+

+
/* tag with no variants (bits 0-3) */
+
#define novariant(x)	((x) & 0x0F)
+

+
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
+
#define ttype(o)	(rttype(o) & 0x3F)
+

+
/* type tag of a TValue with no variants (bits 0-3) */
+
#define ttnov(o)	(novariant(rttype(o)))
+

+

+
/* Macros to test type */
+
#define checktag(o,t)		(rttype(o) == (t))
+
#define checktype(o,t)		(ttnov(o) == (t))
+
#define ttisnumber(o)		checktype((o), LUA_TNUMBER)
+
#define ttisfloat(o)		checktag((o), LUA_TNUMFLT)
+
#define ttisinteger(o)		checktag((o), LUA_TNUMINT)
+
#define ttisnil(o)		checktag((o), LUA_TNIL)
+
#define ttisboolean(o)		checktag((o), LUA_TBOOLEAN)
+
#define ttislightuserdata(o)	checktag((o), LUA_TLIGHTUSERDATA)
+
#define ttisstring(o)		checktype((o), LUA_TSTRING)
+
#define ttisshrstring(o)	checktag((o), ctb(LUA_TSHRSTR))
+
#define ttislngstring(o)	checktag((o), ctb(LUA_TLNGSTR))
+
#define ttistable(o)		checktag((o), ctb(LUA_TTABLE))
+
#define ttisfunction(o)		checktype(o, LUA_TFUNCTION)
+
#define ttisclosure(o)		((rttype(o) & 0x1F) == LUA_TFUNCTION)
+
#define ttisCclosure(o)		checktag((o), ctb(LUA_TCCL))
+
#define ttisLclosure(o)		checktag((o), ctb(LUA_TLCL))
+
#define ttislcf(o)		checktag((o), LUA_TLCF)
+
#define ttisfulluserdata(o)	checktag((o), ctb(LUA_TUSERDATA))
+
#define ttisthread(o)		checktag((o), ctb(LUA_TTHREAD))
+
#define ttisdeadkey(o)		checktag((o), LUA_TDEADKEY)
+

+

+
/* Macros to access values */
+
#define ivalue(o)	check_exp(ttisinteger(o), val_(o).i)
+
#define fltvalue(o)	check_exp(ttisfloat(o), val_(o).n)
+
#define nvalue(o)	check_exp(ttisnumber(o), \
+
	(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
+
#define gcvalue(o)	check_exp(iscollectable(o), val_(o).gc)
+
#define pvalue(o)	check_exp(ttislightuserdata(o), val_(o).p)
+
#define tsvalue(o)	check_exp(ttisstring(o), gco2ts(val_(o).gc))
+
#define uvalue(o)	check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
+
#define clvalue(o)	check_exp(ttisclosure(o), gco2cl(val_(o).gc))
+
#define clLvalue(o)	check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
+
#define clCvalue(o)	check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
+
#define fvalue(o)	check_exp(ttislcf(o), val_(o).f)
+
#define hvalue(o)	check_exp(ttistable(o), gco2t(val_(o).gc))
+
#define bvalue(o)	check_exp(ttisboolean(o), val_(o).b)
+
#define thvalue(o)	check_exp(ttisthread(o), gco2th(val_(o).gc))
+
/* a dead value may get the 'gc' field, but cannot access its contents */
+
#define deadvalue(o)	check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
+

+
#define l_isfalse(o)	(ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
+

+

+
#define iscollectable(o)	(rttype(o) & BIT_ISCOLLECTABLE)
+

+

+
/* Macros for internal tests */
+
#define righttt(obj)		(ttype(obj) == gcvalue(obj)->tt)
+

+
#define checkliveness(L,obj) \
+
	lua_longassert(!iscollectable(obj) || \
+
		(righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)))))
+

+

+
/* Macros to set values */
+
#define settt_(o,t)	((o)->tt_=(t))
+

+
#define setfltvalue(obj,x) \
+
  { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
+

+
#define chgfltvalue(obj,x) \
+
  { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); }
+

+
#define setivalue(obj,x) \
+
  { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
+

+
#define chgivalue(obj,x) \
+
  { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); }
+

+
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
+

+
#define setfvalue(obj,x) \
+
  { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
+

+
#define setpvalue(obj,x) \
+
  { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
+

+
#define setbvalue(obj,x) \
+
  { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
+

+
#define setgcovalue(L,obj,x) \
+
  { TValue *io = (obj); GCObject *i_g=(x); \
+
    val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }
+

+
#define setsvalue(L,obj,x) \
+
  { TValue *io = (obj); TString *x_ = (x); \
+
    val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
+
    checkliveness(L,io); }
+

+
#define setuvalue(L,obj,x) \
+
  { TValue *io = (obj); Udata *x_ = (x); \
+
    val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \
+
    checkliveness(L,io); }
+

+
#define setthvalue(L,obj,x) \
+
  { TValue *io = (obj); lua_State *x_ = (x); \
+
    val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \
+
    checkliveness(L,io); }
+

+
#define setclLvalue(L,obj,x) \
+
  { TValue *io = (obj); LClosure *x_ = (x); \
+
    val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \
+
    checkliveness(L,io); }
+

+
#define setclCvalue(L,obj,x) \
+
  { TValue *io = (obj); CClosure *x_ = (x); \
+
    val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \
+
    checkliveness(L,io); }
+

+
#define sethvalue(L,obj,x) \
+
  { TValue *io = (obj); Table *x_ = (x); \
+
    val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \
+
    checkliveness(L,io); }
+

+
#define setdeadvalue(obj)	settt_(obj, LUA_TDEADKEY)
+

+

+

+
#define setobj(L,obj1,obj2) \
+
	{ TValue *io1=(obj1); *io1 = *(obj2); \
+
	  (void)L; checkliveness(L,io1); }
+

+

+
/*
+
** different types of assignments, according to destination
+
*/
+

+
/* from stack to (same) stack */
+
#define setobjs2s	setobj
+
/* to stack (not from same stack) */
+
#define setobj2s	setobj
+
#define setsvalue2s	setsvalue
+
#define sethvalue2s	sethvalue
+
#define setptvalue2s	setptvalue
+
/* from table to same table */
+
#define setobjt2t	setobj
+
/* to new object */
+
#define setobj2n	setobj
+
#define setsvalue2n	setsvalue
+

+
/* to table (define it as an expression to be used in macros) */
+
#define setobj2t(L,o1,o2)  ((void)L, *(o1)=*(o2), checkliveness(L,(o1)))
+

+

+

+

+
/*
+
** {======================================================
+
** types and prototypes
+
** =======================================================
+
*/
+

+

+
typedef TValue *StkId;  /* index to stack elements */
+

+

+

+

+
/*
+
** Header for string value; string bytes follow the end of this structure
+
** (aligned according to 'UTString'; see next).
+
*/
+
typedef struct TString {
+
  CommonHeader;
+
  lu_byte extra;  /* reserved words for short strings; "has hash" for longs */
+
  lu_byte shrlen;  /* length for short strings */
+
  unsigned int hash;
+
  union {
+
    size_t lnglen;  /* length for long strings */
+
    struct TString *hnext;  /* linked list for hash table */
+
  } u;
+
} TString;
+

+

+
/*
+
** Ensures that address after this type is always fully aligned.
+
*/
+
typedef union UTString {
+
  L_Umaxalign dummy;  /* ensures maximum alignment for strings */
+
  TString tsv;
+
} UTString;
+

+

+
/*
+
** Get the actual string (array of bytes) from a 'TString'.
+
** (Access to 'extra' ensures that value is really a 'TString'.)
+
*/
+
#define getstr(ts)  \
+
  check_exp(sizeof((ts)->extra), cast(char *, (ts)) + sizeof(UTString))
+

+

+
/* get the actual string (array of bytes) from a Lua value */
+
#define svalue(o)       getstr(tsvalue(o))
+

+
/* get string length from 'TString *s' */
+
#define tsslen(s)	((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)
+

+
/* get string length from 'TValue *o' */
+
#define vslen(o)	tsslen(tsvalue(o))
+

+

+
/*
+
** Header for userdata; memory area follows the end of this structure
+
** (aligned according to 'UUdata'; see next).
+
*/
+
typedef struct Udata {
+
  CommonHeader;
+
  lu_byte ttuv_;  /* user value's tag */
+
  struct Table *metatable;
+
  size_t len;  /* number of bytes */
+
  union Value user_;  /* user value */
+
} Udata;
+

+

+
/*
+
** Ensures that address after this type is always fully aligned.
+
*/
+
typedef union UUdata {
+
  L_Umaxalign dummy;  /* ensures maximum alignment for 'local' udata */
+
  Udata uv;
+
} UUdata;
+

+

+
/*
+
**  Get the address of memory block inside 'Udata'.
+
** (Access to 'ttuv_' ensures that value is really a 'Udata'.)
+
*/
+
#define getudatamem(u)  \
+
  check_exp(sizeof((u)->ttuv_), (cast(char*, (u)) + sizeof(UUdata)))
+

+
#define setuservalue(L,u,o) \
+
	{ const TValue *io=(o); Udata *iu = (u); \
+
	  iu->user_ = io->value_; iu->ttuv_ = rttype(io); \
+
	  checkliveness(L,io); }
+

+

+
#define getuservalue(L,u,o) \
+
	{ TValue *io=(o); const Udata *iu = (u); \
+
	  io->value_ = iu->user_; settt_(io, iu->ttuv_); \
+
	  checkliveness(L,io); }
+

+

+
/*
+
** Description of an upvalue for function prototypes
+
*/
+
typedef struct Upvaldesc {
+
  TString *name;  /* upvalue name (for debug information) */
+
  lu_byte instack;  /* whether it is in stack (register) */
+
  lu_byte idx;  /* index of upvalue (in stack or in outer function's list) */
+
} Upvaldesc;
+

+

+
/*
+
** Description of a local variable for function prototypes
+
** (used for debug information)
+
*/
+
typedef struct LocVar {
+
  TString *varname;
+
  int startpc;  /* first point where variable is active */
+
  int endpc;    /* first point where variable is dead */
+
} LocVar;
+

+

+
/*
+
** Function Prototypes
+
*/
+
typedef struct Proto {
+
  CommonHeader;
+
  lu_byte numparams;  /* number of fixed parameters */
+
  lu_byte is_vararg;
+
  lu_byte maxstacksize;  /* number of registers needed by this function */
+
  int sizeupvalues;  /* size of 'upvalues' */
+
  int sizek;  /* size of 'k' */
+
  int sizecode;
+
  int sizelineinfo;
+
  int sizep;  /* size of 'p' */
+
  int sizelocvars;
+
  int linedefined;  /* debug information  */
+
  int lastlinedefined;  /* debug information  */
+
  TValue *k;  /* constants used by the function */
+
  Instruction *code;  /* opcodes */
+
  struct Proto **p;  /* functions defined inside the function */
+
  int *lineinfo;  /* map from opcodes to source lines (debug information) */
+
  LocVar *locvars;  /* information about local variables (debug information) */
+
  Upvaldesc *upvalues;  /* upvalue information */
+
  struct LClosure *cache;  /* last-created closure with this prototype */
+
  TString  *source;  /* used for debug information */
+
  GCObject *gclist;
+
} Proto;
+

+

+

+
/*
+
** Lua Upvalues
+
*/
+
typedef struct UpVal UpVal;
+

+

+
/*
+
** Closures
+
*/
+

+
#define ClosureHeader \
+
	CommonHeader; lu_byte nupvalues; GCObject *gclist
+

+
typedef struct CClosure {
+
  ClosureHeader;
+
  lua_CFunction f;
+
  TValue upvalue[1];  /* list of upvalues */
+
} CClosure;
+

+

+
typedef struct LClosure {
+
  ClosureHeader;
+
  struct Proto *p;
+
  UpVal *upvals[1];  /* list of upvalues */
+
} LClosure;
+

+

+
typedef union Closure {
+
  CClosure c;
+
  LClosure l;
+
} Closure;
+

+

+
#define isLfunction(o)	ttisLclosure(o)
+

+
#define getproto(o)	(clLvalue(o)->p)
+

+

+
/*
+
** Tables
+
*/
+

+
typedef union TKey {
+
  struct {
+
    TValuefields;
+
    int next;  /* for chaining (offset for next node) */
+
  } nk;
+
  TValue tvk;
+
} TKey;
+

+

+
/* copy a value into a key without messing up field 'next' */
+
#define setnodekey(L,key,obj) \
+
	{ TKey *k_=(key); const TValue *io_=(obj); \
+
	  k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \
+
	  (void)L; checkliveness(L,io_); }
+

+

+
typedef struct Node {
+
  TValue i_val;
+
  TKey i_key;
+
} Node;
+

+

+
typedef struct Table {
+
  CommonHeader;
+
  lu_byte flags;  /* 1<<p means tagmethod(p) is not present */
+
  lu_byte lsizenode;  /* log2 of size of 'node' array */
+
  unsigned int sizearray;  /* size of 'array' array */
+
  TValue *array;  /* array part */
+
  Node *node;
+
  Node *lastfree;  /* any free position is before this position */
+
  struct Table *metatable;
+
  GCObject *gclist;
+
} Table;
+

+

+

+
/*
+
** 'module' operation for hashing (size is always a power of 2)
+
*/
+
#define lmod(s,size) \
+
	(check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
+

+

+
#define twoto(x)	(1<<(x))
+
#define sizenode(t)	(twoto((t)->lsizenode))
+

+

+
/*
+
** (address of) a fixed nil value
+
*/
+
#define luaO_nilobject		(&luaO_nilobject_)
+

+

+
LUAI_DDEC const TValue luaO_nilobject_;
+

+
/* size of buffer for 'luaO_utf8esc' function */
+
#define UTF8BUFFSZ	8
+

+
LUAI_FUNC int luaO_int2fb (unsigned int x);
+
LUAI_FUNC int luaO_fb2int (int x);
+
LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x);
+
LUAI_FUNC int luaO_ceillog2 (unsigned int x);
+
LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
+
                           const TValue *p2, TValue *res);
+
LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o);
+
LUAI_FUNC int luaO_hexavalue (int c);
+
LUAI_FUNC void luaO_tostring (lua_State *L, StkId obj);
+
LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
+
                                                       va_list argp);
+
LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
+
LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
+

+

+
#endif
+

added external/lua/src/lopcodes.c
@@ -0,0 +1,124 @@
+
/*
+
** $Id: lopcodes.c,v 1.55.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Opcodes for Lua virtual machine
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lopcodes_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <stddef.h>
+

+
#include "lopcodes.h"
+

+

+
/* ORDER OP */
+

+
LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
+
  "MOVE",
+
  "LOADK",
+
  "LOADKX",
+
  "LOADBOOL",
+
  "LOADNIL",
+
  "GETUPVAL",
+
  "GETTABUP",
+
  "GETTABLE",
+
  "SETTABUP",
+
  "SETUPVAL",
+
  "SETTABLE",
+
  "NEWTABLE",
+
  "SELF",
+
  "ADD",
+
  "SUB",
+
  "MUL",
+
  "MOD",
+
  "POW",
+
  "DIV",
+
  "IDIV",
+
  "BAND",
+
  "BOR",
+
  "BXOR",
+
  "SHL",
+
  "SHR",
+
  "UNM",
+
  "BNOT",
+
  "NOT",
+
  "LEN",
+
  "CONCAT",
+
  "JMP",
+
  "EQ",
+
  "LT",
+
  "LE",
+
  "TEST",
+
  "TESTSET",
+
  "CALL",
+
  "TAILCALL",
+
  "RETURN",
+
  "FORLOOP",
+
  "FORPREP",
+
  "TFORCALL",
+
  "TFORLOOP",
+
  "SETLIST",
+
  "CLOSURE",
+
  "VARARG",
+
  "EXTRAARG",
+
  NULL
+
};
+

+

+
#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
+

+
LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
+
/*       T  A    B       C     mode		   opcode	*/
+
  opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_MOVE */
+
 ,opmode(0, 1, OpArgK, OpArgN, iABx)		/* OP_LOADK */
+
 ,opmode(0, 1, OpArgN, OpArgN, iABx)		/* OP_LOADKX */
+
 ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_LOADBOOL */
+
 ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_LOADNIL */
+
 ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_GETUPVAL */
+
 ,opmode(0, 1, OpArgU, OpArgK, iABC)		/* OP_GETTABUP */
+
 ,opmode(0, 1, OpArgR, OpArgK, iABC)		/* OP_GETTABLE */
+
 ,opmode(0, 0, OpArgK, OpArgK, iABC)		/* OP_SETTABUP */
+
 ,opmode(0, 0, OpArgU, OpArgN, iABC)		/* OP_SETUPVAL */
+
 ,opmode(0, 0, OpArgK, OpArgK, iABC)		/* OP_SETTABLE */
+
 ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_NEWTABLE */
+
 ,opmode(0, 1, OpArgR, OpArgK, iABC)		/* OP_SELF */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_ADD */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_SUB */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_MUL */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_MOD */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_POW */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_DIV */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_IDIV */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_BAND */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_BOR */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_BXOR */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_SHL */
+
 ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_SHR */
+
 ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_UNM */
+
 ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_BNOT */
+
 ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_NOT */
+
 ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_LEN */
+
 ,opmode(0, 1, OpArgR, OpArgR, iABC)		/* OP_CONCAT */
+
 ,opmode(0, 0, OpArgR, OpArgN, iAsBx)		/* OP_JMP */
+
 ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_EQ */
+
 ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_LT */
+
 ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_LE */
+
 ,opmode(1, 0, OpArgN, OpArgU, iABC)		/* OP_TEST */
+
 ,opmode(1, 1, OpArgR, OpArgU, iABC)		/* OP_TESTSET */
+
 ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_CALL */
+
 ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_TAILCALL */
+
 ,opmode(0, 0, OpArgU, OpArgN, iABC)		/* OP_RETURN */
+
 ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_FORLOOP */
+
 ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_FORPREP */
+
 ,opmode(0, 0, OpArgN, OpArgU, iABC)		/* OP_TFORCALL */
+
 ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_TFORLOOP */
+
 ,opmode(0, 0, OpArgU, OpArgU, iABC)		/* OP_SETLIST */
+
 ,opmode(0, 1, OpArgU, OpArgN, iABx)		/* OP_CLOSURE */
+
 ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_VARARG */
+
 ,opmode(0, 0, OpArgU, OpArgU, iAx)		/* OP_EXTRAARG */
+
};
+

added external/lua/src/lopcodes.h
@@ -0,0 +1,297 @@
+
/*
+
** $Id: lopcodes.h,v 1.149.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Opcodes for Lua virtual machine
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lopcodes_h
+
#define lopcodes_h
+

+
#include "llimits.h"
+

+

+
/*===========================================================================
+
  We assume that instructions are unsigned numbers.
+
  All instructions have an opcode in the first 6 bits.
+
  Instructions can have the following fields:
+
	'A' : 8 bits
+
	'B' : 9 bits
+
	'C' : 9 bits
+
	'Ax' : 26 bits ('A', 'B', and 'C' together)
+
	'Bx' : 18 bits ('B' and 'C' together)
+
	'sBx' : signed Bx
+

+
  A signed argument is represented in excess K; that is, the number
+
  value is the unsigned value minus K. K is exactly the maximum value
+
  for that argument (so that -max is represented by 0, and +max is
+
  represented by 2*max), which is half the maximum for the corresponding
+
  unsigned argument.
+
===========================================================================*/
+

+

+
enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
+

+

+
/*
+
** size and position of opcode arguments.
+
*/
+
#define SIZE_C		9
+
#define SIZE_B		9
+
#define SIZE_Bx		(SIZE_C + SIZE_B)
+
#define SIZE_A		8
+
#define SIZE_Ax		(SIZE_C + SIZE_B + SIZE_A)
+

+
#define SIZE_OP		6
+

+
#define POS_OP		0
+
#define POS_A		(POS_OP + SIZE_OP)
+
#define POS_C		(POS_A + SIZE_A)
+
#define POS_B		(POS_C + SIZE_C)
+
#define POS_Bx		POS_C
+
#define POS_Ax		POS_A
+

+

+
/*
+
** limits for opcode arguments.
+
** we use (signed) int to manipulate most arguments,
+
** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
+
*/
+
#if SIZE_Bx < LUAI_BITSINT-1
+
#define MAXARG_Bx        ((1<<SIZE_Bx)-1)
+
#define MAXARG_sBx        (MAXARG_Bx>>1)         /* 'sBx' is signed */
+
#else
+
#define MAXARG_Bx        MAX_INT
+
#define MAXARG_sBx        MAX_INT
+
#endif
+

+
#if SIZE_Ax < LUAI_BITSINT-1
+
#define MAXARG_Ax	((1<<SIZE_Ax)-1)
+
#else
+
#define MAXARG_Ax	MAX_INT
+
#endif
+

+

+
#define MAXARG_A        ((1<<SIZE_A)-1)
+
#define MAXARG_B        ((1<<SIZE_B)-1)
+
#define MAXARG_C        ((1<<SIZE_C)-1)
+

+

+
/* creates a mask with 'n' 1 bits at position 'p' */
+
#define MASK1(n,p)	((~((~(Instruction)0)<<(n)))<<(p))
+

+
/* creates a mask with 'n' 0 bits at position 'p' */
+
#define MASK0(n,p)	(~MASK1(n,p))
+

+
/*
+
** the following macros help to manipulate instructions
+
*/
+

+
#define GET_OPCODE(i)	(cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
+
#define SET_OPCODE(i,o)	((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
+
		((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
+

+
#define getarg(i,pos,size)	(cast(int, ((i)>>pos) & MASK1(size,0)))
+
#define setarg(i,v,pos,size)	((i) = (((i)&MASK0(size,pos)) | \
+
                ((cast(Instruction, v)<<pos)&MASK1(size,pos))))
+

+
#define GETARG_A(i)	getarg(i, POS_A, SIZE_A)
+
#define SETARG_A(i,v)	setarg(i, v, POS_A, SIZE_A)
+

+
#define GETARG_B(i)	getarg(i, POS_B, SIZE_B)
+
#define SETARG_B(i,v)	setarg(i, v, POS_B, SIZE_B)
+

+
#define GETARG_C(i)	getarg(i, POS_C, SIZE_C)
+
#define SETARG_C(i,v)	setarg(i, v, POS_C, SIZE_C)
+

+
#define GETARG_Bx(i)	getarg(i, POS_Bx, SIZE_Bx)
+
#define SETARG_Bx(i,v)	setarg(i, v, POS_Bx, SIZE_Bx)
+

+
#define GETARG_Ax(i)	getarg(i, POS_Ax, SIZE_Ax)
+
#define SETARG_Ax(i,v)	setarg(i, v, POS_Ax, SIZE_Ax)
+

+
#define GETARG_sBx(i)	(GETARG_Bx(i)-MAXARG_sBx)
+
#define SETARG_sBx(i,b)	SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
+

+

+
#define CREATE_ABC(o,a,b,c)	((cast(Instruction, o)<<POS_OP) \
+
			| (cast(Instruction, a)<<POS_A) \
+
			| (cast(Instruction, b)<<POS_B) \
+
			| (cast(Instruction, c)<<POS_C))
+

+
#define CREATE_ABx(o,a,bc)	((cast(Instruction, o)<<POS_OP) \
+
			| (cast(Instruction, a)<<POS_A) \
+
			| (cast(Instruction, bc)<<POS_Bx))
+

+
#define CREATE_Ax(o,a)		((cast(Instruction, o)<<POS_OP) \
+
			| (cast(Instruction, a)<<POS_Ax))
+

+

+
/*
+
** Macros to operate RK indices
+
*/
+

+
/* this bit 1 means constant (0 means register) */
+
#define BITRK		(1 << (SIZE_B - 1))
+

+
/* test whether value is a constant */
+
#define ISK(x)		((x) & BITRK)
+

+
/* gets the index of the constant */
+
#define INDEXK(r)	((int)(r) & ~BITRK)
+

+
#if !defined(MAXINDEXRK)  /* (for debugging only) */
+
#define MAXINDEXRK	(BITRK - 1)
+
#endif
+

+
/* code a constant index as a RK value */
+
#define RKASK(x)	((x) | BITRK)
+

+

+
/*
+
** invalid register that fits in 8 bits
+
*/
+
#define NO_REG		MAXARG_A
+

+

+
/*
+
** R(x) - register
+
** Kst(x) - constant (in constant table)
+
** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
+
*/
+

+

+
/*
+
** grep "ORDER OP" if you change these enums
+
*/
+

+
typedef enum {
+
/*----------------------------------------------------------------------
+
name		args	description
+
------------------------------------------------------------------------*/
+
OP_MOVE,/*	A B	R(A) := R(B)					*/
+
OP_LOADK,/*	A Bx	R(A) := Kst(Bx)					*/
+
OP_LOADKX,/*	A 	R(A) := Kst(extra arg)				*/
+
OP_LOADBOOL,/*	A B C	R(A) := (Bool)B; if (C) pc++			*/
+
OP_LOADNIL,/*	A B	R(A), R(A+1), ..., R(A+B) := nil		*/
+
OP_GETUPVAL,/*	A B	R(A) := UpValue[B]				*/
+

+
OP_GETTABUP,/*	A B C	R(A) := UpValue[B][RK(C)]			*/
+
OP_GETTABLE,/*	A B C	R(A) := R(B)[RK(C)]				*/
+

+
OP_SETTABUP,/*	A B C	UpValue[A][RK(B)] := RK(C)			*/
+
OP_SETUPVAL,/*	A B	UpValue[B] := R(A)				*/
+
OP_SETTABLE,/*	A B C	R(A)[RK(B)] := RK(C)				*/
+

+
OP_NEWTABLE,/*	A B C	R(A) := {} (size = B,C)				*/
+

+
OP_SELF,/*	A B C	R(A+1) := R(B); R(A) := R(B)[RK(C)]		*/
+

+
OP_ADD,/*	A B C	R(A) := RK(B) + RK(C)				*/
+
OP_SUB,/*	A B C	R(A) := RK(B) - RK(C)				*/
+
OP_MUL,/*	A B C	R(A) := RK(B) * RK(C)				*/
+
OP_MOD,/*	A B C	R(A) := RK(B) % RK(C)				*/
+
OP_POW,/*	A B C	R(A) := RK(B) ^ RK(C)				*/
+
OP_DIV,/*	A B C	R(A) := RK(B) / RK(C)				*/
+
OP_IDIV,/*	A B C	R(A) := RK(B) // RK(C)				*/
+
OP_BAND,/*	A B C	R(A) := RK(B) & RK(C)				*/
+
OP_BOR,/*	A B C	R(A) := RK(B) | RK(C)				*/
+
OP_BXOR,/*	A B C	R(A) := RK(B) ~ RK(C)				*/
+
OP_SHL,/*	A B C	R(A) := RK(B) << RK(C)				*/
+
OP_SHR,/*	A B C	R(A) := RK(B) >> RK(C)				*/
+
OP_UNM,/*	A B	R(A) := -R(B)					*/
+
OP_BNOT,/*	A B	R(A) := ~R(B)					*/
+
OP_NOT,/*	A B	R(A) := not R(B)				*/
+
OP_LEN,/*	A B	R(A) := length of R(B)				*/
+

+
OP_CONCAT,/*	A B C	R(A) := R(B).. ... ..R(C)			*/
+

+
OP_JMP,/*	A sBx	pc+=sBx; if (A) close all upvalues >= R(A - 1)	*/
+
OP_EQ,/*	A B C	if ((RK(B) == RK(C)) ~= A) then pc++		*/
+
OP_LT,/*	A B C	if ((RK(B) <  RK(C)) ~= A) then pc++		*/
+
OP_LE,/*	A B C	if ((RK(B) <= RK(C)) ~= A) then pc++		*/
+

+
OP_TEST,/*	A C	if not (R(A) <=> C) then pc++			*/
+
OP_TESTSET,/*	A B C	if (R(B) <=> C) then R(A) := R(B) else pc++	*/
+

+
OP_CALL,/*	A B C	R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
+
OP_TAILCALL,/*	A B C	return R(A)(R(A+1), ... ,R(A+B-1))		*/
+
OP_RETURN,/*	A B	return R(A), ... ,R(A+B-2)	(see note)	*/
+

+
OP_FORLOOP,/*	A sBx	R(A)+=R(A+2);
+
			if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
+
OP_FORPREP,/*	A sBx	R(A)-=R(A+2); pc+=sBx				*/
+

+
OP_TFORCALL,/*	A C	R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));	*/
+
OP_TFORLOOP,/*	A sBx	if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
+

+
OP_SETLIST,/*	A B C	R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B	*/
+

+
OP_CLOSURE,/*	A Bx	R(A) := closure(KPROTO[Bx])			*/
+

+
OP_VARARG,/*	A B	R(A), R(A+1), ..., R(A+B-2) = vararg		*/
+

+
OP_EXTRAARG/*	Ax	extra (larger) argument for previous opcode	*/
+
} OpCode;
+

+

+
#define NUM_OPCODES	(cast(int, OP_EXTRAARG) + 1)
+

+

+

+
/*===========================================================================
+
  Notes:
+
  (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then 'top' is
+
  set to last_result+1, so next open instruction (OP_CALL, OP_RETURN,
+
  OP_SETLIST) may use 'top'.
+

+
  (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
+
  set top (like in OP_CALL with C == 0).
+

+
  (*) In OP_RETURN, if (B == 0) then return up to 'top'.
+

+
  (*) In OP_SETLIST, if (B == 0) then B = 'top'; if (C == 0) then next
+
  'instruction' is EXTRAARG(real C).
+

+
  (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
+

+
  (*) For comparisons, A specifies what condition the test should accept
+
  (true or false).
+

+
  (*) All 'skips' (pc++) assume that next instruction is a jump.
+

+
===========================================================================*/
+

+

+
/*
+
** masks for instruction properties. The format is:
+
** bits 0-1: op mode
+
** bits 2-3: C arg mode
+
** bits 4-5: B arg mode
+
** bit 6: instruction set register A
+
** bit 7: operator is a test (next instruction must be a jump)
+
*/
+

+
enum OpArgMask {
+
  OpArgN,  /* argument is not used */
+
  OpArgU,  /* argument is used */
+
  OpArgR,  /* argument is a register or a jump offset */
+
  OpArgK   /* argument is a constant or register/constant */
+
};
+

+
LUAI_DDEC 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 getCMode(m)	(cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
+
#define testAMode(m)	(luaP_opmodes[m] & (1 << 6))
+
#define testTMode(m)	(luaP_opmodes[m] & (1 << 7))
+

+

+
LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1];  /* opcode names */
+

+

+
/* number of list items to accumulate before a SETLIST instruction */
+
#define LFIELDS_PER_FLUSH	50
+

+

+
#endif
added external/lua/src/loslib.c
@@ -0,0 +1,409 @@
+
/*
+
** $Id: loslib.c,v 1.65.1.1 2017/04/19 17:29:57 roberto Exp $
+
** Standard Operating System library
+
** See Copyright Notice in lua.h
+
*/
+

+
#define loslib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <errno.h>
+
#include <locale.h>
+
#include <stdlib.h>
+
#include <string.h>
+
#include <time.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+
/*
+
** {==================================================================
+
** List of valid conversion specifiers for the 'strftime' function;
+
** options are grouped by length; group of length 2 start with '||'.
+
** ===================================================================
+
*/
+
#if !defined(LUA_STRFTIMEOPTIONS)	/* { */
+

+
/* options for ANSI C 89 (only 1-char options) */
+
#define L_STRFTIMEC89		"aAbBcdHIjmMpSUwWxXyYZ%"
+

+
/* options for ISO C 99 and POSIX */
+
#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
+
    "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy"  /* two-char options */
+

+
/* options for Windows */
+
#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
+
    "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"  /* two-char options */
+

+
#if defined(LUA_USE_WINDOWS)
+
#define LUA_STRFTIMEOPTIONS	L_STRFTIMEWIN
+
#elif defined(LUA_USE_C89)
+
#define LUA_STRFTIMEOPTIONS	L_STRFTIMEC89
+
#else  /* C99 specification */
+
#define LUA_STRFTIMEOPTIONS	L_STRFTIMEC99
+
#endif
+

+
#endif					/* } */
+
/* }================================================================== */
+

+

+
/*
+
** {==================================================================
+
** Configuration for time-related stuff
+
** ===================================================================
+
*/
+

+
#if !defined(l_time_t)		/* { */
+
/*
+
** type to represent time_t in Lua
+
*/
+
#define l_timet			lua_Integer
+
#define l_pushtime(L,t)		lua_pushinteger(L,(lua_Integer)(t))
+

+
static time_t l_checktime (lua_State *L, int arg) {
+
  lua_Integer t = luaL_checkinteger(L, arg);
+
  luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds");
+
  return (time_t)t;
+
}
+

+
#endif				/* } */
+

+

+
#if !defined(l_gmtime)		/* { */
+
/*
+
** By default, Lua uses gmtime/localtime, except when POSIX is available,
+
** where it uses gmtime_r/localtime_r
+
*/
+

+
#if defined(LUA_USE_POSIX)	/* { */
+

+
#define l_gmtime(t,r)		gmtime_r(t,r)
+
#define l_localtime(t,r)	localtime_r(t,r)
+

+
#else				/* }{ */
+

+
/* ISO C definitions */
+
#define l_gmtime(t,r)		((void)(r)->tm_sec, gmtime(t))
+
#define l_localtime(t,r)  	((void)(r)->tm_sec, localtime(t))
+

+
#endif				/* } */
+

+
#endif				/* } */
+

+
/* }================================================================== */
+

+

+
/*
+
** {==================================================================
+
** Configuration for 'tmpnam':
+
** By default, Lua uses tmpnam except when POSIX is available, where
+
** it uses mkstemp.
+
** ===================================================================
+
*/
+
#if !defined(lua_tmpnam)	/* { */
+

+
#if defined(LUA_USE_POSIX)	/* { */
+

+
#include <unistd.h>
+

+
#define LUA_TMPNAMBUFSIZE	32
+

+
#if !defined(LUA_TMPNAMTEMPLATE)
+
#define LUA_TMPNAMTEMPLATE	"/tmp/lua_XXXXXX"
+
#endif
+

+
#define lua_tmpnam(b,e) { \
+
        strcpy(b, LUA_TMPNAMTEMPLATE); \
+
        e = mkstemp(b); \
+
        if (e != -1) close(e); \
+
        e = (e == -1); }
+

+
#else				/* }{ */
+

+
/* ISO C definitions */
+
#define LUA_TMPNAMBUFSIZE	L_tmpnam
+
#define lua_tmpnam(b,e)		{ e = (tmpnam(b) == NULL); }
+

+
#endif				/* } */
+

+
#endif				/* } */
+
/* }================================================================== */
+

+

+

+

+
static int os_execute (lua_State *L) {
+
  const char *cmd = luaL_optstring(L, 1, NULL);
+
  int stat = system(cmd);
+
  if (cmd != NULL)
+
    return luaL_execresult(L, stat);
+
  else {
+
    lua_pushboolean(L, stat);  /* true if there is a shell */
+
    return 1;
+
  }
+
}
+

+

+
static int os_remove (lua_State *L) {
+
  const char *filename = luaL_checkstring(L, 1);
+
  return luaL_fileresult(L, remove(filename) == 0, filename);
+
}
+

+

+
static int os_rename (lua_State *L) {
+
  const char *fromname = luaL_checkstring(L, 1);
+
  const char *toname = luaL_checkstring(L, 2);
+
  return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
+
}
+

+

+
static int os_tmpname (lua_State *L) {
+
  char buff[LUA_TMPNAMBUFSIZE];
+
  int err;
+
  lua_tmpnam(buff, err);
+
  if (err)
+
    return luaL_error(L, "unable to generate a unique filename");
+
  lua_pushstring(L, buff);
+
  return 1;
+
}
+

+

+
static int os_getenv (lua_State *L) {
+
  lua_pushstring(L, getenv(luaL_checkstring(L, 1)));  /* if NULL push nil */
+
  return 1;
+
}
+

+

+
static int os_clock (lua_State *L) {
+
  lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
+
  return 1;
+
}
+

+

+
/*
+
** {======================================================
+
** Time/Date operations
+
** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
+
**   wday=%w+1, yday=%j, isdst=? }
+
** =======================================================
+
*/
+

+
static void setfield (lua_State *L, const char *key, int value) {
+
  lua_pushinteger(L, value);
+
  lua_setfield(L, -2, key);
+
}
+

+
static void setboolfield (lua_State *L, const char *key, int value) {
+
  if (value < 0)  /* undefined? */
+
    return;  /* does not set field */
+
  lua_pushboolean(L, value);
+
  lua_setfield(L, -2, key);
+
}
+

+

+
/*
+
** Set all fields from structure 'tm' in the table on top of the stack
+
*/
+
static void setallfields (lua_State *L, struct tm *stm) {
+
  setfield(L, "sec", stm->tm_sec);
+
  setfield(L, "min", stm->tm_min);
+
  setfield(L, "hour", stm->tm_hour);
+
  setfield(L, "day", stm->tm_mday);
+
  setfield(L, "month", stm->tm_mon + 1);
+
  setfield(L, "year", stm->tm_year + 1900);
+
  setfield(L, "wday", stm->tm_wday + 1);
+
  setfield(L, "yday", stm->tm_yday + 1);
+
  setboolfield(L, "isdst", stm->tm_isdst);
+
}
+

+

+
static int getboolfield (lua_State *L, const char *key) {
+
  int res;
+
  res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
+
  lua_pop(L, 1);
+
  return res;
+
}
+

+

+
/* maximum value for date fields (to avoid arithmetic overflows with 'int') */
+
#if !defined(L_MAXDATEFIELD)
+
#define L_MAXDATEFIELD	(INT_MAX / 2)
+
#endif
+

+
static int getfield (lua_State *L, const char *key, int d, int delta) {
+
  int isnum;
+
  int t = lua_getfield(L, -1, key);  /* get field and its type */
+
  lua_Integer res = lua_tointegerx(L, -1, &isnum);
+
  if (!isnum) {  /* field is not an integer? */
+
    if (t != LUA_TNIL)  /* some other value? */
+
      return luaL_error(L, "field '%s' is not an integer", key);
+
    else if (d < 0)  /* absent field; no default? */
+
      return luaL_error(L, "field '%s' missing in date table", key);
+
    res = d;
+
  }
+
  else {
+
    if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
+
      return luaL_error(L, "field '%s' is out-of-bound", key);
+
    res -= delta;
+
  }
+
  lua_pop(L, 1);
+
  return (int)res;
+
}
+

+

+
static const char *checkoption (lua_State *L, const char *conv,
+
                                ptrdiff_t convlen, char *buff) {
+
  const char *option = LUA_STRFTIMEOPTIONS;
+
  int oplen = 1;  /* length of options being checked */
+
  for (; *option != '\0' && oplen <= convlen; option += oplen) {
+
    if (*option == '|')  /* next block? */
+
      oplen++;  /* will check options with next length (+1) */
+
    else if (memcmp(conv, option, oplen) == 0) {  /* match? */
+
      memcpy(buff, conv, oplen);  /* copy valid option to buffer */
+
      buff[oplen] = '\0';
+
      return conv + oplen;  /* return next item */
+
    }
+
  }
+
  luaL_argerror(L, 1,
+
    lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
+
  return conv;  /* to avoid warnings */
+
}
+

+

+
/* maximum size for an individual 'strftime' item */
+
#define SIZETIMEFMT	250
+

+

+
static int os_date (lua_State *L) {
+
  size_t slen;
+
  const char *s = luaL_optlstring(L, 1, "%c", &slen);
+
  time_t t = luaL_opt(L, l_checktime, 2, time(NULL));
+
  const char *se = s + slen;  /* 's' end */
+
  struct tm tmr, *stm;
+
  if (*s == '!') {  /* UTC? */
+
    stm = l_gmtime(&t, &tmr);
+
    s++;  /* skip '!' */
+
  }
+
  else
+
    stm = l_localtime(&t, &tmr);
+
  if (stm == NULL)  /* invalid date? */
+
    return luaL_error(L,
+
                 "time result cannot be represented in this installation");
+
  if (strcmp(s, "*t") == 0) {
+
    lua_createtable(L, 0, 9);  /* 9 = number of fields */
+
    setallfields(L, stm);
+
  }
+
  else {
+
    char cc[4];  /* buffer for individual conversion specifiers */
+
    luaL_Buffer b;
+
    cc[0] = '%';
+
    luaL_buffinit(L, &b);
+
    while (s < se) {
+
      if (*s != '%')  /* not a conversion specifier? */
+
        luaL_addchar(&b, *s++);
+
      else {
+
        size_t reslen;
+
        char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
+
        s++;  /* skip '%' */
+
        s = checkoption(L, s, se - s, cc + 1);  /* copy specifier to 'cc' */
+
        reslen = strftime(buff, SIZETIMEFMT, cc, stm);
+
        luaL_addsize(&b, reslen);
+
      }
+
    }
+
    luaL_pushresult(&b);
+
  }
+
  return 1;
+
}
+

+

+
static int os_time (lua_State *L) {
+
  time_t t;
+
  if (lua_isnoneornil(L, 1))  /* called without args? */
+
    t = time(NULL);  /* get current time */
+
  else {
+
    struct tm ts;
+
    luaL_checktype(L, 1, LUA_TTABLE);
+
    lua_settop(L, 1);  /* make sure table is at the top */
+
    ts.tm_sec = getfield(L, "sec", 0, 0);
+
    ts.tm_min = getfield(L, "min", 0, 0);
+
    ts.tm_hour = getfield(L, "hour", 12, 0);
+
    ts.tm_mday = getfield(L, "day", -1, 0);
+
    ts.tm_mon = getfield(L, "month", -1, 1);
+
    ts.tm_year = getfield(L, "year", -1, 1900);
+
    ts.tm_isdst = getboolfield(L, "isdst");
+
    t = mktime(&ts);
+
    setallfields(L, &ts);  /* update fields with normalized values */
+
  }
+
  if (t != (time_t)(l_timet)t || t == (time_t)(-1))
+
    return luaL_error(L,
+
                  "time result cannot be represented in this installation");
+
  l_pushtime(L, t);
+
  return 1;
+
}
+

+

+
static int os_difftime (lua_State *L) {
+
  time_t t1 = l_checktime(L, 1);
+
  time_t t2 = l_checktime(L, 2);
+
  lua_pushnumber(L, (lua_Number)difftime(t1, t2));
+
  return 1;
+
}
+

+
/* }====================================================== */
+

+

+
static int os_setlocale (lua_State *L) {
+
  static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
+
                      LC_NUMERIC, LC_TIME};
+
  static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
+
     "numeric", "time", NULL};
+
  const char *l = luaL_optstring(L, 1, NULL);
+
  int op = luaL_checkoption(L, 2, "all", catnames);
+
  lua_pushstring(L, setlocale(cat[op], l));
+
  return 1;
+
}
+

+

+
static int os_exit (lua_State *L) {
+
  int status;
+
  if (lua_isboolean(L, 1))
+
    status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
+
  else
+
    status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS);
+
  if (lua_toboolean(L, 2))
+
    lua_close(L);
+
  if (L) exit(status);  /* 'if' to avoid warnings for unreachable 'return' */
+
  return 0;
+
}
+

+

+
static const luaL_Reg syslib[] = {
+
  {"clock",     os_clock},
+
  {"date",      os_date},
+
  {"difftime",  os_difftime},
+
  {"execute",   os_execute},
+
  {"exit",      os_exit},
+
  {"getenv",    os_getenv},
+
  {"remove",    os_remove},
+
  {"rename",    os_rename},
+
  {"setlocale", os_setlocale},
+
  {"time",      os_time},
+
  {"tmpname",   os_tmpname},
+
  {NULL, NULL}
+
};
+

+
/* }====================================================== */
+

+

+

+
LUAMOD_API int luaopen_os (lua_State *L) {
+
  luaL_newlib(L, syslib);
+
  return 1;
+
}
+

added external/lua/src/lparser.c
@@ -0,0 +1,1650 @@
+
/*
+
** $Id: lparser.c,v 2.155.1.2 2017/04/29 18:11:40 roberto Exp $
+
** Lua Parser
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lparser_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lcode.h"
+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lfunc.h"
+
#include "llex.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lopcodes.h"
+
#include "lparser.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+

+

+

+
/* maximum number of local variables per function (must be smaller
+
   than 250, due to the bytecode format) */
+
#define MAXVARS		200
+

+

+
#define hasmultret(k)		((k) == VCALL || (k) == VVARARG)
+

+

+
/* because all strings are unified by the scanner, the parser
+
   can use pointer equality for string equality */
+
#define eqstr(a,b)	((a) == (b))
+

+

+
/*
+
** nodes for block list (list of active blocks)
+
*/
+
typedef struct BlockCnt {
+
  struct BlockCnt *previous;  /* chain */
+
  int firstlabel;  /* index of first label in this block */
+
  int firstgoto;  /* index of first pending goto in this block */
+
  lu_byte nactvar;  /* # active locals outside the block */
+
  lu_byte upval;  /* true if some variable in the block is an upvalue */
+
  lu_byte isloop;  /* true if 'block' is a loop */
+
} BlockCnt;
+

+

+

+
/*
+
** prototypes for recursive non-terminal functions
+
*/
+
static void statement (LexState *ls);
+
static void expr (LexState *ls, expdesc *v);
+

+

+
/* semantic error */
+
static l_noret semerror (LexState *ls, const char *msg) {
+
  ls->t.token = 0;  /* remove "near <token>" from final message */
+
  luaX_syntaxerror(ls, msg);
+
}
+

+

+
static l_noret error_expected (LexState *ls, int token) {
+
  luaX_syntaxerror(ls,
+
      luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
+
}
+

+

+
static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
+
  lua_State *L = fs->ls->L;
+
  const char *msg;
+
  int line = fs->f->linedefined;
+
  const char *where = (line == 0)
+
                      ? "main function"
+
                      : luaO_pushfstring(L, "function at line %d", line);
+
  msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
+
                             what, limit, where);
+
  luaX_syntaxerror(fs->ls, msg);
+
}
+

+

+
static void checklimit (FuncState *fs, int v, int l, const char *what) {
+
  if (v > l) errorlimit(fs, l, what);
+
}
+

+

+
static int testnext (LexState *ls, int c) {
+
  if (ls->t.token == c) {
+
    luaX_next(ls);
+
    return 1;
+
  }
+
  else return 0;
+
}
+

+

+
static void check (LexState *ls, int c) {
+
  if (ls->t.token != c)
+
    error_expected(ls, c);
+
}
+

+

+
static void checknext (LexState *ls, int c) {
+
  check(ls, c);
+
  luaX_next(ls);
+
}
+

+

+
#define check_condition(ls,c,msg)	{ if (!(c)) luaX_syntaxerror(ls, msg); }
+

+

+

+
static void check_match (LexState *ls, int what, int who, int where) {
+
  if (!testnext(ls, what)) {
+
    if (where == ls->linenumber)
+
      error_expected(ls, what);
+
    else {
+
      luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
+
             "%s expected (to close %s at line %d)",
+
              luaX_token2str(ls, what), luaX_token2str(ls, who), where));
+
    }
+
  }
+
}
+

+

+
static TString *str_checkname (LexState *ls) {
+
  TString *ts;
+
  check(ls, TK_NAME);
+
  ts = ls->t.seminfo.ts;
+
  luaX_next(ls);
+
  return ts;
+
}
+

+

+
static void init_exp (expdesc *e, expkind k, int i) {
+
  e->f = e->t = NO_JUMP;
+
  e->k = k;
+
  e->u.info = i;
+
}
+

+

+
static void codestring (LexState *ls, expdesc *e, TString *s) {
+
  init_exp(e, VK, luaK_stringK(ls->fs, s));
+
}
+

+

+
static void checkname (LexState *ls, expdesc *e) {
+
  codestring(ls, e, str_checkname(ls));
+
}
+

+

+
static int registerlocalvar (LexState *ls, TString *varname) {
+
  FuncState *fs = ls->fs;
+
  Proto *f = fs->f;
+
  int oldsize = f->sizelocvars;
+
  luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
+
                  LocVar, SHRT_MAX, "local variables");
+
  while (oldsize < f->sizelocvars)
+
    f->locvars[oldsize++].varname = NULL;
+
  f->locvars[fs->nlocvars].varname = varname;
+
  luaC_objbarrier(ls->L, f, varname);
+
  return fs->nlocvars++;
+
}
+

+

+
static void new_localvar (LexState *ls, TString *name) {
+
  FuncState *fs = ls->fs;
+
  Dyndata *dyd = ls->dyd;
+
  int reg = registerlocalvar(ls, name);
+
  checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
+
                  MAXVARS, "local variables");
+
  luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,
+
                  dyd->actvar.size, Vardesc, MAX_INT, "local variables");
+
  dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);
+
}
+

+

+
static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
+
  new_localvar(ls, luaX_newstring(ls, name, sz));
+
}
+

+
#define new_localvarliteral(ls,v) \
+
	new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1)
+

+

+
static LocVar *getlocvar (FuncState *fs, int i) {
+
  int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
+
  lua_assert(idx < fs->nlocvars);
+
  return &fs->f->locvars[idx];
+
}
+

+

+
static void adjustlocalvars (LexState *ls, int nvars) {
+
  FuncState *fs = ls->fs;
+
  fs->nactvar = cast_byte(fs->nactvar + nvars);
+
  for (; nvars; nvars--) {
+
    getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
+
  }
+
}
+

+

+
static void removevars (FuncState *fs, int tolevel) {
+
  fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
+
  while (fs->nactvar > tolevel)
+
    getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
+
}
+

+

+
static int searchupvalue (FuncState *fs, TString *name) {
+
  int i;
+
  Upvaldesc *up = fs->f->upvalues;
+
  for (i = 0; i < fs->nups; i++) {
+
    if (eqstr(up[i].name, name)) return i;
+
  }
+
  return -1;  /* not found */
+
}
+

+

+
static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
+
  Proto *f = fs->f;
+
  int oldsize = f->sizeupvalues;
+
  checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
+
  luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
+
                  Upvaldesc, MAXUPVAL, "upvalues");
+
  while (oldsize < f->sizeupvalues)
+
    f->upvalues[oldsize++].name = NULL;
+
  f->upvalues[fs->nups].instack = (v->k == VLOCAL);
+
  f->upvalues[fs->nups].idx = cast_byte(v->u.info);
+
  f->upvalues[fs->nups].name = name;
+
  luaC_objbarrier(fs->ls->L, f, name);
+
  return fs->nups++;
+
}
+

+

+
static int searchvar (FuncState *fs, TString *n) {
+
  int i;
+
  for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
+
    if (eqstr(n, getlocvar(fs, i)->varname))
+
      return i;
+
  }
+
  return -1;  /* not found */
+
}
+

+

+
/*
+
  Mark block where variable at given level was defined
+
  (to emit close instructions later).
+
*/
+
static void markupval (FuncState *fs, int level) {
+
  BlockCnt *bl = fs->bl;
+
  while (bl->nactvar > level)
+
    bl = bl->previous;
+
  bl->upval = 1;
+
}
+

+

+
/*
+
  Find variable with given name 'n'. If it is an upvalue, add this
+
  upvalue into all intermediate functions.
+
*/
+
static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
+
  if (fs == NULL)  /* no more levels? */
+
    init_exp(var, VVOID, 0);  /* default is global */
+
  else {
+
    int v = searchvar(fs, n);  /* look up locals at current level */
+
    if (v >= 0) {  /* found? */
+
      init_exp(var, VLOCAL, v);  /* variable is local */
+
      if (!base)
+
        markupval(fs, v);  /* local will be used as an upval */
+
    }
+
    else {  /* not found as local at current level; try upvalues */
+
      int idx = searchupvalue(fs, n);  /* try existing upvalues */
+
      if (idx < 0) {  /* not found? */
+
        singlevaraux(fs->prev, n, var, 0);  /* try upper levels */
+
        if (var->k == VVOID)  /* not found? */
+
          return;  /* it is a global */
+
        /* else was LOCAL or UPVAL */
+
        idx  = newupvalue(fs, n, var);  /* will be a new upvalue */
+
      }
+
      init_exp(var, VUPVAL, idx);  /* new or old upvalue */
+
    }
+
  }
+
}
+

+

+
static void singlevar (LexState *ls, expdesc *var) {
+
  TString *varname = str_checkname(ls);
+
  FuncState *fs = ls->fs;
+
  singlevaraux(fs, varname, var, 1);
+
  if (var->k == VVOID) {  /* global name? */
+
    expdesc key;
+
    singlevaraux(fs, ls->envn, var, 1);  /* get environment variable */
+
    lua_assert(var->k != VVOID);  /* this one must exist */
+
    codestring(ls, &key, varname);  /* key is variable name */
+
    luaK_indexed(fs, var, &key);  /* env[varname] */
+
  }
+
}
+

+

+
static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
+
  FuncState *fs = ls->fs;
+
  int extra = nvars - nexps;
+
  if (hasmultret(e->k)) {
+
    extra++;  /* includes call itself */
+
    if (extra < 0) extra = 0;
+
    luaK_setreturns(fs, e, extra);  /* last exp. provides the difference */
+
    if (extra > 1) luaK_reserveregs(fs, extra-1);
+
  }
+
  else {
+
    if (e->k != VVOID) luaK_exp2nextreg(fs, e);  /* close last expression */
+
    if (extra > 0) {
+
      int reg = fs->freereg;
+
      luaK_reserveregs(fs, extra);
+
      luaK_nil(fs, reg, extra);
+
    }
+
  }
+
  if (nexps > nvars)
+
    ls->fs->freereg -= nexps - nvars;  /* remove extra values */
+
}
+

+

+
static void enterlevel (LexState *ls) {
+
  lua_State *L = ls->L;
+
  ++L->nCcalls;
+
  checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
+
}
+

+

+
#define leavelevel(ls)	((ls)->L->nCcalls--)
+

+

+
static void closegoto (LexState *ls, int g, Labeldesc *label) {
+
  int i;
+
  FuncState *fs = ls->fs;
+
  Labellist *gl = &ls->dyd->gt;
+
  Labeldesc *gt = &gl->arr[g];
+
  lua_assert(eqstr(gt->name, label->name));
+
  if (gt->nactvar < label->nactvar) {
+
    TString *vname = getlocvar(fs, gt->nactvar)->varname;
+
    const char *msg = luaO_pushfstring(ls->L,
+
      "<goto %s> at line %d jumps into the scope of local '%s'",
+
      getstr(gt->name), gt->line, getstr(vname));
+
    semerror(ls, msg);
+
  }
+
  luaK_patchlist(fs, gt->pc, label->pc);
+
  /* remove goto from pending list */
+
  for (i = g; i < gl->n - 1; i++)
+
    gl->arr[i] = gl->arr[i + 1];
+
  gl->n--;
+
}
+

+

+
/*
+
** try to close a goto with existing labels; this solves backward jumps
+
*/
+
static int findlabel (LexState *ls, int g) {
+
  int i;
+
  BlockCnt *bl = ls->fs->bl;
+
  Dyndata *dyd = ls->dyd;
+
  Labeldesc *gt = &dyd->gt.arr[g];
+
  /* check labels in current block for a match */
+
  for (i = bl->firstlabel; i < dyd->label.n; i++) {
+
    Labeldesc *lb = &dyd->label.arr[i];
+
    if (eqstr(lb->name, gt->name)) {  /* correct label? */
+
      if (gt->nactvar > lb->nactvar &&
+
          (bl->upval || dyd->label.n > bl->firstlabel))
+
        luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
+
      closegoto(ls, g, lb);  /* close it */
+
      return 1;
+
    }
+
  }
+
  return 0;  /* label not found; cannot close goto */
+
}
+

+

+
static int newlabelentry (LexState *ls, Labellist *l, TString *name,
+
                          int line, int pc) {
+
  int n = l->n;
+
  luaM_growvector(ls->L, l->arr, n, l->size,
+
                  Labeldesc, SHRT_MAX, "labels/gotos");
+
  l->arr[n].name = name;
+
  l->arr[n].line = line;
+
  l->arr[n].nactvar = ls->fs->nactvar;
+
  l->arr[n].pc = pc;
+
  l->n = n + 1;
+
  return n;
+
}
+

+

+
/*
+
** check whether new label 'lb' matches any pending gotos in current
+
** block; solves forward jumps
+
*/
+
static void findgotos (LexState *ls, Labeldesc *lb) {
+
  Labellist *gl = &ls->dyd->gt;
+
  int i = ls->fs->bl->firstgoto;
+
  while (i < gl->n) {
+
    if (eqstr(gl->arr[i].name, lb->name))
+
      closegoto(ls, i, lb);
+
    else
+
      i++;
+
  }
+
}
+

+

+
/*
+
** export pending gotos to outer level, to check them against
+
** outer labels; if the block being exited has upvalues, and
+
** the goto exits the scope of any variable (which can be the
+
** upvalue), close those variables being exited.
+
*/
+
static void movegotosout (FuncState *fs, BlockCnt *bl) {
+
  int i = bl->firstgoto;
+
  Labellist *gl = &fs->ls->dyd->gt;
+
  /* correct pending gotos to current block and try to close it
+
     with visible labels */
+
  while (i < gl->n) {
+
    Labeldesc *gt = &gl->arr[i];
+
    if (gt->nactvar > bl->nactvar) {
+
      if (bl->upval)
+
        luaK_patchclose(fs, gt->pc, bl->nactvar);
+
      gt->nactvar = bl->nactvar;
+
    }
+
    if (!findlabel(fs->ls, i))
+
      i++;  /* move to next one */
+
  }
+
}
+

+

+
static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
+
  bl->isloop = isloop;
+
  bl->nactvar = fs->nactvar;
+
  bl->firstlabel = fs->ls->dyd->label.n;
+
  bl->firstgoto = fs->ls->dyd->gt.n;
+
  bl->upval = 0;
+
  bl->previous = fs->bl;
+
  fs->bl = bl;
+
  lua_assert(fs->freereg == fs->nactvar);
+
}
+

+

+
/*
+
** create a label named 'break' to resolve break statements
+
*/
+
static void breaklabel (LexState *ls) {
+
  TString *n = luaS_new(ls->L, "break");
+
  int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc);
+
  findgotos(ls, &ls->dyd->label.arr[l]);
+
}
+

+
/*
+
** generates an error for an undefined 'goto'; choose appropriate
+
** message when label name is a reserved word (which can only be 'break')
+
*/
+
static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
+
  const char *msg = isreserved(gt->name)
+
                    ? "<%s> at line %d not inside a loop"
+
                    : "no visible label '%s' for <goto> at line %d";
+
  msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
+
  semerror(ls, msg);
+
}
+

+

+
static void leaveblock (FuncState *fs) {
+
  BlockCnt *bl = fs->bl;
+
  LexState *ls = fs->ls;
+
  if (bl->previous && bl->upval) {
+
    /* create a 'jump to here' to close upvalues */
+
    int j = luaK_jump(fs);
+
    luaK_patchclose(fs, j, bl->nactvar);
+
    luaK_patchtohere(fs, j);
+
  }
+
  if (bl->isloop)
+
    breaklabel(ls);  /* close pending breaks */
+
  fs->bl = bl->previous;
+
  removevars(fs, bl->nactvar);
+
  lua_assert(bl->nactvar == fs->nactvar);
+
  fs->freereg = fs->nactvar;  /* free registers */
+
  ls->dyd->label.n = bl->firstlabel;  /* remove local labels */
+
  if (bl->previous)  /* inner block? */
+
    movegotosout(fs, bl);  /* update pending gotos to outer block */
+
  else if (bl->firstgoto < ls->dyd->gt.n)  /* pending gotos in outer block? */
+
    undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]);  /* error */
+
}
+

+

+
/*
+
** adds a new prototype into list of prototypes
+
*/
+
static Proto *addprototype (LexState *ls) {
+
  Proto *clp;
+
  lua_State *L = ls->L;
+
  FuncState *fs = ls->fs;
+
  Proto *f = fs->f;  /* prototype of current function */
+
  if (fs->np >= f->sizep) {
+
    int oldsize = f->sizep;
+
    luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
+
    while (oldsize < f->sizep)
+
      f->p[oldsize++] = NULL;
+
  }
+
  f->p[fs->np++] = clp = luaF_newproto(L);
+
  luaC_objbarrier(L, f, clp);
+
  return clp;
+
}
+

+

+
/*
+
** codes instruction to create new closure in parent function.
+
** The OP_CLOSURE instruction must use the last available register,
+
** so that, if it invokes the GC, the GC knows which registers
+
** are in use at that time.
+
*/
+
static void codeclosure (LexState *ls, expdesc *v) {
+
  FuncState *fs = ls->fs->prev;
+
  init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
+
  luaK_exp2nextreg(fs, v);  /* fix it at the last register */
+
}
+

+

+
static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
+
  Proto *f;
+
  fs->prev = ls->fs;  /* linked list of funcstates */
+
  fs->ls = ls;
+
  ls->fs = fs;
+
  fs->pc = 0;
+
  fs->lasttarget = 0;
+
  fs->jpc = NO_JUMP;
+
  fs->freereg = 0;
+
  fs->nk = 0;
+
  fs->np = 0;
+
  fs->nups = 0;
+
  fs->nlocvars = 0;
+
  fs->nactvar = 0;
+
  fs->firstlocal = ls->dyd->actvar.n;
+
  fs->bl = NULL;
+
  f = fs->f;
+
  f->source = ls->source;
+
  f->maxstacksize = 2;  /* registers 0/1 are always valid */
+
  enterblock(fs, bl, 0);
+
}
+

+

+
static void close_func (LexState *ls) {
+
  lua_State *L = ls->L;
+
  FuncState *fs = ls->fs;
+
  Proto *f = fs->f;
+
  luaK_ret(fs, 0, 0);  /* final return */
+
  leaveblock(fs);
+
  luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
+
  f->sizecode = fs->pc;
+
  luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
+
  f->sizelineinfo = fs->pc;
+
  luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
+
  f->sizek = fs->nk;
+
  luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
+
  f->sizep = fs->np;
+
  luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
+
  f->sizelocvars = fs->nlocvars;
+
  luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
+
  f->sizeupvalues = fs->nups;
+
  lua_assert(fs->bl == NULL);
+
  ls->fs = fs->prev;
+
  luaC_checkGC(L);
+
}
+

+

+

+
/*============================================================*/
+
/* GRAMMAR RULES */
+
/*============================================================*/
+

+

+
/*
+
** check whether current token is in the follow set of a block.
+
** 'until' closes syntactical blocks, but do not close scope,
+
** so it is handled in separate.
+
*/
+
static int block_follow (LexState *ls, int withuntil) {
+
  switch (ls->t.token) {
+
    case TK_ELSE: case TK_ELSEIF:
+
    case TK_END: case TK_EOS:
+
      return 1;
+
    case TK_UNTIL: return withuntil;
+
    default: return 0;
+
  }
+
}
+

+

+
static void statlist (LexState *ls) {
+
  /* statlist -> { stat [';'] } */
+
  while (!block_follow(ls, 1)) {
+
    if (ls->t.token == TK_RETURN) {
+
      statement(ls);
+
      return;  /* 'return' must be last statement */
+
    }
+
    statement(ls);
+
  }
+
}
+

+

+
static void fieldsel (LexState *ls, expdesc *v) {
+
  /* fieldsel -> ['.' | ':'] NAME */
+
  FuncState *fs = ls->fs;
+
  expdesc key;
+
  luaK_exp2anyregup(fs, v);
+
  luaX_next(ls);  /* skip the dot or colon */
+
  checkname(ls, &key);
+
  luaK_indexed(fs, v, &key);
+
}
+

+

+
static void yindex (LexState *ls, expdesc *v) {
+
  /* index -> '[' expr ']' */
+
  luaX_next(ls);  /* skip the '[' */
+
  expr(ls, v);
+
  luaK_exp2val(ls->fs, v);
+
  checknext(ls, ']');
+
}
+

+

+
/*
+
** {======================================================================
+
** Rules for Constructors
+
** =======================================================================
+
*/
+

+

+
struct ConsControl {
+
  expdesc v;  /* last list item read */
+
  expdesc *t;  /* table descriptor */
+
  int nh;  /* total number of 'record' elements */
+
  int na;  /* total number of array elements */
+
  int tostore;  /* number of array elements pending to be stored */
+
};
+

+

+
static void recfield (LexState *ls, struct ConsControl *cc) {
+
  /* recfield -> (NAME | '['exp1']') = exp1 */
+
  FuncState *fs = ls->fs;
+
  int reg = ls->fs->freereg;
+
  expdesc key, val;
+
  int rkkey;
+
  if (ls->t.token == TK_NAME) {
+
    checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
+
    checkname(ls, &key);
+
  }
+
  else  /* ls->t.token == '[' */
+
    yindex(ls, &key);
+
  cc->nh++;
+
  checknext(ls, '=');
+
  rkkey = luaK_exp2RK(fs, &key);
+
  expr(ls, &val);
+
  luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));
+
  fs->freereg = reg;  /* free registers */
+
}
+

+

+
static void closelistfield (FuncState *fs, struct ConsControl *cc) {
+
  if (cc->v.k == VVOID) return;  /* there is no list item */
+
  luaK_exp2nextreg(fs, &cc->v);
+
  cc->v.k = VVOID;
+
  if (cc->tostore == LFIELDS_PER_FLUSH) {
+
    luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);  /* flush */
+
    cc->tostore = 0;  /* no more items pending */
+
  }
+
}
+

+

+
static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
+
  if (cc->tostore == 0) return;
+
  if (hasmultret(cc->v.k)) {
+
    luaK_setmultret(fs, &cc->v);
+
    luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
+
    cc->na--;  /* do not count last expression (unknown number of elements) */
+
  }
+
  else {
+
    if (cc->v.k != VVOID)
+
      luaK_exp2nextreg(fs, &cc->v);
+
    luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
+
  }
+
}
+

+

+
static void listfield (LexState *ls, struct ConsControl *cc) {
+
  /* listfield -> exp */
+
  expr(ls, &cc->v);
+
  checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
+
  cc->na++;
+
  cc->tostore++;
+
}
+

+

+
static void field (LexState *ls, struct ConsControl *cc) {
+
  /* field -> listfield | recfield */
+
  switch(ls->t.token) {
+
    case TK_NAME: {  /* may be 'listfield' or 'recfield' */
+
      if (luaX_lookahead(ls) != '=')  /* expression? */
+
        listfield(ls, cc);
+
      else
+
        recfield(ls, cc);
+
      break;
+
    }
+
    case '[': {
+
      recfield(ls, cc);
+
      break;
+
    }
+
    default: {
+
      listfield(ls, cc);
+
      break;
+
    }
+
  }
+
}
+

+

+
static void constructor (LexState *ls, expdesc *t) {
+
  /* constructor -> '{' [ field { sep field } [sep] ] '}'
+
     sep -> ',' | ';' */
+
  FuncState *fs = ls->fs;
+
  int line = ls->linenumber;
+
  int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
+
  struct ConsControl cc;
+
  cc.na = cc.nh = cc.tostore = 0;
+
  cc.t = t;
+
  init_exp(t, VRELOCABLE, pc);
+
  init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
+
  luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top */
+
  checknext(ls, '{');
+
  do {
+
    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
+
    if (ls->t.token == '}') break;
+
    closelistfield(fs, &cc);
+
    field(ls, &cc);
+
  } while (testnext(ls, ',') || testnext(ls, ';'));
+
  check_match(ls, '}', '{', line);
+
  lastlistfield(fs, &cc);
+
  SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
+
  SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh));  /* set initial table size */
+
}
+

+
/* }====================================================================== */
+

+

+

+
static void parlist (LexState *ls) {
+
  /* parlist -> [ param { ',' param } ] */
+
  FuncState *fs = ls->fs;
+
  Proto *f = fs->f;
+
  int nparams = 0;
+
  f->is_vararg = 0;
+
  if (ls->t.token != ')') {  /* is 'parlist' not empty? */
+
    do {
+
      switch (ls->t.token) {
+
        case TK_NAME: {  /* param -> NAME */
+
          new_localvar(ls, str_checkname(ls));
+
          nparams++;
+
          break;
+
        }
+
        case TK_DOTS: {  /* param -> '...' */
+
          luaX_next(ls);
+
          f->is_vararg = 1;  /* declared vararg */
+
          break;
+
        }
+
        default: luaX_syntaxerror(ls, "<name> or '...' expected");
+
      }
+
    } while (!f->is_vararg && testnext(ls, ','));
+
  }
+
  adjustlocalvars(ls, nparams);
+
  f->numparams = cast_byte(fs->nactvar);
+
  luaK_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
+
}
+

+

+
static void body (LexState *ls, expdesc *e, int ismethod, int line) {
+
  /* body ->  '(' parlist ')' block END */
+
  FuncState new_fs;
+
  BlockCnt bl;
+
  new_fs.f = addprototype(ls);
+
  new_fs.f->linedefined = line;
+
  open_func(ls, &new_fs, &bl);
+
  checknext(ls, '(');
+
  if (ismethod) {
+
    new_localvarliteral(ls, "self");  /* create 'self' parameter */
+
    adjustlocalvars(ls, 1);
+
  }
+
  parlist(ls);
+
  checknext(ls, ')');
+
  statlist(ls);
+
  new_fs.f->lastlinedefined = ls->linenumber;
+
  check_match(ls, TK_END, TK_FUNCTION, line);
+
  codeclosure(ls, e);
+
  close_func(ls);
+
}
+

+

+
static int explist (LexState *ls, expdesc *v) {
+
  /* explist -> expr { ',' expr } */
+
  int n = 1;  /* at least one expression */
+
  expr(ls, v);
+
  while (testnext(ls, ',')) {
+
    luaK_exp2nextreg(ls->fs, v);
+
    expr(ls, v);
+
    n++;
+
  }
+
  return n;
+
}
+

+

+
static void funcargs (LexState *ls, expdesc *f, int line) {
+
  FuncState *fs = ls->fs;
+
  expdesc args;
+
  int base, nparams;
+
  switch (ls->t.token) {
+
    case '(': {  /* funcargs -> '(' [ explist ] ')' */
+
      luaX_next(ls);
+
      if (ls->t.token == ')')  /* arg list is empty? */
+
        args.k = VVOID;
+
      else {
+
        explist(ls, &args);
+
        luaK_setmultret(fs, &args);
+
      }
+
      check_match(ls, ')', '(', line);
+
      break;
+
    }
+
    case '{': {  /* funcargs -> constructor */
+
      constructor(ls, &args);
+
      break;
+
    }
+
    case TK_STRING: {  /* funcargs -> STRING */
+
      codestring(ls, &args, ls->t.seminfo.ts);
+
      luaX_next(ls);  /* must use 'seminfo' before 'next' */
+
      break;
+
    }
+
    default: {
+
      luaX_syntaxerror(ls, "function arguments expected");
+
    }
+
  }
+
  lua_assert(f->k == VNONRELOC);
+
  base = f->u.info;  /* base register for call */
+
  if (hasmultret(args.k))
+
    nparams = LUA_MULTRET;  /* open call */
+
  else {
+
    if (args.k != VVOID)
+
      luaK_exp2nextreg(fs, &args);  /* close last argument */
+
    nparams = fs->freereg - (base+1);
+
  }
+
  init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
+
  luaK_fixline(fs, line);
+
  fs->freereg = base+1;  /* call remove function and arguments and leaves
+
                            (unless changed) one result */
+
}
+

+

+

+

+
/*
+
** {======================================================================
+
** Expression parsing
+
** =======================================================================
+
*/
+

+

+
static void primaryexp (LexState *ls, expdesc *v) {
+
  /* primaryexp -> NAME | '(' expr ')' */
+
  switch (ls->t.token) {
+
    case '(': {
+
      int line = ls->linenumber;
+
      luaX_next(ls);
+
      expr(ls, v);
+
      check_match(ls, ')', '(', line);
+
      luaK_dischargevars(ls->fs, v);
+
      return;
+
    }
+
    case TK_NAME: {
+
      singlevar(ls, v);
+
      return;
+
    }
+
    default: {
+
      luaX_syntaxerror(ls, "unexpected symbol");
+
    }
+
  }
+
}
+

+

+
static void suffixedexp (LexState *ls, expdesc *v) {
+
  /* suffixedexp ->
+
       primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
+
  FuncState *fs = ls->fs;
+
  int line = ls->linenumber;
+
  primaryexp(ls, v);
+
  for (;;) {
+
    switch (ls->t.token) {
+
      case '.': {  /* fieldsel */
+
        fieldsel(ls, v);
+
        break;
+
      }
+
      case '[': {  /* '[' exp1 ']' */
+
        expdesc key;
+
        luaK_exp2anyregup(fs, v);
+
        yindex(ls, &key);
+
        luaK_indexed(fs, v, &key);
+
        break;
+
      }
+
      case ':': {  /* ':' NAME funcargs */
+
        expdesc key;
+
        luaX_next(ls);
+
        checkname(ls, &key);
+
        luaK_self(fs, v, &key);
+
        funcargs(ls, v, line);
+
        break;
+
      }
+
      case '(': case TK_STRING: case '{': {  /* funcargs */
+
        luaK_exp2nextreg(fs, v);
+
        funcargs(ls, v, line);
+
        break;
+
      }
+
      default: return;
+
    }
+
  }
+
}
+

+

+
static void simpleexp (LexState *ls, expdesc *v) {
+
  /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... |
+
                  constructor | FUNCTION body | suffixedexp */
+
  switch (ls->t.token) {
+
    case TK_FLT: {
+
      init_exp(v, VKFLT, 0);
+
      v->u.nval = ls->t.seminfo.r;
+
      break;
+
    }
+
    case TK_INT: {
+
      init_exp(v, VKINT, 0);
+
      v->u.ival = ls->t.seminfo.i;
+
      break;
+
    }
+
    case TK_STRING: {
+
      codestring(ls, v, ls->t.seminfo.ts);
+
      break;
+
    }
+
    case TK_NIL: {
+
      init_exp(v, VNIL, 0);
+
      break;
+
    }
+
    case TK_TRUE: {
+
      init_exp(v, VTRUE, 0);
+
      break;
+
    }
+
    case TK_FALSE: {
+
      init_exp(v, VFALSE, 0);
+
      break;
+
    }
+
    case TK_DOTS: {  /* vararg */
+
      FuncState *fs = ls->fs;
+
      check_condition(ls, fs->f->is_vararg,
+
                      "cannot use '...' outside a vararg function");
+
      init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
+
      break;
+
    }
+
    case '{': {  /* constructor */
+
      constructor(ls, v);
+
      return;
+
    }
+
    case TK_FUNCTION: {
+
      luaX_next(ls);
+
      body(ls, v, 0, ls->linenumber);
+
      return;
+
    }
+
    default: {
+
      suffixedexp(ls, v);
+
      return;
+
    }
+
  }
+
  luaX_next(ls);
+
}
+

+

+
static UnOpr getunopr (int op) {
+
  switch (op) {
+
    case TK_NOT: return OPR_NOT;
+
    case '-': return OPR_MINUS;
+
    case '~': return OPR_BNOT;
+
    case '#': return OPR_LEN;
+
    default: return OPR_NOUNOPR;
+
  }
+
}
+

+

+
static BinOpr getbinopr (int op) {
+
  switch (op) {
+
    case '+': return OPR_ADD;
+
    case '-': return OPR_SUB;
+
    case '*': return OPR_MUL;
+
    case '%': return OPR_MOD;
+
    case '^': return OPR_POW;
+
    case '/': return OPR_DIV;
+
    case TK_IDIV: return OPR_IDIV;
+
    case '&': return OPR_BAND;
+
    case '|': return OPR_BOR;
+
    case '~': return OPR_BXOR;
+
    case TK_SHL: return OPR_SHL;
+
    case TK_SHR: return OPR_SHR;
+
    case TK_CONCAT: return OPR_CONCAT;
+
    case TK_NE: return OPR_NE;
+
    case TK_EQ: return OPR_EQ;
+
    case '<': return OPR_LT;
+
    case TK_LE: return OPR_LE;
+
    case '>': return OPR_GT;
+
    case TK_GE: return OPR_GE;
+
    case TK_AND: return OPR_AND;
+
    case TK_OR: return OPR_OR;
+
    default: return OPR_NOBINOPR;
+
  }
+
}
+

+

+
static const struct {
+
  lu_byte left;  /* left priority for each binary operator */
+
  lu_byte right; /* right priority */
+
} priority[] = {  /* ORDER OPR */
+
   {10, 10}, {10, 10},           /* '+' '-' */
+
   {11, 11}, {11, 11},           /* '*' '%' */
+
   {14, 13},                  /* '^' (right associative) */
+
   {11, 11}, {11, 11},           /* '/' '//' */
+
   {6, 6}, {4, 4}, {5, 5},   /* '&' '|' '~' */
+
   {7, 7}, {7, 7},           /* '<<' '>>' */
+
   {9, 8},                   /* '..' (right associative) */
+
   {3, 3}, {3, 3}, {3, 3},   /* ==, <, <= */
+
   {3, 3}, {3, 3}, {3, 3},   /* ~=, >, >= */
+
   {2, 2}, {1, 1}            /* and, or */
+
};
+

+
#define UNARY_PRIORITY	12  /* priority for unary operators */
+

+

+
/*
+
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
+
** where 'binop' is any binary operator with a priority higher than 'limit'
+
*/
+
static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
+
  BinOpr op;
+
  UnOpr uop;
+
  enterlevel(ls);
+
  uop = getunopr(ls->t.token);
+
  if (uop != OPR_NOUNOPR) {
+
    int line = ls->linenumber;
+
    luaX_next(ls);
+
    subexpr(ls, v, UNARY_PRIORITY);
+
    luaK_prefix(ls->fs, uop, v, line);
+
  }
+
  else simpleexp(ls, v);
+
  /* expand while operators have priorities higher than 'limit' */
+
  op = getbinopr(ls->t.token);
+
  while (op != OPR_NOBINOPR && priority[op].left > limit) {
+
    expdesc v2;
+
    BinOpr nextop;
+
    int line = ls->linenumber;
+
    luaX_next(ls);
+
    luaK_infix(ls->fs, op, v);
+
    /* read sub-expression with higher priority */
+
    nextop = subexpr(ls, &v2, priority[op].right);
+
    luaK_posfix(ls->fs, op, v, &v2, line);
+
    op = nextop;
+
  }
+
  leavelevel(ls);
+
  return op;  /* return first untreated operator */
+
}
+

+

+
static void expr (LexState *ls, expdesc *v) {
+
  subexpr(ls, v, 0);
+
}
+

+
/* }==================================================================== */
+

+

+

+
/*
+
** {======================================================================
+
** Rules for Statements
+
** =======================================================================
+
*/
+

+

+
static void block (LexState *ls) {
+
  /* block -> statlist */
+
  FuncState *fs = ls->fs;
+
  BlockCnt bl;
+
  enterblock(fs, &bl, 0);
+
  statlist(ls);
+
  leaveblock(fs);
+
}
+

+

+
/*
+
** structure to chain all variables in the left-hand side of an
+
** assignment
+
*/
+
struct LHS_assign {
+
  struct LHS_assign *prev;
+
  expdesc v;  /* variable (global, local, upvalue, or indexed) */
+
};
+

+

+
/*
+
** check whether, in an assignment to an upvalue/local variable, the
+
** upvalue/local variable is begin used in a previous assignment to a
+
** table. If so, save original upvalue/local value in a safe place and
+
** use this safe copy in the previous assignment.
+
*/
+
static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
+
  FuncState *fs = ls->fs;
+
  int extra = fs->freereg;  /* eventual position to save local variable */
+
  int conflict = 0;
+
  for (; lh; lh = lh->prev) {  /* check all previous assignments */
+
    if (lh->v.k == VINDEXED) {  /* assigning to a table? */
+
      /* table is the upvalue/local being assigned now? */
+
      if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
+
        conflict = 1;
+
        lh->v.u.ind.vt = VLOCAL;
+
        lh->v.u.ind.t = extra;  /* previous assignment will use safe copy */
+
      }
+
      /* index is the local being assigned? (index cannot be upvalue) */
+
      if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
+
        conflict = 1;
+
        lh->v.u.ind.idx = extra;  /* previous assignment will use safe copy */
+
      }
+
    }
+
  }
+
  if (conflict) {
+
    /* copy upvalue/local value to a temporary (in position 'extra') */
+
    OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
+
    luaK_codeABC(fs, op, extra, v->u.info, 0);
+
    luaK_reserveregs(fs, 1);
+
  }
+
}
+

+

+
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
+
  expdesc e;
+
  check_condition(ls, vkisvar(lh->v.k), "syntax error");
+
  if (testnext(ls, ',')) {  /* assignment -> ',' suffixedexp assignment */
+
    struct LHS_assign nv;
+
    nv.prev = lh;
+
    suffixedexp(ls, &nv.v);
+
    if (nv.v.k != VINDEXED)
+
      check_conflict(ls, lh, &nv.v);
+
    checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
+
                    "C levels");
+
    assignment(ls, &nv, nvars+1);
+
  }
+
  else {  /* assignment -> '=' explist */
+
    int nexps;
+
    checknext(ls, '=');
+
    nexps = explist(ls, &e);
+
    if (nexps != nvars)
+
      adjust_assign(ls, nvars, nexps, &e);
+
    else {
+
      luaK_setoneret(ls->fs, &e);  /* close last expression */
+
      luaK_storevar(ls->fs, &lh->v, &e);
+
      return;  /* avoid default */
+
    }
+
  }
+
  init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
+
  luaK_storevar(ls->fs, &lh->v, &e);
+
}
+

+

+
static int cond (LexState *ls) {
+
  /* cond -> exp */
+
  expdesc v;
+
  expr(ls, &v);  /* read condition */
+
  if (v.k == VNIL) v.k = VFALSE;  /* 'falses' are all equal here */
+
  luaK_goiftrue(ls->fs, &v);
+
  return v.f;
+
}
+

+

+
static void gotostat (LexState *ls, int pc) {
+
  int line = ls->linenumber;
+
  TString *label;
+
  int g;
+
  if (testnext(ls, TK_GOTO))
+
    label = str_checkname(ls);
+
  else {
+
    luaX_next(ls);  /* skip break */
+
    label = luaS_new(ls->L, "break");
+
  }
+
  g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
+
  findlabel(ls, g);  /* close it if label already defined */
+
}
+

+

+
/* check for repeated labels on the same block */
+
static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
+
  int i;
+
  for (i = fs->bl->firstlabel; i < ll->n; i++) {
+
    if (eqstr(label, ll->arr[i].name)) {
+
      const char *msg = luaO_pushfstring(fs->ls->L,
+
                          "label '%s' already defined on line %d",
+
                          getstr(label), ll->arr[i].line);
+
      semerror(fs->ls, msg);
+
    }
+
  }
+
}
+

+

+
/* skip no-op statements */
+
static void skipnoopstat (LexState *ls) {
+
  while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
+
    statement(ls);
+
}
+

+

+
static void labelstat (LexState *ls, TString *label, int line) {
+
  /* label -> '::' NAME '::' */
+
  FuncState *fs = ls->fs;
+
  Labellist *ll = &ls->dyd->label;
+
  int l;  /* index of new label being created */
+
  checkrepeated(fs, ll, label);  /* check for repeated labels */
+
  checknext(ls, TK_DBCOLON);  /* skip double colon */
+
  /* create new entry for this label */
+
  l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
+
  skipnoopstat(ls);  /* skip other no-op statements */
+
  if (block_follow(ls, 0)) {  /* label is last no-op statement in the block? */
+
    /* assume that locals are already out of scope */
+
    ll->arr[l].nactvar = fs->bl->nactvar;
+
  }
+
  findgotos(ls, &ll->arr[l]);
+
}
+

+

+
static void whilestat (LexState *ls, int line) {
+
  /* whilestat -> WHILE cond DO block END */
+
  FuncState *fs = ls->fs;
+
  int whileinit;
+
  int condexit;
+
  BlockCnt bl;
+
  luaX_next(ls);  /* skip WHILE */
+
  whileinit = luaK_getlabel(fs);
+
  condexit = cond(ls);
+
  enterblock(fs, &bl, 1);
+
  checknext(ls, TK_DO);
+
  block(ls);
+
  luaK_jumpto(fs, whileinit);
+
  check_match(ls, TK_END, TK_WHILE, line);
+
  leaveblock(fs);
+
  luaK_patchtohere(fs, condexit);  /* false conditions finish the loop */
+
}
+

+

+
static void repeatstat (LexState *ls, int line) {
+
  /* repeatstat -> REPEAT block UNTIL cond */
+
  int condexit;
+
  FuncState *fs = ls->fs;
+
  int repeat_init = luaK_getlabel(fs);
+
  BlockCnt bl1, bl2;
+
  enterblock(fs, &bl1, 1);  /* loop block */
+
  enterblock(fs, &bl2, 0);  /* scope block */
+
  luaX_next(ls);  /* skip REPEAT */
+
  statlist(ls);
+
  check_match(ls, TK_UNTIL, TK_REPEAT, line);
+
  condexit = cond(ls);  /* read condition (inside scope block) */
+
  if (bl2.upval)  /* upvalues? */
+
    luaK_patchclose(fs, condexit, bl2.nactvar);
+
  leaveblock(fs);  /* finish scope */
+
  luaK_patchlist(fs, condexit, repeat_init);  /* close the loop */
+
  leaveblock(fs);  /* finish loop */
+
}
+

+

+
static int exp1 (LexState *ls) {
+
  expdesc e;
+
  int reg;
+
  expr(ls, &e);
+
  luaK_exp2nextreg(ls->fs, &e);
+
  lua_assert(e.k == VNONRELOC);
+
  reg = e.u.info;
+
  return reg;
+
}
+

+

+
static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
+
  /* forbody -> DO block */
+
  BlockCnt bl;
+
  FuncState *fs = ls->fs;
+
  int prep, endfor;
+
  adjustlocalvars(ls, 3);  /* control variables */
+
  checknext(ls, TK_DO);
+
  prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
+
  enterblock(fs, &bl, 0);  /* scope for declared variables */
+
  adjustlocalvars(ls, nvars);
+
  luaK_reserveregs(fs, nvars);
+
  block(ls);
+
  leaveblock(fs);  /* end of scope for declared variables */
+
  luaK_patchtohere(fs, prep);
+
  if (isnum)  /* numeric for? */
+
    endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);
+
  else {  /* generic for */
+
    luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
+
    luaK_fixline(fs, line);
+
    endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);
+
  }
+
  luaK_patchlist(fs, endfor, prep + 1);
+
  luaK_fixline(fs, line);
+
}
+

+

+
static void fornum (LexState *ls, TString *varname, int line) {
+
  /* fornum -> NAME = exp1,exp1[,exp1] forbody */
+
  FuncState *fs = ls->fs;
+
  int base = fs->freereg;
+
  new_localvarliteral(ls, "(for index)");
+
  new_localvarliteral(ls, "(for limit)");
+
  new_localvarliteral(ls, "(for step)");
+
  new_localvar(ls, varname);
+
  checknext(ls, '=');
+
  exp1(ls);  /* initial value */
+
  checknext(ls, ',');
+
  exp1(ls);  /* limit */
+
  if (testnext(ls, ','))
+
    exp1(ls);  /* optional step */
+
  else {  /* default step = 1 */
+
    luaK_codek(fs, fs->freereg, luaK_intK(fs, 1));
+
    luaK_reserveregs(fs, 1);
+
  }
+
  forbody(ls, base, line, 1, 1);
+
}
+

+

+
static void forlist (LexState *ls, TString *indexname) {
+
  /* forlist -> NAME {,NAME} IN explist forbody */
+
  FuncState *fs = ls->fs;
+
  expdesc e;
+
  int nvars = 4;  /* gen, state, control, plus at least one declared var */
+
  int line;
+
  int base = fs->freereg;
+
  /* create control variables */
+
  new_localvarliteral(ls, "(for generator)");
+
  new_localvarliteral(ls, "(for state)");
+
  new_localvarliteral(ls, "(for control)");
+
  /* create declared variables */
+
  new_localvar(ls, indexname);
+
  while (testnext(ls, ',')) {
+
    new_localvar(ls, str_checkname(ls));
+
    nvars++;
+
  }
+
  checknext(ls, TK_IN);
+
  line = ls->linenumber;
+
  adjust_assign(ls, 3, explist(ls, &e), &e);
+
  luaK_checkstack(fs, 3);  /* extra space to call generator */
+
  forbody(ls, base, line, nvars - 3, 0);
+
}
+

+

+
static void forstat (LexState *ls, int line) {
+
  /* forstat -> FOR (fornum | forlist) END */
+
  FuncState *fs = ls->fs;
+
  TString *varname;
+
  BlockCnt bl;
+
  enterblock(fs, &bl, 1);  /* scope for loop and control variables */
+
  luaX_next(ls);  /* skip 'for' */
+
  varname = str_checkname(ls);  /* first variable name */
+
  switch (ls->t.token) {
+
    case '=': fornum(ls, varname, line); break;
+
    case ',': case TK_IN: forlist(ls, varname); break;
+
    default: luaX_syntaxerror(ls, "'=' or 'in' expected");
+
  }
+
  check_match(ls, TK_END, TK_FOR, line);
+
  leaveblock(fs);  /* loop scope ('break' jumps to this point) */
+
}
+

+

+
static void test_then_block (LexState *ls, int *escapelist) {
+
  /* test_then_block -> [IF | ELSEIF] cond THEN block */
+
  BlockCnt bl;
+
  FuncState *fs = ls->fs;
+
  expdesc v;
+
  int jf;  /* instruction to skip 'then' code (if condition is false) */
+
  luaX_next(ls);  /* skip IF or ELSEIF */
+
  expr(ls, &v);  /* read condition */
+
  checknext(ls, TK_THEN);
+
  if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
+
    luaK_goiffalse(ls->fs, &v);  /* will jump to label if condition is true */
+
    enterblock(fs, &bl, 0);  /* must enter block before 'goto' */
+
    gotostat(ls, v.t);  /* handle goto/break */
+
    while (testnext(ls, ';')) {}  /* skip colons */
+
    if (block_follow(ls, 0)) {  /* 'goto' is the entire block? */
+
      leaveblock(fs);
+
      return;  /* and that is it */
+
    }
+
    else  /* must skip over 'then' part if condition is false */
+
      jf = luaK_jump(fs);
+
  }
+
  else {  /* regular case (not goto/break) */
+
    luaK_goiftrue(ls->fs, &v);  /* skip over block if condition is false */
+
    enterblock(fs, &bl, 0);
+
    jf = v.f;
+
  }
+
  statlist(ls);  /* 'then' part */
+
  leaveblock(fs);
+
  if (ls->t.token == TK_ELSE ||
+
      ls->t.token == TK_ELSEIF)  /* followed by 'else'/'elseif'? */
+
    luaK_concat(fs, escapelist, luaK_jump(fs));  /* must jump over it */
+
  luaK_patchtohere(fs, jf);
+
}
+

+

+
static void ifstat (LexState *ls, int line) {
+
  /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
+
  FuncState *fs = ls->fs;
+
  int escapelist = NO_JUMP;  /* exit list for finished parts */
+
  test_then_block(ls, &escapelist);  /* IF cond THEN block */
+
  while (ls->t.token == TK_ELSEIF)
+
    test_then_block(ls, &escapelist);  /* ELSEIF cond THEN block */
+
  if (testnext(ls, TK_ELSE))
+
    block(ls);  /* 'else' part */
+
  check_match(ls, TK_END, TK_IF, line);
+
  luaK_patchtohere(fs, escapelist);  /* patch escape list to 'if' end */
+
}
+

+

+
static void localfunc (LexState *ls) {
+
  expdesc b;
+
  FuncState *fs = ls->fs;
+
  new_localvar(ls, str_checkname(ls));  /* new local variable */
+
  adjustlocalvars(ls, 1);  /* enter its scope */
+
  body(ls, &b, 0, ls->linenumber);  /* function created in next register */
+
  /* debug information will only see the variable after this point! */
+
  getlocvar(fs, b.u.info)->startpc = fs->pc;
+
}
+

+

+
static void localstat (LexState *ls) {
+
  /* stat -> LOCAL NAME {',' NAME} ['=' explist] */
+
  int nvars = 0;
+
  int nexps;
+
  expdesc e;
+
  do {
+
    new_localvar(ls, str_checkname(ls));
+
    nvars++;
+
  } while (testnext(ls, ','));
+
  if (testnext(ls, '='))
+
    nexps = explist(ls, &e);
+
  else {
+
    e.k = VVOID;
+
    nexps = 0;
+
  }
+
  adjust_assign(ls, nvars, nexps, &e);
+
  adjustlocalvars(ls, nvars);
+
}
+

+

+
static int funcname (LexState *ls, expdesc *v) {
+
  /* funcname -> NAME {fieldsel} [':' NAME] */
+
  int ismethod = 0;
+
  singlevar(ls, v);
+
  while (ls->t.token == '.')
+
    fieldsel(ls, v);
+
  if (ls->t.token == ':') {
+
    ismethod = 1;
+
    fieldsel(ls, v);
+
  }
+
  return ismethod;
+
}
+

+

+
static void funcstat (LexState *ls, int line) {
+
  /* funcstat -> FUNCTION funcname body */
+
  int ismethod;
+
  expdesc v, b;
+
  luaX_next(ls);  /* skip FUNCTION */
+
  ismethod = funcname(ls, &v);
+
  body(ls, &b, ismethod, line);
+
  luaK_storevar(ls->fs, &v, &b);
+
  luaK_fixline(ls->fs, line);  /* definition "happens" in the first line */
+
}
+

+

+
static void exprstat (LexState *ls) {
+
  /* stat -> func | assignment */
+
  FuncState *fs = ls->fs;
+
  struct LHS_assign v;
+
  suffixedexp(ls, &v.v);
+
  if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
+
    v.prev = NULL;
+
    assignment(ls, &v, 1);
+
  }
+
  else {  /* stat -> func */
+
    check_condition(ls, v.v.k == VCALL, "syntax error");
+
    SETARG_C(getinstruction(fs, &v.v), 1);  /* call statement uses no results */
+
  }
+
}
+

+

+
static void retstat (LexState *ls) {
+
  /* stat -> RETURN [explist] [';'] */
+
  FuncState *fs = ls->fs;
+
  expdesc e;
+
  int first, nret;  /* registers with returned values */
+
  if (block_follow(ls, 1) || ls->t.token == ';')
+
    first = nret = 0;  /* return no values */
+
  else {
+
    nret = explist(ls, &e);  /* optional return values */
+
    if (hasmultret(e.k)) {
+
      luaK_setmultret(fs, &e);
+
      if (e.k == VCALL && nret == 1) {  /* tail call? */
+
        SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL);
+
        lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar);
+
      }
+
      first = fs->nactvar;
+
      nret = LUA_MULTRET;  /* return all values */
+
    }
+
    else {
+
      if (nret == 1)  /* only one single value? */
+
        first = luaK_exp2anyreg(fs, &e);
+
      else {
+
        luaK_exp2nextreg(fs, &e);  /* values must go to the stack */
+
        first = fs->nactvar;  /* return all active values */
+
        lua_assert(nret == fs->freereg - first);
+
      }
+
    }
+
  }
+
  luaK_ret(fs, first, nret);
+
  testnext(ls, ';');  /* skip optional semicolon */
+
}
+

+

+
static void statement (LexState *ls) {
+
  int line = ls->linenumber;  /* may be needed for error messages */
+
  enterlevel(ls);
+
  switch (ls->t.token) {
+
    case ';': {  /* stat -> ';' (empty statement) */
+
      luaX_next(ls);  /* skip ';' */
+
      break;
+
    }
+
    case TK_IF: {  /* stat -> ifstat */
+
      ifstat(ls, line);
+
      break;
+
    }
+
    case TK_WHILE: {  /* stat -> whilestat */
+
      whilestat(ls, line);
+
      break;
+
    }
+
    case TK_DO: {  /* stat -> DO block END */
+
      luaX_next(ls);  /* skip DO */
+
      block(ls);
+
      check_match(ls, TK_END, TK_DO, line);
+
      break;
+
    }
+
    case TK_FOR: {  /* stat -> forstat */
+
      forstat(ls, line);
+
      break;
+
    }
+
    case TK_REPEAT: {  /* stat -> repeatstat */
+
      repeatstat(ls, line);
+
      break;
+
    }
+
    case TK_FUNCTION: {  /* stat -> funcstat */
+
      funcstat(ls, line);
+
      break;
+
    }
+
    case TK_LOCAL: {  /* stat -> localstat */
+
      luaX_next(ls);  /* skip LOCAL */
+
      if (testnext(ls, TK_FUNCTION))  /* local function? */
+
        localfunc(ls);
+
      else
+
        localstat(ls);
+
      break;
+
    }
+
    case TK_DBCOLON: {  /* stat -> label */
+
      luaX_next(ls);  /* skip double colon */
+
      labelstat(ls, str_checkname(ls), line);
+
      break;
+
    }
+
    case TK_RETURN: {  /* stat -> retstat */
+
      luaX_next(ls);  /* skip RETURN */
+
      retstat(ls);
+
      break;
+
    }
+
    case TK_BREAK:   /* stat -> breakstat */
+
    case TK_GOTO: {  /* stat -> 'goto' NAME */
+
      gotostat(ls, luaK_jump(ls->fs));
+
      break;
+
    }
+
    default: {  /* stat -> func | assignment */
+
      exprstat(ls);
+
      break;
+
    }
+
  }
+
  lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
+
             ls->fs->freereg >= ls->fs->nactvar);
+
  ls->fs->freereg = ls->fs->nactvar;  /* free registers */
+
  leavelevel(ls);
+
}
+

+
/* }====================================================================== */
+

+

+
/*
+
** compiles the main function, which is a regular vararg function with an
+
** upvalue named LUA_ENV
+
*/
+
static void mainfunc (LexState *ls, FuncState *fs) {
+
  BlockCnt bl;
+
  expdesc v;
+
  open_func(ls, fs, &bl);
+
  fs->f->is_vararg = 1;  /* main function is always declared vararg */
+
  init_exp(&v, VLOCAL, 0);  /* create and... */
+
  newupvalue(fs, ls->envn, &v);  /* ...set environment upvalue */
+
  luaX_next(ls);  /* read first token */
+
  statlist(ls);  /* parse main body */
+
  check(ls, TK_EOS);
+
  close_func(ls);
+
}
+

+

+
LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
+
                       Dyndata *dyd, const char *name, int firstchar) {
+
  LexState lexstate;
+
  FuncState funcstate;
+
  LClosure *cl = luaF_newLclosure(L, 1);  /* create main closure */
+
  setclLvalue(L, L->top, cl);  /* anchor it (to avoid being collected) */
+
  luaD_inctop(L);
+
  lexstate.h = luaH_new(L);  /* create table for scanner */
+
  sethvalue(L, L->top, lexstate.h);  /* anchor it */
+
  luaD_inctop(L);
+
  funcstate.f = cl->p = luaF_newproto(L);
+
  funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */
+
  lua_assert(iswhite(funcstate.f));  /* do not need barrier here */
+
  lexstate.buff = buff;
+
  lexstate.dyd = dyd;
+
  dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
+
  luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
+
  mainfunc(&lexstate, &funcstate);
+
  lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
+
  /* all scopes should be correctly finished */
+
  lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
+
  L->top--;  /* remove scanner's table */
+
  return cl;  /* closure is on the stack, too */
+
}
+

added external/lua/src/lparser.h
@@ -0,0 +1,133 @@
+
/*
+
** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Lua Parser
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lparser_h
+
#define lparser_h
+

+
#include "llimits.h"
+
#include "lobject.h"
+
#include "lzio.h"
+

+

+
/*
+
** Expression and variable descriptor.
+
** Code generation for variables and expressions can be delayed to allow
+
** optimizations; An 'expdesc' structure describes a potentially-delayed
+
** variable/expression. It has a description of its "main" value plus a
+
** list of conditional jumps that can also produce its value (generated
+
** by short-circuit operators 'and'/'or').
+
*/
+

+
/* kinds of variables/expressions */
+
typedef enum {
+
  VVOID,  /* when 'expdesc' describes the last expression a list,
+
             this kind means an empty list (so, no expression) */
+
  VNIL,  /* constant nil */
+
  VTRUE,  /* constant true */
+
  VFALSE,  /* constant false */
+
  VK,  /* constant in 'k'; info = index of constant in 'k' */
+
  VKFLT,  /* floating constant; nval = numerical float value */
+
  VKINT,  /* integer constant; nval = numerical integer value */
+
  VNONRELOC,  /* expression has its value in a fixed register;
+
                 info = result register */
+
  VLOCAL,  /* local variable; info = local register */
+
  VUPVAL,  /* upvalue variable; info = index of upvalue in 'upvalues' */
+
  VINDEXED,  /* indexed variable;
+
                ind.vt = whether 't' is register or upvalue;
+
                ind.t = table register or upvalue;
+
                ind.idx = key's R/K index */
+
  VJMP,  /* expression is a test/comparison;
+
            info = pc of corresponding jump instruction */
+
  VRELOCABLE,  /* expression can put result in any register;
+
                  info = instruction pc */
+
  VCALL,  /* expression is a function call; info = instruction pc */
+
  VVARARG  /* vararg expression; info = instruction pc */
+
} expkind;
+

+

+
#define vkisvar(k)	(VLOCAL <= (k) && (k) <= VINDEXED)
+
#define vkisinreg(k)	((k) == VNONRELOC || (k) == VLOCAL)
+

+
typedef struct expdesc {
+
  expkind k;
+
  union {
+
    lua_Integer ival;    /* for VKINT */
+
    lua_Number nval;  /* for VKFLT */
+
    int info;  /* for generic use */
+
    struct {  /* for indexed variables (VINDEXED) */
+
      short idx;  /* index (R/K) */
+
      lu_byte t;  /* table (register or upvalue) */
+
      lu_byte vt;  /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
+
    } ind;
+
  } u;
+
  int t;  /* patch list of 'exit when true' */
+
  int f;  /* patch list of 'exit when false' */
+
} expdesc;
+

+

+
/* description of active local variable */
+
typedef struct Vardesc {
+
  short idx;  /* variable index in stack */
+
} Vardesc;
+

+

+
/* description of pending goto statements and label statements */
+
typedef struct Labeldesc {
+
  TString *name;  /* label identifier */
+
  int pc;  /* position in code */
+
  int line;  /* line where it appeared */
+
  lu_byte nactvar;  /* local level where it appears in current block */
+
} Labeldesc;
+

+

+
/* list of labels or gotos */
+
typedef struct Labellist {
+
  Labeldesc *arr;  /* array */
+
  int n;  /* number of entries in use */
+
  int size;  /* array size */
+
} Labellist;
+

+

+
/* dynamic structures used by the parser */
+
typedef struct Dyndata {
+
  struct {  /* list of active local variables */
+
    Vardesc *arr;
+
    int n;
+
    int size;
+
  } actvar;
+
  Labellist gt;  /* list of pending gotos */
+
  Labellist label;   /* list of active labels */
+
} Dyndata;
+

+

+
/* control of blocks */
+
struct BlockCnt;  /* defined in lparser.c */
+

+

+
/* state needed to generate code for a given function */
+
typedef struct FuncState {
+
  Proto *f;  /* current function header */
+
  struct FuncState *prev;  /* enclosing function */
+
  struct LexState *ls;  /* lexical state */
+
  struct BlockCnt *bl;  /* chain of current blocks */
+
  int pc;  /* next position to code (equivalent to 'ncode') */
+
  int lasttarget;   /* 'label' of last 'jump label' */
+
  int jpc;  /* list of pending jumps to 'pc' */
+
  int nk;  /* number of elements in 'k' */
+
  int np;  /* number of elements in 'p' */
+
  int firstlocal;  /* index of first local var (in Dyndata array) */
+
  short nlocvars;  /* number of elements in 'f->locvars' */
+
  lu_byte nactvar;  /* number of active local variables */
+
  lu_byte nups;  /* number of upvalues */
+
  lu_byte freereg;  /* first free register */
+
} FuncState;
+

+

+
LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
+
                                 Dyndata *dyd, const char *name, int firstchar);
+

+

+
#endif
added external/lua/src/lprefix.h
@@ -0,0 +1,45 @@
+
/*
+
** $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
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lprefix_h
+
#define lprefix_h
+

+

+
/*
+
** Allows POSIX/XSI stuff
+
*/
+
#if !defined(LUA_USE_C89)	/* { */
+

+
#if !defined(_XOPEN_SOURCE)
+
#define _XOPEN_SOURCE           600
+
#elif _XOPEN_SOURCE == 0
+
#undef _XOPEN_SOURCE  /* use -D_XOPEN_SOURCE=0 to undefine it */
+
#endif
+

+
/*
+
** Allows manipulation of large files in gcc and some other compilers
+
*/
+
#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS)
+
#define _LARGEFILE_SOURCE       1
+
#define _FILE_OFFSET_BITS       64
+
#endif
+

+
#endif				/* } */
+

+

+
/*
+
** Windows stuff
+
*/
+
#if defined(_WIN32) 	/* { */
+

+
#if !defined(_CRT_SECURE_NO_WARNINGS)
+
#define _CRT_SECURE_NO_WARNINGS  /* avoid warnings about ISO C functions */
+
#endif
+

+
#endif			/* } */
+

+
#endif
+

added external/lua/src/lstate.c
@@ -0,0 +1,347 @@
+
/*
+
** $Id: lstate.c,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
+
** Global State
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lstate_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <stddef.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lapi.h"
+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lfunc.h"
+
#include "lgc.h"
+
#include "llex.h"
+
#include "lmem.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "ltm.h"
+

+

+
#if !defined(LUAI_GCPAUSE)
+
#define LUAI_GCPAUSE	200  /* 200% */
+
#endif
+

+
#if !defined(LUAI_GCMUL)
+
#define LUAI_GCMUL	200 /* GC runs 'twice the speed' of memory allocation */
+
#endif
+

+

+
/*
+
** a macro to help the creation of a unique random seed when a state is
+
** created; the seed is used to randomize hashes.
+
*/
+
#if !defined(luai_makeseed)
+
#include <time.h>
+
#define luai_makeseed()		cast(unsigned int, time(NULL))
+
#endif
+

+

+

+
/*
+
** thread state + extra space
+
*/
+
typedef struct LX {
+
  lu_byte extra_[LUA_EXTRASPACE];
+
  lua_State l;
+
} LX;
+

+

+
/*
+
** Main thread combines a thread state and the global state
+
*/
+
typedef struct LG {
+
  LX l;
+
  global_State g;
+
} LG;
+

+

+

+
#define fromstate(L)	(cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
+

+

+
/*
+
** Compute an initial seed as random as possible. Rely on Address Space
+
** Layout Randomization (if present) to increase randomness..
+
*/
+
#define addbuff(b,p,e) \
+
  { size_t t = cast(size_t, e); \
+
    memcpy(b + p, &t, sizeof(t)); p += sizeof(t); }
+

+
static unsigned int makeseed (lua_State *L) {
+
  char buff[4 * sizeof(size_t)];
+
  unsigned int h = luai_makeseed();
+
  int p = 0;
+
  addbuff(buff, p, L);  /* heap variable */
+
  addbuff(buff, p, &h);  /* local variable */
+
  addbuff(buff, p, luaO_nilobject);  /* global variable */
+
  addbuff(buff, p, &lua_newstate);  /* public function */
+
  lua_assert(p == sizeof(buff));
+
  return luaS_hash(buff, p, h);
+
}
+

+

+
/*
+
** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
+
** invariant (and avoiding underflows in 'totalbytes')
+
*/
+
void luaE_setdebt (global_State *g, l_mem debt) {
+
  l_mem tb = gettotalbytes(g);
+
  lua_assert(tb > 0);
+
  if (debt < tb - MAX_LMEM)
+
    debt = tb - MAX_LMEM;  /* will make 'totalbytes == MAX_LMEM' */
+
  g->totalbytes = tb - debt;
+
  g->GCdebt = debt;
+
}
+

+

+
CallInfo *luaE_extendCI (lua_State *L) {
+
  CallInfo *ci = luaM_new(L, CallInfo);
+
  lua_assert(L->ci->next == NULL);
+
  L->ci->next = ci;
+
  ci->previous = L->ci;
+
  ci->next = NULL;
+
  L->nci++;
+
  return ci;
+
}
+

+

+
/*
+
** free all CallInfo structures not in use by a thread
+
*/
+
void luaE_freeCI (lua_State *L) {
+
  CallInfo *ci = L->ci;
+
  CallInfo *next = ci->next;
+
  ci->next = NULL;
+
  while ((ci = next) != NULL) {
+
    next = ci->next;
+
    luaM_free(L, ci);
+
    L->nci--;
+
  }
+
}
+

+

+
/*
+
** free half of the CallInfo structures not in use by a thread
+
*/
+
void luaE_shrinkCI (lua_State *L) {
+
  CallInfo *ci = L->ci;
+
  CallInfo *next2;  /* next's next */
+
  /* while there are two nexts */
+
  while (ci->next != NULL && (next2 = ci->next->next) != NULL) {
+
    luaM_free(L, ci->next);  /* free next */
+
    L->nci--;
+
    ci->next = next2;  /* remove 'next' from the list */
+
    next2->previous = ci;
+
    ci = next2;  /* keep next's next */
+
  }
+
}
+

+

+
static void stack_init (lua_State *L1, lua_State *L) {
+
  int i; CallInfo *ci;
+
  /* initialize stack array */
+
  L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
+
  L1->stacksize = BASIC_STACK_SIZE;
+
  for (i = 0; i < BASIC_STACK_SIZE; i++)
+
    setnilvalue(L1->stack + i);  /* erase new stack */
+
  L1->top = L1->stack;
+
  L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
+
  /* initialize first ci */
+
  ci = &L1->base_ci;
+
  ci->next = ci->previous = NULL;
+
  ci->callstatus = 0;
+
  ci->func = L1->top;
+
  setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
+
  ci->top = L1->top + LUA_MINSTACK;
+
  L1->ci = ci;
+
}
+

+

+
static void freestack (lua_State *L) {
+
  if (L->stack == NULL)
+
    return;  /* stack not completely built yet */
+
  L->ci = &L->base_ci;  /* free the entire 'ci' list */
+
  luaE_freeCI(L);
+
  lua_assert(L->nci == 0);
+
  luaM_freearray(L, L->stack, L->stacksize);  /* free stack array */
+
}
+

+

+
/*
+
** Create registry table and its predefined values
+
*/
+
static void init_registry (lua_State *L, global_State *g) {
+
  TValue temp;
+
  /* create registry */
+
  Table *registry = luaH_new(L);
+
  sethvalue(L, &g->l_registry, registry);
+
  luaH_resize(L, registry, LUA_RIDX_LAST, 0);
+
  /* registry[LUA_RIDX_MAINTHREAD] = L */
+
  setthvalue(L, &temp, L);  /* temp = L */
+
  luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
+
  /* registry[LUA_RIDX_GLOBALS] = table of globals */
+
  sethvalue(L, &temp, luaH_new(L));  /* temp = new table (global table) */
+
  luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
+
}
+

+

+
/*
+
** open parts of the state that may cause memory-allocation errors.
+
** ('g->version' != NULL flags that the state was completely build)
+
*/
+
static void f_luaopen (lua_State *L, void *ud) {
+
  global_State *g = G(L);
+
  UNUSED(ud);
+
  stack_init(L, L);  /* init stack */
+
  init_registry(L, g);
+
  luaS_init(L);
+
  luaT_init(L);
+
  luaX_init(L);
+
  g->gcrunning = 1;  /* allow gc */
+
  g->version = lua_version(NULL);
+
  luai_userstateopen(L);
+
}
+

+

+
/*
+
** preinitialize a thread with consistent values without allocating
+
** any memory (to avoid errors)
+
*/
+
static void preinit_thread (lua_State *L, global_State *g) {
+
  G(L) = g;
+
  L->stack = NULL;
+
  L->ci = NULL;
+
  L->nci = 0;
+
  L->stacksize = 0;
+
  L->twups = L;  /* thread has no upvalues */
+
  L->errorJmp = NULL;
+
  L->nCcalls = 0;
+
  L->hook = NULL;
+
  L->hookmask = 0;
+
  L->basehookcount = 0;
+
  L->allowhook = 1;
+
  resethookcount(L);
+
  L->openupval = NULL;
+
  L->nny = 1;
+
  L->status = LUA_OK;
+
  L->errfunc = 0;
+
}
+

+

+
static void close_state (lua_State *L) {
+
  global_State *g = G(L);
+
  luaF_close(L, L->stack);  /* close all upvalues for this thread */
+
  luaC_freeallobjects(L);  /* collect all objects */
+
  if (g->version)  /* closing a fully built state? */
+
    luai_userstateclose(L);
+
  luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
+
  freestack(L);
+
  lua_assert(gettotalbytes(g) == sizeof(LG));
+
  (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);  /* free main block */
+
}
+

+

+
LUA_API lua_State *lua_newthread (lua_State *L) {
+
  global_State *g = G(L);
+
  lua_State *L1;
+
  lua_lock(L);
+
  luaC_checkGC(L);
+
  /* create new thread */
+
  L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
+
  L1->marked = luaC_white(g);
+
  L1->tt = LUA_TTHREAD;
+
  /* link it on list 'allgc' */
+
  L1->next = g->allgc;
+
  g->allgc = obj2gco(L1);
+
  /* anchor it on L stack */
+
  setthvalue(L, L->top, L1);
+
  api_incr_top(L);
+
  preinit_thread(L1, g);
+
  L1->hookmask = L->hookmask;
+
  L1->basehookcount = L->basehookcount;
+
  L1->hook = L->hook;
+
  resethookcount(L1);
+
  /* initialize L1 extra space */
+
  memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread),
+
         LUA_EXTRASPACE);
+
  luai_userstatethread(L, L1);
+
  stack_init(L1, L);  /* init stack */
+
  lua_unlock(L);
+
  return L1;
+
}
+

+

+
void luaE_freethread (lua_State *L, lua_State *L1) {
+
  LX *l = fromstate(L1);
+
  luaF_close(L1, L1->stack);  /* close all upvalues for this thread */
+
  lua_assert(L1->openupval == NULL);
+
  luai_userstatefree(L, L1);
+
  freestack(L1);
+
  luaM_free(L, l);
+
}
+

+

+
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
+
  int i;
+
  lua_State *L;
+
  global_State *g;
+
  LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
+
  if (l == NULL) return NULL;
+
  L = &l->l.l;
+
  g = &l->g;
+
  L->next = NULL;
+
  L->tt = LUA_TTHREAD;
+
  g->currentwhite = bitmask(WHITE0BIT);
+
  L->marked = luaC_white(g);
+
  preinit_thread(L, g);
+
  g->frealloc = f;
+
  g->ud = ud;
+
  g->mainthread = L;
+
  g->seed = makeseed(L);
+
  g->gcrunning = 0;  /* no GC while building state */
+
  g->GCestimate = 0;
+
  g->strt.size = g->strt.nuse = 0;
+
  g->strt.hash = NULL;
+
  setnilvalue(&g->l_registry);
+
  g->panic = NULL;
+
  g->version = NULL;
+
  g->gcstate = GCSpause;
+
  g->gckind = KGC_NORMAL;
+
  g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL;
+
  g->sweepgc = NULL;
+
  g->gray = g->grayagain = NULL;
+
  g->weak = g->ephemeron = g->allweak = NULL;
+
  g->twups = NULL;
+
  g->totalbytes = sizeof(LG);
+
  g->GCdebt = 0;
+
  g->gcfinnum = 0;
+
  g->gcpause = LUAI_GCPAUSE;
+
  g->gcstepmul = LUAI_GCMUL;
+
  for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
+
  if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
+
    /* memory allocation error: free partial state */
+
    close_state(L);
+
    L = NULL;
+
  }
+
  return L;
+
}
+

+

+
LUA_API void lua_close (lua_State *L) {
+
  L = G(L)->mainthread;  /* only the main thread can be closed */
+
  lua_lock(L);
+
  close_state(L);
+
}
+

+

added external/lua/src/lstate.h
@@ -0,0 +1,253 @@
+
/*
+
** $Id: lstate.h,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
+
** Global State
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lstate_h
+
#define lstate_h
+

+
#include "lua.h"
+

+
#include "lobject.h"
+
#include "ltm.h"
+
#include "lzio.h"
+

+

+
/*
+

+
** Some notes about garbage-collected objects: All objects in Lua must
+
** be kept somehow accessible until being freed, so all objects always
+
** belong to one (and only one) of these lists, using field 'next' of
+
** the 'CommonHeader' for the link:
+
**
+
** 'allgc': all objects not marked for finalization;
+
** 'finobj': all objects marked for finalization;
+
** 'tobefnz': all objects ready to be finalized;
+
** 'fixedgc': all objects that are not to be collected (currently
+
** 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.
+

+
*/
+

+

+
struct lua_longjmp;  /* defined in ldo.c */
+

+

+
/*
+
** Atomic type (relative to signals) to better ensure that 'lua_sethook'
+
** is thread safe
+
*/
+
#if !defined(l_signalT)
+
#include <signal.h>
+
#define l_signalT	sig_atomic_t
+
#endif
+

+

+
/* extra stack space to handle TM calls and some other extras */
+
#define EXTRA_STACK   5
+

+

+
#define BASIC_STACK_SIZE        (2*LUA_MINSTACK)
+

+

+
/* kinds of Garbage Collection */
+
#define KGC_NORMAL	0
+
#define KGC_EMERGENCY	1	/* gc was forced by an allocation failure */
+

+

+
typedef struct stringtable {
+
  TString **hash;
+
  int nuse;  /* number of elements */
+
  int size;
+
} stringtable;
+

+

+
/*
+
** Information about a call.
+
** When a thread yields, 'func' is adjusted to pretend that the
+
** top function has only the yielded values in its stack; in that
+
** case, the actual 'func' value is saved in field 'extra'.
+
** When a function calls another with a continuation, 'extra' keeps
+
** the function index so that, in case of errors, the continuation
+
** function can be called with the correct top.
+
*/
+
typedef struct CallInfo {
+
  StkId func;  /* function index in the stack */
+
  StkId	top;  /* top for this function */
+
  struct CallInfo *previous, *next;  /* dynamic call link */
+
  union {
+
    struct {  /* only for Lua functions */
+
      StkId base;  /* base for this function */
+
      const Instruction *savedpc;
+
    } l;
+
    struct {  /* only for C functions */
+
      lua_KFunction k;  /* continuation in case of yields */
+
      ptrdiff_t old_errfunc;
+
      lua_KContext ctx;  /* context info. in case of yields */
+
    } c;
+
  } u;
+
  ptrdiff_t extra;
+
  short nresults;  /* expected number of results from this function */
+
  unsigned short callstatus;
+
} CallInfo;
+

+

+
/*
+
** Bits in CallInfo status
+
*/
+
#define CIST_OAH	(1<<0)	/* original value of 'allowhook' */
+
#define CIST_LUA	(1<<1)	/* call is running a Lua function */
+
#define CIST_HOOKED	(1<<2)	/* call is running a debug hook */
+
#define CIST_FRESH	(1<<3)	/* call is running on a fresh invocation
+
                                   of luaV_execute */
+
#define CIST_YPCALL	(1<<4)	/* call is a yieldable protected call */
+
#define CIST_TAIL	(1<<5)	/* call was tail called */
+
#define CIST_HOOKYIELD	(1<<6)	/* last hook called yielded */
+
#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)
+

+
/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */
+
#define setoah(st,v)	((st) = ((st) & ~CIST_OAH) | (v))
+
#define getoah(st)	((st) & CIST_OAH)
+

+

+
/*
+
** 'global state', shared by all threads of this state
+
*/
+
typedef struct global_State {
+
  lua_Alloc frealloc;  /* function to reallocate memory */
+
  void *ud;         /* auxiliary data to 'frealloc' */
+
  l_mem totalbytes;  /* number of bytes currently allocated - GCdebt */
+
  l_mem GCdebt;  /* bytes allocated not yet compensated by the collector */
+
  lu_mem GCmemtrav;  /* memory traversed by the GC */
+
  lu_mem GCestimate;  /* an estimate of the non-garbage memory in use */
+
  stringtable strt;  /* hash table for strings */
+
  TValue l_registry;
+
  unsigned int seed;  /* randomized seed for hashes */
+
  lu_byte currentwhite;
+
  lu_byte gcstate;  /* state of garbage collector */
+
  lu_byte gckind;  /* kind of GC running */
+
  lu_byte gcrunning;  /* true if GC is running */
+
  GCObject *allgc;  /* list of all collectable objects */
+
  GCObject **sweepgc;  /* current position of sweep in list */
+
  GCObject *finobj;  /* list of collectable objects with finalizers */
+
  GCObject *gray;  /* list of gray objects */
+
  GCObject *grayagain;  /* list of objects to be traversed atomically */
+
  GCObject *weak;  /* list of tables with weak values */
+
  GCObject *ephemeron;  /* list of ephemeron tables (weak keys) */
+
  GCObject *allweak;  /* list of all-weak tables */
+
  GCObject *tobefnz;  /* list of userdata to be GC */
+
  GCObject *fixedgc;  /* list of objects not to be collected */
+
  struct lua_State *twups;  /* list of threads with open upvalues */
+
  unsigned int gcfinnum;  /* number of finalizers to call in each GC step */
+
  int gcpause;  /* size of pause between successive GCs */
+
  int gcstepmul;  /* GC 'granularity' */
+
  lua_CFunction panic;  /* to be called in unprotected errors */
+
  struct lua_State *mainthread;
+
  const lua_Number *version;  /* pointer to version number */
+
  TString *memerrmsg;  /* memory-error message */
+
  TString *tmname[TM_N];  /* array with tag-method names */
+
  struct Table *mt[LUA_NUMTAGS];  /* metatables for basic types */
+
  TString *strcache[STRCACHE_N][STRCACHE_M];  /* cache for strings in API */
+
} global_State;
+

+

+
/*
+
** 'per thread' state
+
*/
+
struct lua_State {
+
  CommonHeader;
+
  unsigned short nci;  /* number of items in 'ci' list */
+
  lu_byte status;
+
  StkId top;  /* first free slot in the stack */
+
  global_State *l_G;
+
  CallInfo *ci;  /* call info for current function */
+
  const Instruction *oldpc;  /* last pc traced */
+
  StkId stack_last;  /* last free slot in the stack */
+
  StkId stack;  /* stack base */
+
  UpVal *openupval;  /* list of open upvalues in this stack */
+
  GCObject *gclist;
+
  struct lua_State *twups;  /* list of threads with open upvalues */
+
  struct lua_longjmp *errorJmp;  /* current error recover point */
+
  CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */
+
  volatile lua_Hook hook;
+
  ptrdiff_t errfunc;  /* current error handling function (stack index) */
+
  int stacksize;
+
  int basehookcount;
+
  int hookcount;
+
  unsigned short nny;  /* number of non-yieldable calls in stack */
+
  unsigned short nCcalls;  /* number of nested C calls */
+
  l_signalT hookmask;
+
  lu_byte allowhook;
+
};
+

+

+
#define G(L)	(L->l_G)
+

+

+
/*
+
** Union of all collectable objects (only for conversions)
+
*/
+
union GCUnion {
+
  GCObject gc;  /* common header */
+
  struct TString ts;
+
  struct Udata u;
+
  union Closure cl;
+
  struct Table h;
+
  struct Proto p;
+
  struct lua_State th;  /* thread */
+
};
+

+

+
#define cast_u(o)	cast(union GCUnion *, (o))
+

+
/* macros to convert a GCObject into a specific value */
+
#define gco2ts(o)  \
+
	check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))
+
#define gco2u(o)  check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u))
+
#define gco2lcl(o)  check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l))
+
#define gco2ccl(o)  check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c))
+
#define gco2cl(o)  \
+
	check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))
+
#define gco2t(o)  check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))
+
#define gco2p(o)  check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))
+
#define gco2th(o)  check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))
+

+

+
/* macro to convert a Lua object into a GCObject */
+
#define obj2gco(v) \
+
	check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc)))
+

+

+
/* actual number of total bytes allocated */
+
#define gettotalbytes(g)	cast(lu_mem, (g)->totalbytes + (g)->GCdebt)
+

+
LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
+
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
+
LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
+
LUAI_FUNC void luaE_freeCI (lua_State *L);
+
LUAI_FUNC void luaE_shrinkCI (lua_State *L);
+

+

+
#endif
+

added external/lua/src/lstring.c
@@ -0,0 +1,248 @@
+
/*
+
** $Id: lstring.c,v 2.56.1.1 2017/04/19 17:20:42 roberto Exp $
+
** String table (keeps all strings handled by Lua)
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lstring_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lstate.h"
+
#include "lstring.h"
+

+

+
#define MEMERRMSG       "not enough memory"
+

+

+
/*
+
** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
+
** compute its hash
+
*/
+
#if !defined(LUAI_HASHLIMIT)
+
#define LUAI_HASHLIMIT		5
+
#endif
+

+

+
/*
+
** equality for long strings
+
*/
+
int luaS_eqlngstr (TString *a, TString *b) {
+
  size_t len = a->u.lnglen;
+
  lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
+
  return (a == b) ||  /* same instance or... */
+
    ((len == b->u.lnglen) &&  /* equal length and ... */
+
     (memcmp(getstr(a), getstr(b), len) == 0));  /* equal contents */
+
}
+

+

+
unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {
+
  unsigned int h = seed ^ cast(unsigned int, l);
+
  size_t step = (l >> LUAI_HASHLIMIT) + 1;
+
  for (; l >= step; l -= step)
+
    h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1]));
+
  return h;
+
}
+

+

+
unsigned int luaS_hashlongstr (TString *ts) {
+
  lua_assert(ts->tt == LUA_TLNGSTR);
+
  if (ts->extra == 0) {  /* no hash? */
+
    ts->hash = luaS_hash(getstr(ts), ts->u.lnglen, ts->hash);
+
    ts->extra = 1;  /* now it has its hash */
+
  }
+
  return ts->hash;
+
}
+

+

+
/*
+
** resizes the string table
+
*/
+
void luaS_resize (lua_State *L, int newsize) {
+
  int i;
+
  stringtable *tb = &G(L)->strt;
+
  if (newsize > tb->size) {  /* grow table if needed */
+
    luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
+
    for (i = tb->size; i < newsize; i++)
+
      tb->hash[i] = NULL;
+
  }
+
  for (i = 0; i < tb->size; i++) {  /* rehash */
+
    TString *p = tb->hash[i];
+
    tb->hash[i] = NULL;
+
    while (p) {  /* for each node in the list */
+
      TString *hnext = p->u.hnext;  /* save next */
+
      unsigned int h = lmod(p->hash, newsize);  /* new position */
+
      p->u.hnext = tb->hash[h];  /* chain it */
+
      tb->hash[h] = p;
+
      p = hnext;
+
    }
+
  }
+
  if (newsize < tb->size) {  /* shrink table if needed */
+
    /* vanishing slice should be empty */
+
    lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
+
    luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
+
  }
+
  tb->size = newsize;
+
}
+

+

+
/*
+
** Clear API string cache. (Entries cannot be empty, so fill them with
+
** a non-collectable string.)
+
*/
+
void luaS_clearcache (global_State *g) {
+
  int i, j;
+
  for (i = 0; i < STRCACHE_N; i++)
+
    for (j = 0; j < STRCACHE_M; j++) {
+
    if (iswhite(g->strcache[i][j]))  /* will entry be collected? */
+
      g->strcache[i][j] = g->memerrmsg;  /* replace it with something fixed */
+
    }
+
}
+

+

+
/*
+
** Initialize the string table and the string cache
+
*/
+
void luaS_init (lua_State *L) {
+
  global_State *g = G(L);
+
  int i, j;
+
  luaS_resize(L, MINSTRTABSIZE);  /* initial size of string table */
+
  /* pre-create memory-error message */
+
  g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
+
  luaC_fix(L, obj2gco(g->memerrmsg));  /* it should never be collected */
+
  for (i = 0; i < STRCACHE_N; i++)  /* fill cache with valid strings */
+
    for (j = 0; j < STRCACHE_M; j++)
+
      g->strcache[i][j] = g->memerrmsg;
+
}
+

+

+

+
/*
+
** creates a new string object
+
*/
+
static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) {
+
  TString *ts;
+
  GCObject *o;
+
  size_t totalsize;  /* total size of TString object */
+
  totalsize = sizelstring(l);
+
  o = luaC_newobj(L, tag, totalsize);
+
  ts = gco2ts(o);
+
  ts->hash = h;
+
  ts->extra = 0;
+
  getstr(ts)[l] = '\0';  /* ending 0 */
+
  return ts;
+
}
+

+

+
TString *luaS_createlngstrobj (lua_State *L, size_t l) {
+
  TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed);
+
  ts->u.lnglen = l;
+
  return ts;
+
}
+

+

+
void luaS_remove (lua_State *L, TString *ts) {
+
  stringtable *tb = &G(L)->strt;
+
  TString **p = &tb->hash[lmod(ts->hash, tb->size)];
+
  while (*p != ts)  /* find previous element */
+
    p = &(*p)->u.hnext;
+
  *p = (*p)->u.hnext;  /* remove element from its list */
+
  tb->nuse--;
+
}
+

+

+
/*
+
** checks whether short string exists and reuses it or creates a new one
+
*/
+
static TString *internshrstr (lua_State *L, const char *str, size_t l) {
+
  TString *ts;
+
  global_State *g = G(L);
+
  unsigned int h = luaS_hash(str, l, g->seed);
+
  TString **list = &g->strt.hash[lmod(h, g->strt.size)];
+
  lua_assert(str != NULL);  /* otherwise 'memcmp'/'memcpy' are undefined */
+
  for (ts = *list; ts != NULL; ts = ts->u.hnext) {
+
    if (l == ts->shrlen &&
+
        (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
+
      /* found! */
+
      if (isdead(g, ts))  /* dead (but not collected yet)? */
+
        changewhite(ts);  /* resurrect it */
+
      return ts;
+
    }
+
  }
+
  if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) {
+
    luaS_resize(L, g->strt.size * 2);
+
    list = &g->strt.hash[lmod(h, g->strt.size)];  /* recompute with new size */
+
  }
+
  ts = createstrobj(L, l, LUA_TSHRSTR, h);
+
  memcpy(getstr(ts), str, l * sizeof(char));
+
  ts->shrlen = cast_byte(l);
+
  ts->u.hnext = *list;
+
  *list = ts;
+
  g->strt.nuse++;
+
  return ts;
+
}
+

+

+
/*
+
** new string (with explicit length)
+
*/
+
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
+
  if (l <= LUAI_MAXSHORTLEN)  /* short string? */
+
    return internshrstr(L, str, l);
+
  else {
+
    TString *ts;
+
    if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char))
+
      luaM_toobig(L);
+
    ts = luaS_createlngstrobj(L, l);
+
    memcpy(getstr(ts), str, l * sizeof(char));
+
    return ts;
+
  }
+
}
+

+

+
/*
+
** Create or reuse a zero-terminated string, first checking in the
+
** cache (using the string address as a key). The cache can contain
+
** only zero-terminated strings, so it is safe to use 'strcmp' to
+
** check hits.
+
*/
+
TString *luaS_new (lua_State *L, const char *str) {
+
  unsigned int i = point2uint(str) % STRCACHE_N;  /* hash */
+
  int j;
+
  TString **p = G(L)->strcache[i];
+
  for (j = 0; j < STRCACHE_M; j++) {
+
    if (strcmp(str, getstr(p[j])) == 0)  /* hit? */
+
      return p[j];  /* that is it */
+
  }
+
  /* normal route */
+
  for (j = STRCACHE_M - 1; j > 0; j--)
+
    p[j] = p[j - 1];  /* move out last element */
+
  /* new element is first in the list */
+
  p[0] = luaS_newlstr(L, str, strlen(str));
+
  return p[0];
+
}
+

+

+
Udata *luaS_newudata (lua_State *L, size_t s) {
+
  Udata *u;
+
  GCObject *o;
+
  if (s > MAX_SIZE - sizeof(Udata))
+
    luaM_toobig(L);
+
  o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s));
+
  u = gco2u(o);
+
  u->len = s;
+
  u->metatable = NULL;
+
  setuservalue(L, u, luaO_nilobject);
+
  return u;
+
}
+

added external/lua/src/lstring.h
@@ -0,0 +1,49 @@
+
/*
+
** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $
+
** String table (keep all strings handled by Lua)
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lstring_h
+
#define lstring_h
+

+
#include "lgc.h"
+
#include "lobject.h"
+
#include "lstate.h"
+

+

+
#define sizelstring(l)  (sizeof(union UTString) + ((l) + 1) * sizeof(char))
+

+
#define sizeludata(l)	(sizeof(union UUdata) + (l))
+
#define sizeudata(u)	sizeludata((u)->len)
+

+
#define luaS_newliteral(L, s)	(luaS_newlstr(L, "" s, \
+
                                 (sizeof(s)/sizeof(char))-1))
+

+

+
/*
+
** test whether a string is a reserved word
+
*/
+
#define isreserved(s)	((s)->tt == LUA_TSHRSTR && (s)->extra > 0)
+

+

+
/*
+
** equality for short strings, which are always internalized
+
*/
+
#define eqshrstr(a,b)	check_exp((a)->tt == LUA_TSHRSTR, (a) == (b))
+

+

+
LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
+
LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts);
+
LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
+
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
+
LUAI_FUNC void luaS_clearcache (global_State *g);
+
LUAI_FUNC void luaS_init (lua_State *L);
+
LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
+
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
+
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
+
LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
+
LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l);
+

+

+
#endif
added external/lua/src/lstrlib.c
@@ -0,0 +1,1584 @@
+
/*
+
** $Id: lstrlib.c,v 1.254.1.1 2017/04/19 17:29:57 roberto Exp $
+
** Standard library for string operations and pattern-matching
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lstrlib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <ctype.h>
+
#include <float.h>
+
#include <limits.h>
+
#include <locale.h>
+
#include <stddef.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+
/*
+
** maximum number of captures that a pattern can do during
+
** pattern-matching. This limit is arbitrary, but must fit in
+
** an unsigned char.
+
*/
+
#if !defined(LUA_MAXCAPTURES)
+
#define LUA_MAXCAPTURES		32
+
#endif
+

+

+
/* macro to 'unsign' a character */
+
#define uchar(c)	((unsigned char)(c))
+

+

+
/*
+
** Some sizes are better limited to fit in 'int', but must also fit in
+
** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.)
+
*/
+
#define MAX_SIZET	((size_t)(~(size_t)0))
+

+
#define MAXSIZE  \
+
	(sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX))
+

+

+

+

+
static int str_len (lua_State *L) {
+
  size_t l;
+
  luaL_checklstring(L, 1, &l);
+
  lua_pushinteger(L, (lua_Integer)l);
+
  return 1;
+
}
+

+

+
/* translate a relative string position: negative means back from end */
+
static lua_Integer posrelat (lua_Integer pos, size_t len) {
+
  if (pos >= 0) return pos;
+
  else if (0u - (size_t)pos > len) return 0;
+
  else return (lua_Integer)len + pos + 1;
+
}
+

+

+
static int str_sub (lua_State *L) {
+
  size_t l;
+
  const char *s = luaL_checklstring(L, 1, &l);
+
  lua_Integer start = posrelat(luaL_checkinteger(L, 2), l);
+
  lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l);
+
  if (start < 1) start = 1;
+
  if (end > (lua_Integer)l) end = l;
+
  if (start <= end)
+
    lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1);
+
  else lua_pushliteral(L, "");
+
  return 1;
+
}
+

+

+
static int str_reverse (lua_State *L) {
+
  size_t l, i;
+
  luaL_Buffer b;
+
  const char *s = luaL_checklstring(L, 1, &l);
+
  char *p = luaL_buffinitsize(L, &b, l);
+
  for (i = 0; i < l; i++)
+
    p[i] = s[l - i - 1];
+
  luaL_pushresultsize(&b, l);
+
  return 1;
+
}
+

+

+
static int str_lower (lua_State *L) {
+
  size_t l;
+
  size_t i;
+
  luaL_Buffer b;
+
  const char *s = luaL_checklstring(L, 1, &l);
+
  char *p = luaL_buffinitsize(L, &b, l);
+
  for (i=0; i<l; i++)
+
    p[i] = tolower(uchar(s[i]));
+
  luaL_pushresultsize(&b, l);
+
  return 1;
+
}
+

+

+
static int str_upper (lua_State *L) {
+
  size_t l;
+
  size_t i;
+
  luaL_Buffer b;
+
  const char *s = luaL_checklstring(L, 1, &l);
+
  char *p = luaL_buffinitsize(L, &b, l);
+
  for (i=0; i<l; i++)
+
    p[i] = toupper(uchar(s[i]));
+
  luaL_pushresultsize(&b, l);
+
  return 1;
+
}
+

+

+
static int str_rep (lua_State *L) {
+
  size_t l, lsep;
+
  const char *s = luaL_checklstring(L, 1, &l);
+
  lua_Integer n = luaL_checkinteger(L, 2);
+
  const char *sep = luaL_optlstring(L, 3, "", &lsep);
+
  if (n <= 0) lua_pushliteral(L, "");
+
  else if (l + lsep < l || l + lsep > MAXSIZE / n)  /* may overflow? */
+
    return luaL_error(L, "resulting string too large");
+
  else {
+
    size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep;
+
    luaL_Buffer b;
+
    char *p = luaL_buffinitsize(L, &b, totallen);
+
    while (n-- > 1) {  /* first n-1 copies (followed by separator) */
+
      memcpy(p, s, l * sizeof(char)); p += l;
+
      if (lsep > 0) {  /* empty 'memcpy' is not that cheap */
+
        memcpy(p, sep, lsep * sizeof(char));
+
        p += lsep;
+
      }
+
    }
+
    memcpy(p, s, l * sizeof(char));  /* last copy (not followed by separator) */
+
    luaL_pushresultsize(&b, totallen);
+
  }
+
  return 1;
+
}
+

+

+
static int str_byte (lua_State *L) {
+
  size_t l;
+
  const char *s = luaL_checklstring(L, 1, &l);
+
  lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l);
+
  lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l);
+
  int n, i;
+
  if (posi < 1) posi = 1;
+
  if (pose > (lua_Integer)l) pose = l;
+
  if (posi > pose) return 0;  /* empty interval; return no values */
+
  if (pose - posi >= INT_MAX)  /* arithmetic overflow? */
+
    return luaL_error(L, "string slice too long");
+
  n = (int)(pose -  posi) + 1;
+
  luaL_checkstack(L, n, "string slice too long");
+
  for (i=0; i<n; i++)
+
    lua_pushinteger(L, uchar(s[posi+i-1]));
+
  return n;
+
}
+

+

+
static int str_char (lua_State *L) {
+
  int n = lua_gettop(L);  /* number of arguments */
+
  int i;
+
  luaL_Buffer b;
+
  char *p = luaL_buffinitsize(L, &b, n);
+
  for (i=1; i<=n; i++) {
+
    lua_Integer c = luaL_checkinteger(L, i);
+
    luaL_argcheck(L, uchar(c) == c, i, "value out of range");
+
    p[i - 1] = uchar(c);
+
  }
+
  luaL_pushresultsize(&b, n);
+
  return 1;
+
}
+

+

+
static int writer (lua_State *L, const void *b, size_t size, void *B) {
+
  (void)L;
+
  luaL_addlstring((luaL_Buffer *) B, (const char *)b, size);
+
  return 0;
+
}
+

+

+
static int str_dump (lua_State *L) {
+
  luaL_Buffer b;
+
  int strip = lua_toboolean(L, 2);
+
  luaL_checktype(L, 1, LUA_TFUNCTION);
+
  lua_settop(L, 1);
+
  luaL_buffinit(L,&b);
+
  if (lua_dump(L, writer, &b, strip) != 0)
+
    return luaL_error(L, "unable to dump given function");
+
  luaL_pushresult(&b);
+
  return 1;
+
}
+

+

+

+
/*
+
** {======================================================
+
** PATTERN MATCHING
+
** =======================================================
+
*/
+

+

+
#define CAP_UNFINISHED	(-1)
+
#define CAP_POSITION	(-2)
+

+

+
typedef struct MatchState {
+
  const char *src_init;  /* init of source string */
+
  const char *src_end;  /* end ('\0') of source string */
+
  const char *p_end;  /* end ('\0') of pattern */
+
  lua_State *L;
+
  int matchdepth;  /* control for recursive depth (to avoid C stack overflow) */
+
  unsigned char level;  /* total number of captures (finished or unfinished) */
+
  struct {
+
    const char *init;
+
    ptrdiff_t len;
+
  } capture[LUA_MAXCAPTURES];
+
} MatchState;
+

+

+
/* recursive function */
+
static const char *match (MatchState *ms, const char *s, const char *p);
+

+

+
/* maximum recursion depth for 'match' */
+
#if !defined(MAXCCALLS)
+
#define MAXCCALLS	200
+
#endif
+

+

+
#define L_ESC		'%'
+
#define SPECIALS	"^$*+?.([%-"
+

+

+
static int check_capture (MatchState *ms, int l) {
+
  l -= '1';
+
  if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
+
    return luaL_error(ms->L, "invalid capture index %%%d", l + 1);
+
  return l;
+
}
+

+

+
static int capture_to_close (MatchState *ms) {
+
  int level = ms->level;
+
  for (level--; level>=0; level--)
+
    if (ms->capture[level].len == CAP_UNFINISHED) return level;
+
  return luaL_error(ms->L, "invalid pattern capture");
+
}
+

+

+
static const char *classend (MatchState *ms, const char *p) {
+
  switch (*p++) {
+
    case L_ESC: {
+
      if (p == ms->p_end)
+
        luaL_error(ms->L, "malformed pattern (ends with '%%')");
+
      return p+1;
+
    }
+
    case '[': {
+
      if (*p == '^') p++;
+
      do {  /* look for a ']' */
+
        if (p == ms->p_end)
+
          luaL_error(ms->L, "malformed pattern (missing ']')");
+
        if (*(p++) == L_ESC && p < ms->p_end)
+
          p++;  /* skip escapes (e.g. '%]') */
+
      } while (*p != ']');
+
      return p+1;
+
    }
+
    default: {
+
      return p;
+
    }
+
  }
+
}
+

+

+
static int match_class (int c, int cl) {
+
  int res;
+
  switch (tolower(cl)) {
+
    case 'a' : res = isalpha(c); break;
+
    case 'c' : res = iscntrl(c); break;
+
    case 'd' : res = isdigit(c); break;
+
    case 'g' : res = isgraph(c); break;
+
    case 'l' : res = islower(c); break;
+
    case 'p' : res = ispunct(c); break;
+
    case 's' : res = isspace(c); break;
+
    case 'u' : res = isupper(c); break;
+
    case 'w' : res = isalnum(c); break;
+
    case 'x' : res = isxdigit(c); break;
+
    case 'z' : res = (c == 0); break;  /* deprecated option */
+
    default: return (cl == c);
+
  }
+
  return (islower(cl) ? res : !res);
+
}
+

+

+
static int matchbracketclass (int c, const char *p, const char *ec) {
+
  int sig = 1;
+
  if (*(p+1) == '^') {
+
    sig = 0;
+
    p++;  /* skip the '^' */
+
  }
+
  while (++p < ec) {
+
    if (*p == L_ESC) {
+
      p++;
+
      if (match_class(c, uchar(*p)))
+
        return sig;
+
    }
+
    else if ((*(p+1) == '-') && (p+2 < ec)) {
+
      p+=2;
+
      if (uchar(*(p-2)) <= c && c <= uchar(*p))
+
        return sig;
+
    }
+
    else if (uchar(*p) == c) return sig;
+
  }
+
  return !sig;
+
}
+

+

+
static int singlematch (MatchState *ms, const char *s, const char *p,
+
                        const char *ep) {
+
  if (s >= ms->src_end)
+
    return 0;
+
  else {
+
    int c = uchar(*s);
+
    switch (*p) {
+
      case '.': return 1;  /* matches any char */
+
      case L_ESC: return match_class(c, uchar(*(p+1)));
+
      case '[': return matchbracketclass(c, p, ep-1);
+
      default:  return (uchar(*p) == c);
+
    }
+
  }
+
}
+

+

+
static const char *matchbalance (MatchState *ms, const char *s,
+
                                   const char *p) {
+
  if (p >= ms->p_end - 1)
+
    luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')");
+
  if (*s != *p) return NULL;
+
  else {
+
    int b = *p;
+
    int e = *(p+1);
+
    int cont = 1;
+
    while (++s < ms->src_end) {
+
      if (*s == e) {
+
        if (--cont == 0) return s+1;
+
      }
+
      else if (*s == b) cont++;
+
    }
+
  }
+
  return NULL;  /* string ends out of balance */
+
}
+

+

+
static const char *max_expand (MatchState *ms, const char *s,
+
                                 const char *p, const char *ep) {
+
  ptrdiff_t i = 0;  /* counts maximum expand for item */
+
  while (singlematch(ms, s + i, p, ep))
+
    i++;
+
  /* keeps trying to match with the maximum repetitions */
+
  while (i>=0) {
+
    const char *res = match(ms, (s+i), ep+1);
+
    if (res) return res;
+
    i--;  /* else didn't match; reduce 1 repetition to try again */
+
  }
+
  return NULL;
+
}
+

+

+
static const char *min_expand (MatchState *ms, const char *s,
+
                                 const char *p, const char *ep) {
+
  for (;;) {
+
    const char *res = match(ms, s, ep+1);
+
    if (res != NULL)
+
      return res;
+
    else if (singlematch(ms, s, p, ep))
+
      s++;  /* try with one more repetition */
+
    else return NULL;
+
  }
+
}
+

+

+
static const char *start_capture (MatchState *ms, const char *s,
+
                                    const char *p, int what) {
+
  const char *res;
+
  int level = ms->level;
+
  if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
+
  ms->capture[level].init = s;
+
  ms->capture[level].len = what;
+
  ms->level = level+1;
+
  if ((res=match(ms, s, p)) == NULL)  /* match failed? */
+
    ms->level--;  /* undo capture */
+
  return res;
+
}
+

+

+
static const char *end_capture (MatchState *ms, const char *s,
+
                                  const char *p) {
+
  int l = capture_to_close(ms);
+
  const char *res;
+
  ms->capture[l].len = s - ms->capture[l].init;  /* close capture */
+
  if ((res = match(ms, s, p)) == NULL)  /* match failed? */
+
    ms->capture[l].len = CAP_UNFINISHED;  /* undo capture */
+
  return res;
+
}
+

+

+
static const char *match_capture (MatchState *ms, const char *s, int l) {
+
  size_t len;
+
  l = check_capture(ms, l);
+
  len = ms->capture[l].len;
+
  if ((size_t)(ms->src_end-s) >= len &&
+
      memcmp(ms->capture[l].init, s, len) == 0)
+
    return s+len;
+
  else return NULL;
+
}
+

+

+
static const char *match (MatchState *ms, const char *s, const char *p) {
+
  if (ms->matchdepth-- == 0)
+
    luaL_error(ms->L, "pattern too complex");
+
  init: /* using goto's to optimize tail recursion */
+
  if (p != ms->p_end) {  /* end of pattern? */
+
    switch (*p) {
+
      case '(': {  /* start capture */
+
        if (*(p + 1) == ')')  /* position capture? */
+
          s = start_capture(ms, s, p + 2, CAP_POSITION);
+
        else
+
          s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
+
        break;
+
      }
+
      case ')': {  /* end capture */
+
        s = end_capture(ms, s, p + 1);
+
        break;
+
      }
+
      case '$': {
+
        if ((p + 1) != ms->p_end)  /* is the '$' the last char in pattern? */
+
          goto dflt;  /* no; go to default */
+
        s = (s == ms->src_end) ? s : NULL;  /* check end of string */
+
        break;
+
      }
+
      case L_ESC: {  /* escaped sequences not in the format class[*+?-]? */
+
        switch (*(p + 1)) {
+
          case 'b': {  /* balanced string? */
+
            s = matchbalance(ms, s, p + 2);
+
            if (s != NULL) {
+
              p += 4; goto init;  /* return match(ms, s, p + 4); */
+
            }  /* else fail (s == NULL) */
+
            break;
+
          }
+
          case 'f': {  /* frontier? */
+
            const char *ep; char previous;
+
            p += 2;
+
            if (*p != '[')
+
              luaL_error(ms->L, "missing '[' after '%%f' in pattern");
+
            ep = classend(ms, p);  /* points to what is next */
+
            previous = (s == ms->src_init) ? '\0' : *(s - 1);
+
            if (!matchbracketclass(uchar(previous), p, ep - 1) &&
+
               matchbracketclass(uchar(*s), p, ep - 1)) {
+
              p = ep; goto init;  /* return match(ms, s, ep); */
+
            }
+
            s = NULL;  /* match failed */
+
            break;
+
          }
+
          case '0': case '1': case '2': case '3':
+
          case '4': case '5': case '6': case '7':
+
          case '8': case '9': {  /* capture results (%0-%9)? */
+
            s = match_capture(ms, s, uchar(*(p + 1)));
+
            if (s != NULL) {
+
              p += 2; goto init;  /* return match(ms, s, p + 2) */
+
            }
+
            break;
+
          }
+
          default: goto dflt;
+
        }
+
        break;
+
      }
+
      default: dflt: {  /* pattern class plus optional suffix */
+
        const char *ep = classend(ms, p);  /* points to optional suffix */
+
        /* does not match at least once? */
+
        if (!singlematch(ms, s, p, ep)) {
+
          if (*ep == '*' || *ep == '?' || *ep == '-') {  /* accept empty? */
+
            p = ep + 1; goto init;  /* return match(ms, s, ep + 1); */
+
          }
+
          else  /* '+' or no suffix */
+
            s = NULL;  /* fail */
+
        }
+
        else {  /* matched once */
+
          switch (*ep) {  /* handle optional suffix */
+
            case '?': {  /* optional */
+
              const char *res;
+
              if ((res = match(ms, s + 1, ep + 1)) != NULL)
+
                s = res;
+
              else {
+
                p = ep + 1; goto init;  /* else return match(ms, s, ep + 1); */
+
              }
+
              break;
+
            }
+
            case '+':  /* 1 or more repetitions */
+
              s++;  /* 1 match already done */
+
              /* FALLTHROUGH */
+
            case '*':  /* 0 or more repetitions */
+
              s = max_expand(ms, s, p, ep);
+
              break;
+
            case '-':  /* 0 or more repetitions (minimum) */
+
              s = min_expand(ms, s, p, ep);
+
              break;
+
            default:  /* no suffix */
+
              s++; p = ep; goto init;  /* return match(ms, s + 1, ep); */
+
          }
+
        }
+
        break;
+
      }
+
    }
+
  }
+
  ms->matchdepth++;
+
  return s;
+
}
+

+

+

+
static const char *lmemfind (const char *s1, size_t l1,
+
                               const char *s2, size_t l2) {
+
  if (l2 == 0) return s1;  /* empty strings are everywhere */
+
  else if (l2 > l1) return NULL;  /* avoids a negative 'l1' */
+
  else {
+
    const char *init;  /* to search for a '*s2' inside 's1' */
+
    l2--;  /* 1st char will be checked by 'memchr' */
+
    l1 = l1-l2;  /* 's2' cannot be found after that */
+
    while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
+
      init++;   /* 1st char is already checked */
+
      if (memcmp(init, s2+1, l2) == 0)
+
        return init-1;
+
      else {  /* correct 'l1' and 's1' to try again */
+
        l1 -= init-s1;
+
        s1 = init;
+
      }
+
    }
+
    return NULL;  /* not found */
+
  }
+
}
+

+

+
static void push_onecapture (MatchState *ms, int i, const char *s,
+
                                                    const char *e) {
+
  if (i >= ms->level) {
+
    if (i == 0)  /* ms->level == 0, too */
+
      lua_pushlstring(ms->L, s, e - s);  /* add whole match */
+
    else
+
      luaL_error(ms->L, "invalid capture index %%%d", i + 1);
+
  }
+
  else {
+
    ptrdiff_t l = ms->capture[i].len;
+
    if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
+
    if (l == CAP_POSITION)
+
      lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
+
    else
+
      lua_pushlstring(ms->L, ms->capture[i].init, l);
+
  }
+
}
+

+

+
static int push_captures (MatchState *ms, const char *s, const char *e) {
+
  int i;
+
  int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
+
  luaL_checkstack(ms->L, nlevels, "too many captures");
+
  for (i = 0; i < nlevels; i++)
+
    push_onecapture(ms, i, s, e);
+
  return nlevels;  /* number of strings pushed */
+
}
+

+

+
/* check whether pattern has no special characters */
+
static int nospecials (const char *p, size_t l) {
+
  size_t upto = 0;
+
  do {
+
    if (strpbrk(p + upto, SPECIALS))
+
      return 0;  /* pattern has a special character */
+
    upto += strlen(p + upto) + 1;  /* may have more after \0 */
+
  } while (upto <= l);
+
  return 1;  /* no special chars found */
+
}
+

+

+
static void prepstate (MatchState *ms, lua_State *L,
+
                       const char *s, size_t ls, const char *p, size_t lp) {
+
  ms->L = L;
+
  ms->matchdepth = MAXCCALLS;
+
  ms->src_init = s;
+
  ms->src_end = s + ls;
+
  ms->p_end = p + lp;
+
}
+

+

+
static void reprepstate (MatchState *ms) {
+
  ms->level = 0;
+
  lua_assert(ms->matchdepth == MAXCCALLS);
+
}
+

+

+
static int str_find_aux (lua_State *L, int find) {
+
  size_t ls, lp;
+
  const char *s = luaL_checklstring(L, 1, &ls);
+
  const char *p = luaL_checklstring(L, 2, &lp);
+
  lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls);
+
  if (init < 1) init = 1;
+
  else if (init > (lua_Integer)ls + 1) {  /* start after string's end? */
+
    lua_pushnil(L);  /* cannot find anything */
+
    return 1;
+
  }
+
  /* explicit request or no special characters? */
+
  if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
+
    /* do a plain search */
+
    const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp);
+
    if (s2) {
+
      lua_pushinteger(L, (s2 - s) + 1);
+
      lua_pushinteger(L, (s2 - s) + lp);
+
      return 2;
+
    }
+
  }
+
  else {
+
    MatchState ms;
+
    const char *s1 = s + init - 1;
+
    int anchor = (*p == '^');
+
    if (anchor) {
+
      p++; lp--;  /* skip anchor character */
+
    }
+
    prepstate(&ms, L, s, ls, p, lp);
+
    do {
+
      const char *res;
+
      reprepstate(&ms);
+
      if ((res=match(&ms, s1, p)) != NULL) {
+
        if (find) {
+
          lua_pushinteger(L, (s1 - s) + 1);  /* start */
+
          lua_pushinteger(L, res - s);   /* end */
+
          return push_captures(&ms, NULL, 0) + 2;
+
        }
+
        else
+
          return push_captures(&ms, s1, res);
+
      }
+
    } while (s1++ < ms.src_end && !anchor);
+
  }
+
  lua_pushnil(L);  /* not found */
+
  return 1;
+
}
+

+

+
static int str_find (lua_State *L) {
+
  return str_find_aux(L, 1);
+
}
+

+

+
static int str_match (lua_State *L) {
+
  return str_find_aux(L, 0);
+
}
+

+

+
/* state for 'gmatch' */
+
typedef struct GMatchState {
+
  const char *src;  /* current position */
+
  const char *p;  /* pattern */
+
  const char *lastmatch;  /* end of last match */
+
  MatchState ms;  /* match state */
+
} GMatchState;
+

+

+
static int gmatch_aux (lua_State *L) {
+
  GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
+
  const char *src;
+
  gm->ms.L = L;
+
  for (src = gm->src; src <= gm->ms.src_end; src++) {
+
    const char *e;
+
    reprepstate(&gm->ms);
+
    if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) {
+
      gm->src = gm->lastmatch = e;
+
      return push_captures(&gm->ms, src, e);
+
    }
+
  }
+
  return 0;  /* not found */
+
}
+

+

+
static int gmatch (lua_State *L) {
+
  size_t ls, lp;
+
  const char *s = luaL_checklstring(L, 1, &ls);
+
  const char *p = luaL_checklstring(L, 2, &lp);
+
  GMatchState *gm;
+
  lua_settop(L, 2);  /* keep them on closure to avoid being collected */
+
  gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState));
+
  prepstate(&gm->ms, L, s, ls, p, lp);
+
  gm->src = s; gm->p = p; gm->lastmatch = NULL;
+
  lua_pushcclosure(L, gmatch_aux, 3);
+
  return 1;
+
}
+

+

+
static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
+
                                                   const char *e) {
+
  size_t l, i;
+
  lua_State *L = ms->L;
+
  const char *news = lua_tolstring(L, 3, &l);
+
  for (i = 0; i < l; i++) {
+
    if (news[i] != L_ESC)
+
      luaL_addchar(b, news[i]);
+
    else {
+
      i++;  /* skip ESC */
+
      if (!isdigit(uchar(news[i]))) {
+
        if (news[i] != L_ESC)
+
          luaL_error(L, "invalid use of '%c' in replacement string", L_ESC);
+
        luaL_addchar(b, news[i]);
+
      }
+
      else if (news[i] == '0')
+
          luaL_addlstring(b, s, e - s);
+
      else {
+
        push_onecapture(ms, news[i] - '1', s, e);
+
        luaL_tolstring(L, -1, NULL);  /* if number, convert it to string */
+
        lua_remove(L, -2);  /* remove original value */
+
        luaL_addvalue(b);  /* add capture to accumulated result */
+
      }
+
    }
+
  }
+
}
+

+

+
static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
+
                                       const char *e, int tr) {
+
  lua_State *L = ms->L;
+
  switch (tr) {
+
    case LUA_TFUNCTION: {
+
      int n;
+
      lua_pushvalue(L, 3);
+
      n = push_captures(ms, s, e);
+
      lua_call(L, n, 1);
+
      break;
+
    }
+
    case LUA_TTABLE: {
+
      push_onecapture(ms, 0, s, e);
+
      lua_gettable(L, 3);
+
      break;
+
    }
+
    default: {  /* LUA_TNUMBER or LUA_TSTRING */
+
      add_s(ms, b, s, e);
+
      return;
+
    }
+
  }
+
  if (!lua_toboolean(L, -1)) {  /* nil or false? */
+
    lua_pop(L, 1);
+
    lua_pushlstring(L, s, e - s);  /* keep original text */
+
  }
+
  else if (!lua_isstring(L, -1))
+
    luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
+
  luaL_addvalue(b);  /* add result to accumulator */
+
}
+

+

+
static int str_gsub (lua_State *L) {
+
  size_t srcl, lp;
+
  const char *src = luaL_checklstring(L, 1, &srcl);  /* subject */
+
  const char *p = luaL_checklstring(L, 2, &lp);  /* pattern */
+
  const char *lastmatch = NULL;  /* end of last match */
+
  int tr = lua_type(L, 3);  /* replacement type */
+
  lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1);  /* max replacements */
+
  int anchor = (*p == '^');
+
  lua_Integer n = 0;  /* replacement count */
+
  MatchState ms;
+
  luaL_Buffer b;
+
  luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
+
                   tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
+
                      "string/function/table expected");
+
  luaL_buffinit(L, &b);
+
  if (anchor) {
+
    p++; lp--;  /* skip anchor character */
+
  }
+
  prepstate(&ms, L, src, srcl, p, lp);
+
  while (n < max_s) {
+
    const char *e;
+
    reprepstate(&ms);  /* (re)prepare state for new match */
+
    if ((e = match(&ms, src, p)) != NULL && e != lastmatch) {  /* match? */
+
      n++;
+
      add_value(&ms, &b, src, e, tr);  /* add replacement to buffer */
+
      src = lastmatch = e;
+
    }
+
    else if (src < ms.src_end)  /* otherwise, skip one character */
+
      luaL_addchar(&b, *src++);
+
    else break;  /* end of subject */
+
    if (anchor) break;
+
  }
+
  luaL_addlstring(&b, src, ms.src_end-src);
+
  luaL_pushresult(&b);
+
  lua_pushinteger(L, n);  /* number of substitutions */
+
  return 2;
+
}
+

+
/* }====================================================== */
+

+

+

+
/*
+
** {======================================================
+
** STRING FORMAT
+
** =======================================================
+
*/
+

+
#if !defined(lua_number2strx)	/* { */
+

+
/*
+
** Hexadecimal floating-point formatter
+
*/
+

+
#include <math.h>
+

+
#define SIZELENMOD	(sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
+

+

+
/*
+
** Number of bits that goes into the first digit. It can be any value
+
** between 1 and 4; the following definition tries to align the number
+
** to nibble boundaries by making what is left after that first digit a
+
** multiple of 4.
+
*/
+
#define L_NBFD		((l_mathlim(MANT_DIG) - 1)%4 + 1)
+

+

+
/*
+
** Add integer part of 'x' to buffer and return new 'x'
+
*/
+
static lua_Number adddigit (char *buff, int n, lua_Number x) {
+
  lua_Number dd = l_mathop(floor)(x);  /* get integer part from 'x' */
+
  int d = (int)dd;
+
  buff[n] = (d < 10 ? d + '0' : d - 10 + 'a');  /* add to buffer */
+
  return x - dd;  /* return what is left */
+
}
+

+

+
static int num2straux (char *buff, int sz, lua_Number x) {
+
  /* if 'inf' or 'NaN', format it like '%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... */
+
    /* create "0" or "-0" followed by exponent */
+
    return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x);
+
  }
+
  else {
+
    int e;
+
    lua_Number m = l_mathop(frexp)(x, &e);  /* 'x' fraction and exponent */
+
    int n = 0;  /* character count */
+
    if (m < 0) {  /* is number negative? */
+
      buff[n++] = '-';  /* add signal */
+
      m = -m;  /* make it positive */
+
    }
+
    buff[n++] = '0'; buff[n++] = 'x';  /* add "0x" */
+
    m = adddigit(buff, n++, m * (1 << L_NBFD));  /* add first digit */
+
    e -= L_NBFD;  /* this digit goes before the radix point */
+
    if (m > 0) {  /* more digits? */
+
      buff[n++] = lua_getlocaledecpoint();  /* add radix point */
+
      do {  /* add as many digits as needed */
+
        m = adddigit(buff, n++, m * 16);
+
      } while (m > 0);
+
    }
+
    n += l_sprintf(buff + n, sz - n, "p%+d", e);  /* add exponent */
+
    lua_assert(n < sz);
+
    return n;
+
  }
+
}
+

+

+
static int lua_number2strx (lua_State *L, char *buff, int sz,
+
                            const char *fmt, lua_Number x) {
+
  int n = num2straux(buff, sz, x);
+
  if (fmt[SIZELENMOD] == 'A') {
+
    int i;
+
    for (i = 0; i < n; i++)
+
      buff[i] = toupper(uchar(buff[i]));
+
  }
+
  else if (fmt[SIZELENMOD] != 'a')
+
    return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
+
  return n;
+
}
+

+
#endif				/* } */
+

+

+
/*
+
** Maximum size of each formatted item. This maximum size is produced
+
** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.',
+
** and '\0') + number of decimal digits to represent maxfloat (which
+
** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra
+
** expenses", such as locale-dependent stuff)
+
*/
+
#define MAX_ITEM        (120 + l_mathlim(MAX_10_EXP))
+

+

+
/* valid flags in a format specification */
+
#define FLAGS	"-+ #0"
+

+
/*
+
** maximum size of each format specification (such as "%-099.99d")
+
*/
+
#define MAX_FORMAT	32
+

+

+
static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
+
  luaL_addchar(b, '"');
+
  while (len--) {
+
    if (*s == '"' || *s == '\\' || *s == '\n') {
+
      luaL_addchar(b, '\\');
+
      luaL_addchar(b, *s);
+
    }
+
    else if (iscntrl(uchar(*s))) {
+
      char buff[10];
+
      if (!isdigit(uchar(*(s+1))))
+
        l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
+
      else
+
        l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s));
+
      luaL_addstring(b, buff);
+
    }
+
    else
+
      luaL_addchar(b, *s);
+
    s++;
+
  }
+
  luaL_addchar(b, '"');
+
}
+

+

+
/*
+
** Ensures the 'buff' string uses a dot as the radix character.
+
*/
+
static void checkdp (char *buff, int nb) {
+
  if (memchr(buff, '.', nb) == NULL) {  /* no dot? */
+
    char point = lua_getlocaledecpoint();  /* try locale point */
+
    char *ppoint = (char *)memchr(buff, point, nb);
+
    if (ppoint) *ppoint = '.';  /* change it to a dot */
+
  }
+
}
+

+

+
static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
+
  switch (lua_type(L, arg)) {
+
    case LUA_TSTRING: {
+
      size_t len;
+
      const char *s = lua_tolstring(L, arg, &len);
+
      addquoted(b, s, len);
+
      break;
+
    }
+
    case LUA_TNUMBER: {
+
      char *buff = luaL_prepbuffsize(b, MAX_ITEM);
+
      int nb;
+
      if (!lua_isinteger(L, arg)) {  /* float? */
+
        lua_Number n = lua_tonumber(L, arg);  /* write as hexa ('%a') */
+
        nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n);
+
        checkdp(buff, nb);  /* ensure it uses a dot */
+
      }
+
      else {  /* integers */
+
        lua_Integer n = lua_tointeger(L, arg);
+
        const char *format = (n == LUA_MININTEGER)  /* corner case? */
+
                           ? "0x%" LUA_INTEGER_FRMLEN "x"  /* use hexa */
+
                           : LUA_INTEGER_FMT;  /* else use default format */
+
        nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n);
+
      }
+
      luaL_addsize(b, nb);
+
      break;
+
    }
+
    case LUA_TNIL: case LUA_TBOOLEAN: {
+
      luaL_tolstring(L, arg, NULL);
+
      luaL_addvalue(b);
+
      break;
+
    }
+
    default: {
+
      luaL_argerror(L, arg, "value has no literal form");
+
    }
+
  }
+
}
+

+

+
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
+
  const char *p = strfrmt;
+
  while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++;  /* skip flags */
+
  if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char))
+
    luaL_error(L, "invalid format (repeated flags)");
+
  if (isdigit(uchar(*p))) p++;  /* skip width */
+
  if (isdigit(uchar(*p))) p++;  /* (2 digits at most) */
+
  if (*p == '.') {
+
    p++;
+
    if (isdigit(uchar(*p))) p++;  /* skip precision */
+
    if (isdigit(uchar(*p))) p++;  /* (2 digits at most) */
+
  }
+
  if (isdigit(uchar(*p)))
+
    luaL_error(L, "invalid format (width or precision too long)");
+
  *(form++) = '%';
+
  memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char));
+
  form += (p - strfrmt) + 1;
+
  *form = '\0';
+
  return p;
+
}
+

+

+
/*
+
** add length modifier into formats
+
*/
+
static void addlenmod (char *form, const char *lenmod) {
+
  size_t l = strlen(form);
+
  size_t lm = strlen(lenmod);
+
  char spec = form[l - 1];
+
  strcpy(form + l - 1, lenmod);
+
  form[l + lm - 1] = spec;
+
  form[l + lm] = '\0';
+
}
+

+

+
static int str_format (lua_State *L) {
+
  int top = lua_gettop(L);
+
  int arg = 1;
+
  size_t sfl;
+
  const char *strfrmt = luaL_checklstring(L, arg, &sfl);
+
  const char *strfrmt_end = strfrmt+sfl;
+
  luaL_Buffer b;
+
  luaL_buffinit(L, &b);
+
  while (strfrmt < strfrmt_end) {
+
    if (*strfrmt != L_ESC)
+
      luaL_addchar(&b, *strfrmt++);
+
    else if (*++strfrmt == L_ESC)
+
      luaL_addchar(&b, *strfrmt++);  /* %% */
+
    else { /* format 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);
+
      switch (*strfrmt++) {
+
        case 'c': {
+
          nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg));
+
          break;
+
        }
+
        case 'd': case 'i':
+
        case 'o': case 'u': case 'x': case 'X': {
+
          lua_Integer n = luaL_checkinteger(L, arg);
+
          addlenmod(form, LUA_INTEGER_FRMLEN);
+
          nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n);
+
          break;
+
        }
+
        case 'a': case 'A':
+
          addlenmod(form, LUA_NUMBER_FRMLEN);
+
          nb = lua_number2strx(L, buff, MAX_ITEM, form,
+
                                  luaL_checknumber(L, arg));
+
          break;
+
        case 'e': case 'E': case 'f':
+
        case 'g': case 'G': {
+
          lua_Number n = luaL_checknumber(L, arg);
+
          addlenmod(form, LUA_NUMBER_FRMLEN);
+
          nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n);
+
          break;
+
        }
+
        case 'q': {
+
          addliteral(L, &b, arg);
+
          break;
+
        }
+
        case 's': {
+
          size_t l;
+
          const char *s = luaL_tolstring(L, arg, &l);
+
          if (form[2] == '\0')  /* no modifiers? */
+
            luaL_addvalue(&b);  /* keep entire string */
+
          else {
+
            luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
+
            if (!strchr(form, '.') && l >= 100) {
+
              /* no precision and string is too long to be formatted */
+
              luaL_addvalue(&b);  /* keep entire string */
+
            }
+
            else {  /* format the string into 'buff' */
+
              nb = l_sprintf(buff, MAX_ITEM, form, s);
+
              lua_pop(L, 1);  /* remove result from 'luaL_tolstring' */
+
            }
+
          }
+
          break;
+
        }
+
        default: {  /* also treat cases 'pnLlh' */
+
          return luaL_error(L, "invalid option '%%%c' to 'format'",
+
                               *(strfrmt - 1));
+
        }
+
      }
+
      lua_assert(nb < MAX_ITEM);
+
      luaL_addsize(&b, nb);
+
    }
+
  }
+
  luaL_pushresult(&b);
+
  return 1;
+
}
+

+
/* }====================================================== */
+

+

+
/*
+
** {======================================================
+
** PACK/UNPACK
+
** =======================================================
+
*/
+

+

+
/* value used for padding */
+
#if !defined(LUAL_PACKPADBYTE)
+
#define LUAL_PACKPADBYTE		0x00
+
#endif
+

+
/* maximum size for the binary representation of an integer */
+
#define MAXINTSIZE	16
+

+
/* number of bits in a character */
+
#define NB	CHAR_BIT
+

+
/* mask for one character (NB 1's) */
+
#define MC	((1 << NB) - 1)
+

+
/* size of a lua_Integer */
+
#define SZINT	((int)sizeof(lua_Integer))
+

+

+
/* dummy union to get native endianness */
+
static const union {
+
  int dummy;
+
  char little;  /* true iff machine is little endian */
+
} nativeendian = {1};
+

+

+
/* dummy structure to get native alignment requirements */
+
struct cD {
+
  char c;
+
  union { double d; void *p; lua_Integer i; lua_Number n; } u;
+
};
+

+
#define MAXALIGN	(offsetof(struct cD, u))
+

+

+
/*
+
** Union for serializing floats
+
*/
+
typedef union Ftypes {
+
  float f;
+
  double d;
+
  lua_Number n;
+
  char buff[5 * sizeof(lua_Number)];  /* enough for any float type */
+
} Ftypes;
+

+

+
/*
+
** information to pack/unpack stuff
+
*/
+
typedef struct Header {
+
  lua_State *L;
+
  int islittle;
+
  int maxalign;
+
} Header;
+

+

+
/*
+
** options for pack/unpack
+
*/
+
typedef enum KOption {
+
  Kint,		/* signed integers */
+
  Kuint,	/* unsigned integers */
+
  Kfloat,	/* floating-point numbers */
+
  Kchar,	/* fixed-length strings */
+
  Kstring,	/* strings with prefixed length */
+
  Kzstr,	/* zero-terminated strings */
+
  Kpadding,	/* padding */
+
  Kpaddalign,	/* padding for alignment */
+
  Knop		/* no-op (configuration or spaces) */
+
} KOption;
+

+

+
/*
+
** Read an integer numeral from string 'fmt' or return 'df' if
+
** there is no numeral
+
*/
+
static int digit (int c) { return '0' <= c && c <= '9'; }
+

+
static int getnum (const char **fmt, int df) {
+
  if (!digit(**fmt))  /* no number? */
+
    return df;  /* return default value */
+
  else {
+
    int a = 0;
+
    do {
+
      a = a*10 + (*((*fmt)++) - '0');
+
    } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10);
+
    return a;
+
  }
+
}
+

+

+
/*
+
** Read an integer numeral and raises an error if it is larger
+
** than the maximum size for integers.
+
*/
+
static int getnumlimit (Header *h, const char **fmt, int df) {
+
  int sz = getnum(fmt, df);
+
  if (sz > MAXINTSIZE || sz <= 0)
+
    return luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
+
                            sz, MAXINTSIZE);
+
  return sz;
+
}
+

+

+
/*
+
** Initialize Header
+
*/
+
static void initheader (lua_State *L, Header *h) {
+
  h->L = L;
+
  h->islittle = nativeendian.little;
+
  h->maxalign = 1;
+
}
+

+

+
/*
+
** Read and classify next option. 'size' is filled with option's size.
+
*/
+
static KOption getoption (Header *h, const char **fmt, int *size) {
+
  int opt = *((*fmt)++);
+
  *size = 0;  /* default */
+
  switch (opt) {
+
    case 'b': *size = sizeof(char); return Kint;
+
    case 'B': *size = sizeof(char); return Kuint;
+
    case 'h': *size = sizeof(short); return Kint;
+
    case 'H': *size = sizeof(short); return Kuint;
+
    case 'l': *size = sizeof(long); return Kint;
+
    case 'L': *size = sizeof(long); return Kuint;
+
    case 'j': *size = sizeof(lua_Integer); return Kint;
+
    case 'J': *size = sizeof(lua_Integer); return Kuint;
+
    case 'T': *size = sizeof(size_t); return Kuint;
+
    case 'f': *size = sizeof(float); return Kfloat;
+
    case 'd': *size = sizeof(double); return Kfloat;
+
    case 'n': *size = sizeof(lua_Number); return Kfloat;
+
    case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint;
+
    case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
+
    case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
+
    case 'c':
+
      *size = getnum(fmt, -1);
+
      if (*size == -1)
+
        luaL_error(h->L, "missing size for format option 'c'");
+
      return Kchar;
+
    case 'z': return Kzstr;
+
    case 'x': *size = 1; return Kpadding;
+
    case 'X': return Kpaddalign;
+
    case ' ': break;
+
    case '<': h->islittle = 1; break;
+
    case '>': h->islittle = 0; break;
+
    case '=': h->islittle = nativeendian.little; break;
+
    case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break;
+
    default: luaL_error(h->L, "invalid format option '%c'", opt);
+
  }
+
  return Knop;
+
}
+

+

+
/*
+
** Read, classify, and fill other details about the next option.
+
** 'psize' is filled with option's size, 'notoalign' with its
+
** alignment requirements.
+
** Local variable 'size' gets the size to be aligned. (Kpadal option
+
** always gets its full alignment, other options are limited by
+
** the maximum alignment ('maxalign'). Kchar option needs no alignment
+
** despite its size.
+
*/
+
static KOption getdetails (Header *h, size_t totalsize,
+
                           const char **fmt, int *psize, int *ntoalign) {
+
  KOption opt = getoption(h, fmt, psize);
+
  int align = *psize;  /* usually, alignment follows size */
+
  if (opt == Kpaddalign) {  /* 'X' gets alignment from following option */
+
    if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0)
+
      luaL_argerror(h->L, 1, "invalid next option for option 'X'");
+
  }
+
  if (align <= 1 || opt == Kchar)  /* need no alignment? */
+
    *ntoalign = 0;
+
  else {
+
    if (align > h->maxalign)  /* enforce maximum alignment */
+
      align = h->maxalign;
+
    if ((align & (align - 1)) != 0)  /* is 'align' not a power of 2? */
+
      luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
+
    *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1);
+
  }
+
  return opt;
+
}
+

+

+
/*
+
** Pack integer 'n' with 'size' bytes and 'islittle' endianness.
+
** The final 'if' handles the case when 'size' is larger than
+
** the size of a Lua integer, correcting the extra sign-extension
+
** bytes if necessary (by default they would be zeros).
+
*/
+
static void packint (luaL_Buffer *b, lua_Unsigned n,
+
                     int islittle, int size, int neg) {
+
  char *buff = luaL_prepbuffsize(b, size);
+
  int i;
+
  buff[islittle ? 0 : size - 1] = (char)(n & MC);  /* first byte */
+
  for (i = 1; i < size; i++) {
+
    n >>= NB;
+
    buff[islittle ? i : size - 1 - i] = (char)(n & MC);
+
  }
+
  if (neg && size > SZINT) {  /* negative number need sign extension? */
+
    for (i = SZINT; i < size; i++)  /* correct extra bytes */
+
      buff[islittle ? i : size - 1 - i] = (char)MC;
+
  }
+
  luaL_addsize(b, size);  /* add result to buffer */
+
}
+

+

+
/*
+
** Copy 'size' bytes from 'src' to 'dest', correcting endianness if
+
** given 'islittle' is different from native endianness.
+
*/
+
static void copywithendian (volatile char *dest, volatile const char *src,
+
                            int size, int islittle) {
+
  if (islittle == nativeendian.little) {
+
    while (size-- != 0)
+
      *(dest++) = *(src++);
+
  }
+
  else {
+
    dest += size - 1;
+
    while (size-- != 0)
+
      *(dest--) = *(src++);
+
  }
+
}
+

+

+
static int str_pack (lua_State *L) {
+
  luaL_Buffer b;
+
  Header h;
+
  const char *fmt = luaL_checkstring(L, 1);  /* format string */
+
  int arg = 1;  /* current argument to pack */
+
  size_t totalsize = 0;  /* accumulate total size of result */
+
  initheader(L, &h);
+
  lua_pushnil(L);  /* mark to separate arguments from string buffer */
+
  luaL_buffinit(L, &b);
+
  while (*fmt != '\0') {
+
    int size, ntoalign;
+
    KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
+
    totalsize += ntoalign + size;
+
    while (ntoalign-- > 0)
+
     luaL_addchar(&b, LUAL_PACKPADBYTE);  /* fill alignment */
+
    arg++;
+
    switch (opt) {
+
      case Kint: {  /* signed integers */
+
        lua_Integer n = luaL_checkinteger(L, arg);
+
        if (size < SZINT) {  /* need overflow check? */
+
          lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1);
+
          luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow");
+
        }
+
        packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0));
+
        break;
+
      }
+
      case Kuint: {  /* unsigned integers */
+
        lua_Integer n = luaL_checkinteger(L, arg);
+
        if (size < SZINT)  /* need overflow check? */
+
          luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)),
+
                           arg, "unsigned overflow");
+
        packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
+
        break;
+
      }
+
      case Kfloat: {  /* floating-point options */
+
        volatile Ftypes u;
+
        char *buff = luaL_prepbuffsize(&b, size);
+
        lua_Number n = luaL_checknumber(L, arg);  /* get argument */
+
        if (size == sizeof(u.f)) u.f = (float)n;  /* copy it into 'u' */
+
        else if (size == sizeof(u.d)) u.d = (double)n;
+
        else u.n = n;
+
        /* move 'u' to final result, correcting endianness if needed */
+
        copywithendian(buff, u.buff, size, h.islittle);
+
        luaL_addsize(&b, size);
+
        break;
+
      }
+
      case Kchar: {  /* fixed-size string */
+
        size_t len;
+
        const char *s = luaL_checklstring(L, arg, &len);
+
        luaL_argcheck(L, len <= (size_t)size, arg,
+
                         "string longer than given size");
+
        luaL_addlstring(&b, s, len);  /* add string */
+
        while (len++ < (size_t)size)  /* pad extra space */
+
          luaL_addchar(&b, LUAL_PACKPADBYTE);
+
        break;
+
      }
+
      case Kstring: {  /* strings with length count */
+
        size_t len;
+
        const char *s = luaL_checklstring(L, arg, &len);
+
        luaL_argcheck(L, size >= (int)sizeof(size_t) ||
+
                         len < ((size_t)1 << (size * NB)),
+
                         arg, "string length does not fit in given size");
+
        packint(&b, (lua_Unsigned)len, h.islittle, size, 0);  /* pack length */
+
        luaL_addlstring(&b, s, len);
+
        totalsize += len;
+
        break;
+
      }
+
      case Kzstr: {  /* zero-terminated string */
+
        size_t len;
+
        const char *s = luaL_checklstring(L, arg, &len);
+
        luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros");
+
        luaL_addlstring(&b, s, len);
+
        luaL_addchar(&b, '\0');  /* add zero at the end */
+
        totalsize += len + 1;
+
        break;
+
      }
+
      case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE);  /* FALLTHROUGH */
+
      case Kpaddalign: case Knop:
+
        arg--;  /* undo increment */
+
        break;
+
    }
+
  }
+
  luaL_pushresult(&b);
+
  return 1;
+
}
+

+

+
static int str_packsize (lua_State *L) {
+
  Header h;
+
  const char *fmt = luaL_checkstring(L, 1);  /* format string */
+
  size_t totalsize = 0;  /* accumulate total size of result */
+
  initheader(L, &h);
+
  while (*fmt != '\0') {
+
    int size, ntoalign;
+
    KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
+
    size += ntoalign;  /* total space used by option */
+
    luaL_argcheck(L, totalsize <= MAXSIZE - size, 1,
+
                     "format result too large");
+
    totalsize += size;
+
    switch (opt) {
+
      case Kstring:  /* strings with length count */
+
      case Kzstr:    /* zero-terminated string */
+
        luaL_argerror(L, 1, "variable-length format");
+
        /* call never return, but to avoid warnings: *//* FALLTHROUGH */
+
      default:  break;
+
    }
+
  }
+
  lua_pushinteger(L, (lua_Integer)totalsize);
+
  return 1;
+
}
+

+

+
/*
+
** Unpack an integer with 'size' bytes and 'islittle' endianness.
+
** If size is smaller than the size of a Lua integer and integer
+
** is signed, must do sign extension (propagating the sign to the
+
** higher bits); if size is larger than the size of a Lua integer,
+
** it must check the unread bytes to see whether they do not cause an
+
** overflow.
+
*/
+
static lua_Integer unpackint (lua_State *L, const char *str,
+
                              int islittle, int size, int issigned) {
+
  lua_Unsigned res = 0;
+
  int i;
+
  int limit = (size  <= SZINT) ? size : SZINT;
+
  for (i = limit - 1; i >= 0; i--) {
+
    res <<= NB;
+
    res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i];
+
  }
+
  if (size < SZINT) {  /* real size smaller than lua_Integer? */
+
    if (issigned) {  /* needs sign extension? */
+
      lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1);
+
      res = ((res ^ mask) - mask);  /* do sign extension */
+
    }
+
  }
+
  else if (size > SZINT) {  /* must check unread bytes */
+
    int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC;
+
    for (i = limit; i < size; i++) {
+
      if ((unsigned char)str[islittle ? i : size - 1 - i] != mask)
+
        luaL_error(L, "%d-byte integer does not fit into Lua Integer", size);
+
    }
+
  }
+
  return (lua_Integer)res;
+
}
+

+

+
static int str_unpack (lua_State *L) {
+
  Header h;
+
  const char *fmt = luaL_checkstring(L, 1);
+
  size_t ld;
+
  const char *data = luaL_checklstring(L, 2, &ld);
+
  size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1;
+
  int n = 0;  /* number of results */
+
  luaL_argcheck(L, pos <= ld, 3, "initial position out of string");
+
  initheader(L, &h);
+
  while (*fmt != '\0') {
+
    int size, ntoalign;
+
    KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
+
    if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld)
+
      luaL_argerror(L, 2, "data string too short");
+
    pos += ntoalign;  /* skip alignment */
+
    /* stack space for item + next position */
+
    luaL_checkstack(L, 2, "too many results");
+
    n++;
+
    switch (opt) {
+
      case Kint:
+
      case Kuint: {
+
        lua_Integer res = unpackint(L, data + pos, h.islittle, size,
+
                                       (opt == Kint));
+
        lua_pushinteger(L, res);
+
        break;
+
      }
+
      case Kfloat: {
+
        volatile Ftypes u;
+
        lua_Number num;
+
        copywithendian(u.buff, data + pos, size, h.islittle);
+
        if (size == sizeof(u.f)) num = (lua_Number)u.f;
+
        else if (size == sizeof(u.d)) num = (lua_Number)u.d;
+
        else num = u.n;
+
        lua_pushnumber(L, num);
+
        break;
+
      }
+
      case Kchar: {
+
        lua_pushlstring(L, data + pos, size);
+
        break;
+
      }
+
      case Kstring: {
+
        size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0);
+
        luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short");
+
        lua_pushlstring(L, data + pos + size, len);
+
        pos += len;  /* skip string */
+
        break;
+
      }
+
      case Kzstr: {
+
        size_t len = (int)strlen(data + pos);
+
        lua_pushlstring(L, data + pos, len);
+
        pos += len + 1;  /* skip string plus final '\0' */
+
        break;
+
      }
+
      case Kpaddalign: case Kpadding: case Knop:
+
        n--;  /* undo increment */
+
        break;
+
    }
+
    pos += size;
+
  }
+
  lua_pushinteger(L, pos + 1);  /* next position */
+
  return n + 1;
+
}
+

+
/* }====================================================== */
+

+

+
static const luaL_Reg strlib[] = {
+
  {"byte", str_byte},
+
  {"char", str_char},
+
  {"dump", str_dump},
+
  {"find", str_find},
+
  {"format", str_format},
+
  {"gmatch", gmatch},
+
  {"gsub", str_gsub},
+
  {"len", str_len},
+
  {"lower", str_lower},
+
  {"match", str_match},
+
  {"rep", str_rep},
+
  {"reverse", str_reverse},
+
  {"sub", str_sub},
+
  {"upper", str_upper},
+
  {"pack", str_pack},
+
  {"packsize", str_packsize},
+
  {"unpack", str_unpack},
+
  {NULL, NULL}
+
};
+

+

+
static void createmetatable (lua_State *L) {
+
  lua_createtable(L, 0, 1);  /* table to be metatable for strings */
+
  lua_pushliteral(L, "");  /* dummy string */
+
  lua_pushvalue(L, -2);  /* copy table */
+
  lua_setmetatable(L, -2);  /* set table as metatable for strings */
+
  lua_pop(L, 1);  /* pop dummy string */
+
  lua_pushvalue(L, -2);  /* get string library */
+
  lua_setfield(L, -2, "__index");  /* metatable.__index = string */
+
  lua_pop(L, 1);  /* pop metatable */
+
}
+

+

+
/*
+
** Open string library
+
*/
+
LUAMOD_API int luaopen_string (lua_State *L) {
+
  luaL_newlib(L, strlib);
+
  createmetatable(L);
+
  return 1;
+
}
+

added external/lua/src/ltable.c
@@ -0,0 +1,688 @@
+
/*
+
** $Id: ltable.c,v 2.118.1.4 2018/06/08 16:22:51 roberto Exp $
+
** Lua tables (hash)
+
** See Copyright Notice in lua.h
+
*/
+

+
#define ltable_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
/*
+
** Implementation of tables (aka arrays, objects, or hash tables).
+
** Tables keep its elements in two parts: an array part and a hash part.
+
** Non-negative integer keys are all candidates to be kept in the array
+
** part. The actual size of the array is the largest 'n' such that
+
** more than half the slots between 1 and n are in use.
+
** Hash uses a mix of chained scatter table with Brent's variation.
+
** A main invariant of these tables is that, if an element is not
+
** in its main position (i.e. the 'original' position that its hash gives
+
** to it), then the colliding element is in its own main position.
+
** Hence even when the load factor reaches 100%, performance remains good.
+
*/
+

+
#include <math.h>
+
#include <limits.h>
+

+
#include "lua.h"
+

+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lgc.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "lvm.h"
+

+

+
/*
+
** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is
+
** the largest integer such that MAXASIZE fits in an unsigned int.
+
*/
+
#define MAXABITS	cast_int(sizeof(int) * CHAR_BIT - 1)
+
#define MAXASIZE	(1u << MAXABITS)
+

+
/*
+
** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest
+
** integer such that 2^MAXHBITS fits in a signed int. (Note that the
+
** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still
+
** fits comfortably in an unsigned int.)
+
*/
+
#define MAXHBITS	(MAXABITS - 1)
+

+

+
#define hashpow2(t,n)		(gnode(t, lmod((n), sizenode(t))))
+

+
#define hashstr(t,str)		hashpow2(t, (str)->hash)
+
#define hashboolean(t,p)	hashpow2(t, p)
+
#define hashint(t,i)		hashpow2(t, i)
+

+

+
/*
+
** for some types, it is better to avoid modulus by power of 2, as
+
** they tend to have many 2 factors.
+
*/
+
#define hashmod(t,n)	(gnode(t, ((n) % ((sizenode(t)-1)|1))))
+

+

+
#define hashpointer(t,p)	hashmod(t, point2uint(p))
+

+

+
#define dummynode		(&dummynode_)
+

+
static const Node dummynode_ = {
+
  {NILCONSTANT},  /* value */
+
  {{NILCONSTANT, 0}}  /* key */
+
};
+

+

+
/*
+
** Hash for floating-point numbers.
+
** The main computation should be just
+
**     n = frexp(n, &i); return (n * INT_MAX) + i
+
** but there are some numerical subtleties.
+
** In a two-complement representation, INT_MAX does not has an exact
+
** representation as a float, but INT_MIN does; because the absolute
+
** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
+
** absolute value of the product 'frexp * -INT_MIN' is smaller or equal
+
** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when
+
** adding 'i'; the use of '~u' (instead of '-u') avoids problems with
+
** INT_MIN.
+
*/
+
#if !defined(l_hashfloat)
+
static int l_hashfloat (lua_Number n) {
+
  int i;
+
  lua_Integer ni;
+
  n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN);
+
  if (!lua_numbertointeger(n, &ni)) {  /* is 'n' inf/-inf/NaN? */
+
    lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL));
+
    return 0;
+
  }
+
  else {  /* normal case */
+
    unsigned int u = cast(unsigned int, i) + cast(unsigned int, ni);
+
    return cast_int(u <= cast(unsigned int, INT_MAX) ? u : ~u);
+
  }
+
}
+
#endif
+

+

+
/*
+
** returns the 'main' position of an element in a table (that is, the index
+
** of its hash value)
+
*/
+
static Node *mainposition (const Table *t, const TValue *key) {
+
  switch (ttype(key)) {
+
    case LUA_TNUMINT:
+
      return hashint(t, ivalue(key));
+
    case LUA_TNUMFLT:
+
      return hashmod(t, l_hashfloat(fltvalue(key)));
+
    case LUA_TSHRSTR:
+
      return hashstr(t, tsvalue(key));
+
    case LUA_TLNGSTR:
+
      return hashpow2(t, luaS_hashlongstr(tsvalue(key)));
+
    case LUA_TBOOLEAN:
+
      return hashboolean(t, bvalue(key));
+
    case LUA_TLIGHTUSERDATA:
+
      return hashpointer(t, pvalue(key));
+
    case LUA_TLCF:
+
      return hashpointer(t, fvalue(key));
+
    default:
+
      lua_assert(!ttisdeadkey(key));
+
      return hashpointer(t, gcvalue(key));
+
  }
+
}
+

+

+
/*
+
** returns the index for 'key' if 'key' is an appropriate key to live in
+
** the array part of the table, 0 otherwise.
+
*/
+
static unsigned int arrayindex (const TValue *key) {
+
  if (ttisinteger(key)) {
+
    lua_Integer k = ivalue(key);
+
    if (0 < k && (lua_Unsigned)k <= MAXASIZE)
+
      return cast(unsigned int, k);  /* 'key' is an appropriate array index */
+
  }
+
  return 0;  /* 'key' did not match some condition */
+
}
+

+

+
/*
+
** returns the index of a 'key' for table traversals. First goes all
+
** elements in the array part, then elements in the hash part. The
+
** beginning of a traversal is signaled by 0.
+
*/
+
static unsigned int findindex (lua_State *L, Table *t, StkId key) {
+
  unsigned int i;
+
  if (ttisnil(key)) return 0;  /* first iteration */
+
  i = arrayindex(key);
+
  if (i != 0 && i <= t->sizearray)  /* is 'key' inside array part? */
+
    return i;  /* yes; that's the index */
+
  else {
+
    int nx;
+
    Node *n = mainposition(t, key);
+
    for (;;) {  /* check whether 'key' is somewhere in the chain */
+
      /* key may be dead already, but it is ok to use it in 'next' */
+
      if (luaV_rawequalobj(gkey(n), key) ||
+
            (ttisdeadkey(gkey(n)) && iscollectable(key) &&
+
             deadvalue(gkey(n)) == gcvalue(key))) {
+
        i = cast_int(n - gnode(t, 0));  /* key index in hash table */
+
        /* hash elements are numbered after array ones */
+
        return (i + 1) + t->sizearray;
+
      }
+
      nx = gnext(n);
+
      if (nx == 0)
+
        luaG_runerror(L, "invalid key to 'next'");  /* key not found */
+
      else n += nx;
+
    }
+
  }
+
}
+

+

+
int luaH_next (lua_State *L, Table *t, StkId key) {
+
  unsigned int i = findindex(L, t, key);  /* find original element */
+
  for (; i < t->sizearray; i++) {  /* try first array part */
+
    if (!ttisnil(&t->array[i])) {  /* a non-nil value? */
+
      setivalue(key, i + 1);
+
      setobj2s(L, key+1, &t->array[i]);
+
      return 1;
+
    }
+
  }
+
  for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) {  /* hash part */
+
    if (!ttisnil(gval(gnode(t, i)))) {  /* a non-nil value? */
+
      setobj2s(L, key, gkey(gnode(t, i)));
+
      setobj2s(L, key+1, gval(gnode(t, i)));
+
      return 1;
+
    }
+
  }
+
  return 0;  /* no more elements */
+
}
+

+

+
/*
+
** {=============================================================
+
** Rehash
+
** ==============================================================
+
*/
+

+
/*
+
** Compute the optimal size for the array part of table 't'. 'nums' is a
+
** "count array" where 'nums[i]' is the number of integers in the table
+
** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of
+
** integer keys in the table and leaves with the number of keys that
+
** will go to the array part; return the optimal size.
+
*/
+
static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
+
  int i;
+
  unsigned int twotoi;  /* 2^i (candidate for optimal size) */
+
  unsigned int a = 0;  /* number of elements smaller than 2^i */
+
  unsigned int na = 0;  /* number of elements to go to array part */
+
  unsigned int optimal = 0;  /* optimal size for array part */
+
  /* loop while keys can fill more than half of total size */
+
  for (i = 0, twotoi = 1;
+
       twotoi > 0 && *pna > twotoi / 2;
+
       i++, twotoi *= 2) {
+
    if (nums[i] > 0) {
+
      a += nums[i];
+
      if (a > twotoi/2) {  /* more than half elements present? */
+
        optimal = twotoi;  /* optimal size (till now) */
+
        na = a;  /* all elements up to 'optimal' will go to array part */
+
      }
+
    }
+
  }
+
  lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal);
+
  *pna = na;
+
  return optimal;
+
}
+

+

+
static int countint (const TValue *key, unsigned int *nums) {
+
  unsigned int k = arrayindex(key);
+
  if (k != 0) {  /* is 'key' an appropriate array index? */
+
    nums[luaO_ceillog2(k)]++;  /* count as such */
+
    return 1;
+
  }
+
  else
+
    return 0;
+
}
+

+

+
/*
+
** Count keys in array part of table 't': Fill 'nums[i]' with
+
** number of keys that will go into corresponding slice and return
+
** total number of non-nil keys.
+
*/
+
static unsigned int numusearray (const Table *t, unsigned int *nums) {
+
  int lg;
+
  unsigned int ttlg;  /* 2^lg */
+
  unsigned int ause = 0;  /* summation of 'nums' */
+
  unsigned int i = 1;  /* count to traverse all array keys */
+
  /* traverse each slice */
+
  for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) {
+
    unsigned int lc = 0;  /* counter */
+
    unsigned int lim = ttlg;
+
    if (lim > t->sizearray) {
+
      lim = t->sizearray;  /* adjust upper limit */
+
      if (i > lim)
+
        break;  /* no more elements to count */
+
    }
+
    /* count elements in range (2^(lg - 1), 2^lg] */
+
    for (; i <= lim; i++) {
+
      if (!ttisnil(&t->array[i-1]))
+
        lc++;
+
    }
+
    nums[lg] += lc;
+
    ause += lc;
+
  }
+
  return ause;
+
}
+

+

+
static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
+
  int totaluse = 0;  /* total number of elements */
+
  int ause = 0;  /* elements added to 'nums' (can go to array part) */
+
  int i = sizenode(t);
+
  while (i--) {
+
    Node *n = &t->node[i];
+
    if (!ttisnil(gval(n))) {
+
      ause += countint(gkey(n), nums);
+
      totaluse++;
+
    }
+
  }
+
  *pna += ause;
+
  return totaluse;
+
}
+

+

+
static void setarrayvector (lua_State *L, Table *t, unsigned int size) {
+
  unsigned int i;
+
  luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
+
  for (i=t->sizearray; i<size; i++)
+
     setnilvalue(&t->array[i]);
+
  t->sizearray = size;
+
}
+

+

+
static void setnodevector (lua_State *L, Table *t, unsigned int size) {
+
  if (size == 0) {  /* no elements to hash part? */
+
    t->node = cast(Node *, dummynode);  /* use common 'dummynode' */
+
    t->lsizenode = 0;
+
    t->lastfree = NULL;  /* signal that it is using dummy node */
+
  }
+
  else {
+
    int i;
+
    int lsize = luaO_ceillog2(size);
+
    if (lsize > MAXHBITS)
+
      luaG_runerror(L, "table overflow");
+
    size = twoto(lsize);
+
    t->node = luaM_newvector(L, size, Node);
+
    for (i = 0; i < (int)size; i++) {
+
      Node *n = gnode(t, i);
+
      gnext(n) = 0;
+
      setnilvalue(wgkey(n));
+
      setnilvalue(gval(n));
+
    }
+
    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);
+
}
+

+

+
void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
+
                                          unsigned int nhsize) {
+
  unsigned int i;
+
  int j;
+
  AuxsetnodeT asn;
+
  unsigned int oldasize = t->sizearray;
+
  int oldhsize = allocsizenode(t);
+
  Node *nold = t->node;  /* save old hash ... */
+
  if (nasize > oldasize)  /* array part must grow? */
+
    setarrayvector(L, t, nasize);
+
  /* create new hash part with appropriate size */
+
  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? */
+
    t->sizearray = nasize;
+
    /* re-insert elements from vanishing slice */
+
    for (i=nasize; i<oldasize; i++) {
+
      if (!ttisnil(&t->array[i]))
+
        luaH_setint(L, t, i + 1, &t->array[i]);
+
    }
+
    /* shrink array */
+
    luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
+
  }
+
  /* re-insert elements from hash part */
+
  for (j = oldhsize - 1; j >= 0; j--) {
+
    Node *old = nold + j;
+
    if (!ttisnil(gval(old))) {
+
      /* doesn't need barrier/invalidate cache, as entry was
+
         already present in the table */
+
      setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
+
    }
+
  }
+
  if (oldhsize > 0)  /* not the dummy node? */
+
    luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */
+
}
+

+

+
void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
+
  int nsize = allocsizenode(t);
+
  luaH_resize(L, t, nasize, nsize);
+
}
+

+
/*
+
** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
+
*/
+
static void rehash (lua_State *L, Table *t, const TValue *ek) {
+
  unsigned int asize;  /* optimal size for array part */
+
  unsigned int na;  /* number of keys in the array part */
+
  unsigned int nums[MAXABITS + 1];
+
  int i;
+
  int totaluse;
+
  for (i = 0; i <= MAXABITS; i++) nums[i] = 0;  /* reset counts */
+
  na = numusearray(t, nums);  /* count keys in array part */
+
  totaluse = na;  /* all those keys are integer keys */
+
  totaluse += numusehash(t, nums, &na);  /* count keys in hash part */
+
  /* count extra key */
+
  na += countint(ek, nums);
+
  totaluse++;
+
  /* compute new size for array part */
+
  asize = computesizes(nums, &na);
+
  /* resize the table to new computed sizes */
+
  luaH_resize(L, t, asize, totaluse - na);
+
}
+

+

+

+
/*
+
** }=============================================================
+
*/
+

+

+
Table *luaH_new (lua_State *L) {
+
  GCObject *o = luaC_newobj(L, LUA_TTABLE, sizeof(Table));
+
  Table *t = gco2t(o);
+
  t->metatable = NULL;
+
  t->flags = cast_byte(~0);
+
  t->array = NULL;
+
  t->sizearray = 0;
+
  setnodevector(L, t, 0);
+
  return t;
+
}
+

+

+
void luaH_free (lua_State *L, Table *t) {
+
  if (!isdummy(t))
+
    luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
+
  luaM_freearray(L, t->array, t->sizearray);
+
  luaM_free(L, t);
+
}
+

+

+
static Node *getfreepos (Table *t) {
+
  if (!isdummy(t)) {
+
    while (t->lastfree > t->node) {
+
      t->lastfree--;
+
      if (ttisnil(gkey(t->lastfree)))
+
        return t->lastfree;
+
    }
+
  }
+
  return NULL;  /* could not find a free place */
+
}
+

+

+

+
/*
+
** inserts a new key into a hash table; first, check whether key's main
+
** position is free. If not, check whether colliding node is in its main
+
** position or not: if it is not, move colliding node to an empty place and
+
** put new key in its main position; otherwise (colliding node is in its main
+
** position), new key goes to an empty position.
+
*/
+
TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
+
  Node *mp;
+
  TValue aux;
+
  if (ttisnil(key)) luaG_runerror(L, "table index is nil");
+
  else if (ttisfloat(key)) {
+
    lua_Integer k;
+
    if (luaV_tointeger(key, &k, 0)) {  /* does index fit in an integer? */
+
      setivalue(&aux, k);
+
      key = &aux;  /* insert it as an integer */
+
    }
+
    else if (luai_numisnan(fltvalue(key)))
+
      luaG_runerror(L, "table index is NaN");
+
  }
+
  mp = mainposition(t, key);
+
  if (!ttisnil(gval(mp)) || isdummy(t)) {  /* main position is taken? */
+
    Node *othern;
+
    Node *f = getfreepos(t);  /* get a free place */
+
    if (f == NULL) {  /* cannot find a free place? */
+
      rehash(L, t, key);  /* grow table */
+
      /* whatever called 'newkey' takes care of TM cache */
+
      return luaH_set(L, t, key);  /* insert key into grown table */
+
    }
+
    lua_assert(!isdummy(t));
+
    othern = mainposition(t, gkey(mp));
+
    if (othern != mp) {  /* is colliding node out of its main position? */
+
      /* yes; move colliding node into free position */
+
      while (othern + gnext(othern) != mp)  /* find previous */
+
        othern += gnext(othern);
+
      gnext(othern) = cast_int(f - othern);  /* rechain to point to 'f' */
+
      *f = *mp;  /* copy colliding node into free pos. (mp->next also goes) */
+
      if (gnext(mp) != 0) {
+
        gnext(f) += cast_int(mp - f);  /* correct 'next' */
+
        gnext(mp) = 0;  /* now 'mp' is free */
+
      }
+
      setnilvalue(gval(mp));
+
    }
+
    else {  /* colliding node is in its own main position */
+
      /* new node will go into free position */
+
      if (gnext(mp) != 0)
+
        gnext(f) = cast_int((mp + gnext(mp)) - f);  /* chain new position */
+
      else lua_assert(gnext(f) == 0);
+
      gnext(mp) = cast_int(f - mp);
+
      mp = f;
+
    }
+
  }
+
  setnodekey(L, &mp->i_key, key);
+
  luaC_barrierback(L, t, key);
+
  lua_assert(ttisnil(gval(mp)));
+
  return gval(mp);
+
}
+

+

+
/*
+
** search function for integers
+
*/
+
const TValue *luaH_getint (Table *t, lua_Integer key) {
+
  /* (1 <= key && key <= t->sizearray) */
+
  if (l_castS2U(key) - 1 < t->sizearray)
+
    return &t->array[key - 1];
+
  else {
+
    Node *n = hashint(t, key);
+
    for (;;) {  /* check whether 'key' is somewhere in the chain */
+
      if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key)
+
        return gval(n);  /* that's it */
+
      else {
+
        int nx = gnext(n);
+
        if (nx == 0) break;
+
        n += nx;
+
      }
+
    }
+
    return luaO_nilobject;
+
  }
+
}
+

+

+
/*
+
** search function for short strings
+
*/
+
const TValue *luaH_getshortstr (Table *t, TString *key) {
+
  Node *n = hashstr(t, key);
+
  lua_assert(key->tt == LUA_TSHRSTR);
+
  for (;;) {  /* check whether 'key' is somewhere in the chain */
+
    const TValue *k = gkey(n);
+
    if (ttisshrstring(k) && eqshrstr(tsvalue(k), key))
+
      return gval(n);  /* that's it */
+
    else {
+
      int nx = gnext(n);
+
      if (nx == 0)
+
        return luaO_nilobject;  /* not found */
+
      n += nx;
+
    }
+
  }
+
}
+

+

+
/*
+
** "Generic" get version. (Not that generic: not valid for integers,
+
** which may be in array part, nor for floats with integral values.)
+
*/
+
static const TValue *getgeneric (Table *t, const TValue *key) {
+
  Node *n = mainposition(t, key);
+
  for (;;) {  /* check whether 'key' is somewhere in the chain */
+
    if (luaV_rawequalobj(gkey(n), key))
+
      return gval(n);  /* that's it */
+
    else {
+
      int nx = gnext(n);
+
      if (nx == 0)
+
        return luaO_nilobject;  /* not found */
+
      n += nx;
+
    }
+
  }
+
}
+

+

+
const TValue *luaH_getstr (Table *t, TString *key) {
+
  if (key->tt == LUA_TSHRSTR)
+
    return luaH_getshortstr(t, key);
+
  else {  /* for long strings, use generic case */
+
    TValue ko;
+
    setsvalue(cast(lua_State *, NULL), &ko, key);
+
    return getgeneric(t, &ko);
+
  }
+
}
+

+

+
/*
+
** main search function
+
*/
+
const TValue *luaH_get (Table *t, const TValue *key) {
+
  switch (ttype(key)) {
+
    case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key));
+
    case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
+
    case LUA_TNIL: return luaO_nilobject;
+
    case LUA_TNUMFLT: {
+
      lua_Integer k;
+
      if (luaV_tointeger(key, &k, 0)) /* index is int? */
+
        return luaH_getint(t, k);  /* use specialized version */
+
      /* else... */
+
    }  /* FALLTHROUGH */
+
    default:
+
      return getgeneric(t, key);
+
  }
+
}
+

+

+
/*
+
** beware: when using this function you probably need to check a GC
+
** barrier and invalidate the TM cache.
+
*/
+
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
+
  const TValue *p = luaH_get(t, key);
+
  if (p != luaO_nilobject)
+
    return cast(TValue *, p);
+
  else return luaH_newkey(L, t, key);
+
}
+

+

+
void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
+
  const TValue *p = luaH_getint(t, key);
+
  TValue *cell;
+
  if (p != luaO_nilobject)
+
    cell = cast(TValue *, p);
+
  else {
+
    TValue k;
+
    setivalue(&k, key);
+
    cell = luaH_newkey(L, t, &k);
+
  }
+
  setobj2t(L, cell, value);
+
}
+

+

+
static lua_Unsigned unbound_search (Table *t, lua_Unsigned j) {
+
  lua_Unsigned i = j;  /* i is zero or a present index */
+
  j++;
+
  /* find 'i' and 'j' such that i is present and j is not */
+
  while (!ttisnil(luaH_getint(t, j))) {
+
    i = j;
+
    if (j > l_castS2U(LUA_MAXINTEGER) / 2) {  /* overflow? */
+
      /* table was built with bad purposes: resort to linear search */
+
      i = 1;
+
      while (!ttisnil(luaH_getint(t, i))) i++;
+
      return i - 1;
+
    }
+
    j *= 2;
+
  }
+
  /* now do a binary search between them */
+
  while (j - i > 1) {
+
    lua_Unsigned m = (i+j)/2;
+
    if (ttisnil(luaH_getint(t, m))) j = m;
+
    else i = m;
+
  }
+
  return i;
+
}
+

+

+
/*
+
** 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).
+
*/
+
lua_Unsigned luaH_getn (Table *t) {
+
  unsigned int j = t->sizearray;
+
  if (j > 0 && ttisnil(&t->array[j - 1])) {
+
    /* there is a boundary in the array part: (binary) search for it */
+
    unsigned int i = 0;
+
    while (j - i > 1) {
+
      unsigned int m = (i+j)/2;
+
      if (ttisnil(&t->array[m - 1])) j = m;
+
      else i = m;
+
    }
+
    return i;
+
  }
+
  /* else must find a boundary in hash part */
+
  else if (isdummy(t))  /* hash part is empty? */
+
    return j;  /* that is easy... */
+
  else return unbound_search(t, j);
+
}
+

+

+

+
#if defined(LUA_DEBUG)
+

+
Node *luaH_mainposition (const Table *t, const TValue *key) {
+
  return mainposition(t, key);
+
}
+

+
int luaH_isdummy (const Table *t) { return isdummy(t); }
+

+
#endif
added external/lua/src/ltable.h
@@ -0,0 +1,66 @@
+
/*
+
** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $
+
** Lua tables (hash)
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef ltable_h
+
#define ltable_h
+

+
#include "lobject.h"
+

+

+
#define gnode(t,i)	(&(t)->node[i])
+
#define gval(n)		(&(n)->i_val)
+
#define gnext(n)	((n)->i_key.nk.next)
+

+

+
/* 'const' to avoid wrong writings that can mess up field 'next' */
+
#define gkey(n)		cast(const TValue*, (&(n)->i_key.tvk))
+

+
/*
+
** writable version of 'gkey'; allows updates to individual fields,
+
** but not to the whole (which has incompatible type)
+
*/
+
#define wgkey(n)		(&(n)->i_key.nk)
+

+
#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 */
+
#define keyfromval(v) \
+
  (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
+

+

+
LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
+
LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
+
                                                    TValue *value);
+
LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
+
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
+
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
+
LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
+
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
+
LUAI_FUNC Table *luaH_new (lua_State *L);
+
LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
+
                                                    unsigned int nhsize);
+
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 int luaH_next (lua_State *L, Table *t, StkId key);
+
LUAI_FUNC lua_Unsigned luaH_getn (Table *t);
+

+

+
#if defined(LUA_DEBUG)
+
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
+
LUAI_FUNC int luaH_isdummy (const Table *t);
+
#endif
+

+

+
#endif
added external/lua/src/ltablib.c
@@ -0,0 +1,450 @@
+
/*
+
** $Id: ltablib.c,v 1.93.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Library for Table Manipulation
+
** See Copyright Notice in lua.h
+
*/
+

+
#define ltablib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <limits.h>
+
#include <stddef.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+
/*
+
** Operations that an object must define to mimic a table
+
** (some functions only need some of them)
+
*/
+
#define TAB_R	1			/* read */
+
#define TAB_W	2			/* write */
+
#define TAB_L	4			/* length */
+
#define TAB_RW	(TAB_R | TAB_W)		/* read/write */
+

+

+
#define aux_getn(L,n,w)	(checktab(L, n, (w) | TAB_L), luaL_len(L, n))
+

+

+
static int checkfield (lua_State *L, const char *key, int n) {
+
  lua_pushstring(L, key);
+
  return (lua_rawget(L, -n) != LUA_TNIL);
+
}
+

+

+
/*
+
** Check that 'arg' either is a table or can behave like one (that is,
+
** has a metatable with the required metamethods)
+
*/
+
static void checktab (lua_State *L, int arg, int what) {
+
  if (lua_type(L, arg) != LUA_TTABLE) {  /* is it not a table? */
+
    int n = 1;  /* number of elements to pop */
+
    if (lua_getmetatable(L, arg) &&  /* must have metatable */
+
        (!(what & TAB_R) || checkfield(L, "__index", ++n)) &&
+
        (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) &&
+
        (!(what & TAB_L) || checkfield(L, "__len", ++n))) {
+
      lua_pop(L, n);  /* pop metatable and tested metamethods */
+
    }
+
    else
+
      luaL_checktype(L, arg, LUA_TTABLE);  /* force an error */
+
  }
+
}
+

+

+
#if defined(LUA_COMPAT_MAXN)
+
static int maxn (lua_State *L) {
+
  lua_Number max = 0;
+
  luaL_checktype(L, 1, LUA_TTABLE);
+
  lua_pushnil(L);  /* first key */
+
  while (lua_next(L, 1)) {
+
    lua_pop(L, 1);  /* remove value */
+
    if (lua_type(L, -1) == LUA_TNUMBER) {
+
      lua_Number v = lua_tonumber(L, -1);
+
      if (v > max) max = v;
+
    }
+
  }
+
  lua_pushnumber(L, max);
+
  return 1;
+
}
+
#endif
+

+

+
static int tinsert (lua_State *L) {
+
  lua_Integer e = aux_getn(L, 1, TAB_RW) + 1;  /* first empty element */
+
  lua_Integer pos;  /* where to insert new element */
+
  switch (lua_gettop(L)) {
+
    case 2: {  /* called with only 2 arguments */
+
      pos = e;  /* insert new element at the end */
+
      break;
+
    }
+
    case 3: {
+
      lua_Integer i;
+
      pos = luaL_checkinteger(L, 2);  /* 2nd argument is the position */
+
      luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds");
+
      for (i = e; i > pos; i--) {  /* move up elements */
+
        lua_geti(L, 1, i - 1);
+
        lua_seti(L, 1, i);  /* t[i] = t[i - 1] */
+
      }
+
      break;
+
    }
+
    default: {
+
      return luaL_error(L, "wrong number of arguments to 'insert'");
+
    }
+
  }
+
  lua_seti(L, 1, pos);  /* t[pos] = v */
+
  return 0;
+
}
+

+

+
static int tremove (lua_State *L) {
+
  lua_Integer size = aux_getn(L, 1, TAB_RW);
+
  lua_Integer pos = luaL_optinteger(L, 2, size);
+
  if (pos != size)  /* validate 'pos' if given */
+
    luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds");
+
  lua_geti(L, 1, pos);  /* result = t[pos] */
+
  for ( ; pos < size; pos++) {
+
    lua_geti(L, 1, pos + 1);
+
    lua_seti(L, 1, pos);  /* t[pos] = t[pos + 1] */
+
  }
+
  lua_pushnil(L);
+
  lua_seti(L, 1, pos);  /* t[pos] = nil */
+
  return 1;
+
}
+

+

+
/*
+
** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever
+
** possible, copy in increasing order, which is better for rehashing.
+
** "possible" means destination after original range, or smaller
+
** than origin, or copying to another table.
+
*/
+
static int tmove (lua_State *L) {
+
  lua_Integer f = luaL_checkinteger(L, 2);
+
  lua_Integer e = luaL_checkinteger(L, 3);
+
  lua_Integer t = luaL_checkinteger(L, 4);
+
  int tt = !lua_isnoneornil(L, 5) ? 5 : 1;  /* destination table */
+
  checktab(L, 1, TAB_R);
+
  checktab(L, tt, TAB_W);
+
  if (e >= f) {  /* otherwise, nothing to move */
+
    lua_Integer n, i;
+
    luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
+
                  "too many elements to move");
+
    n = e - f + 1;  /* number of elements to move */
+
    luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
+
                  "destination wrap around");
+
    if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) {
+
      for (i = 0; i < n; i++) {
+
        lua_geti(L, 1, f + i);
+
        lua_seti(L, tt, t + i);
+
      }
+
    }
+
    else {
+
      for (i = n - 1; i >= 0; i--) {
+
        lua_geti(L, 1, f + i);
+
        lua_seti(L, tt, t + i);
+
      }
+
    }
+
  }
+
  lua_pushvalue(L, tt);  /* return destination table */
+
  return 1;
+
}
+

+

+
static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) {
+
  lua_geti(L, 1, i);
+
  if (!lua_isstring(L, -1))
+
    luaL_error(L, "invalid value (%s) at index %d in table for 'concat'",
+
                  luaL_typename(L, -1), i);
+
  luaL_addvalue(b);
+
}
+

+

+
static int tconcat (lua_State *L) {
+
  luaL_Buffer b;
+
  lua_Integer last = aux_getn(L, 1, TAB_R);
+
  size_t lsep;
+
  const char *sep = luaL_optlstring(L, 2, "", &lsep);
+
  lua_Integer i = luaL_optinteger(L, 3, 1);
+
  last = luaL_optinteger(L, 4, last);
+
  luaL_buffinit(L, &b);
+
  for (; i < last; i++) {
+
    addfield(L, &b, i);
+
    luaL_addlstring(&b, sep, lsep);
+
  }
+
  if (i == last)  /* add last value (if interval was not empty) */
+
    addfield(L, &b, i);
+
  luaL_pushresult(&b);
+
  return 1;
+
}
+

+

+
/*
+
** {======================================================
+
** Pack/unpack
+
** =======================================================
+
*/
+

+
static int pack (lua_State *L) {
+
  int i;
+
  int n = lua_gettop(L);  /* number of elements to pack */
+
  lua_createtable(L, n, 1);  /* create result table */
+
  lua_insert(L, 1);  /* put it at index 1 */
+
  for (i = n; i >= 1; i--)  /* assign elements */
+
    lua_seti(L, 1, i);
+
  lua_pushinteger(L, n);
+
  lua_setfield(L, 1, "n");  /* t.n = number of elements */
+
  return 1;  /* return table */
+
}
+

+

+
static int unpack (lua_State *L) {
+
  lua_Unsigned n;
+
  lua_Integer i = luaL_optinteger(L, 2, 1);
+
  lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1));
+
  if (i > e) return 0;  /* empty range */
+
  n = (lua_Unsigned)e - i;  /* number of elements minus 1 (avoid overflows) */
+
  if (n >= (unsigned int)INT_MAX  || !lua_checkstack(L, (int)(++n)))
+
    return luaL_error(L, "too many results to unpack");
+
  for (; i < e; i++) {  /* push arg[i..e - 1] (to avoid overflows) */
+
    lua_geti(L, 1, i);
+
  }
+
  lua_geti(L, 1, e);  /* push last element */
+
  return (int)n;
+
}
+

+
/* }====================================================== */
+

+

+

+
/*
+
** {======================================================
+
** Quicksort
+
** (based on 'Algorithms in MODULA-3', Robert Sedgewick;
+
**  Addison-Wesley, 1993.)
+
** =======================================================
+
*/
+

+

+
/* type for array indices */
+
typedef unsigned int IdxT;
+

+

+
/*
+
** Produce a "random" 'unsigned int' to randomize pivot choice. This
+
** macro is used only when 'sort' detects a big imbalance in the result
+
** of a partition. (If you don't want/need this "randomness", ~0 is a
+
** good choice.)
+
*/
+
#if !defined(l_randomizePivot)		/* { */
+

+
#include <time.h>
+

+
/* size of 'e' measured in number of 'unsigned int's */
+
#define sof(e)		(sizeof(e) / sizeof(unsigned int))
+

+
/*
+
** Use 'time' and 'clock' as sources of "randomness". Because we don't
+
** know the types 'clock_t' and 'time_t', we cannot cast them to
+
** anything without risking overflows. A safe way to use their values
+
** is to copy them to an array of a known type and use the array values.
+
*/
+
static unsigned int l_randomizePivot (void) {
+
  clock_t c = clock();
+
  time_t t = time(NULL);
+
  unsigned int buff[sof(c) + sof(t)];
+
  unsigned int i, rnd = 0;
+
  memcpy(buff, &c, sof(c) * sizeof(unsigned int));
+
  memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int));
+
  for (i = 0; i < sof(buff); i++)
+
    rnd += buff[i];
+
  return rnd;
+
}
+

+
#endif					/* } */
+

+

+
/* arrays larger than 'RANLIMIT' may use randomized pivots */
+
#define RANLIMIT	100u
+

+

+
static void set2 (lua_State *L, IdxT i, IdxT j) {
+
  lua_seti(L, 1, i);
+
  lua_seti(L, 1, j);
+
}
+

+

+
/*
+
** Return true iff value at stack index 'a' is less than the value at
+
** index 'b' (according to the order of the sort).
+
*/
+
static int sort_comp (lua_State *L, int a, int b) {
+
  if (lua_isnil(L, 2))  /* no function? */
+
    return lua_compare(L, a, b, LUA_OPLT);  /* a < b */
+
  else {  /* function */
+
    int res;
+
    lua_pushvalue(L, 2);    /* push function */
+
    lua_pushvalue(L, a-1);  /* -1 to compensate function */
+
    lua_pushvalue(L, b-2);  /* -2 to compensate function and 'a' */
+
    lua_call(L, 2, 1);      /* call function */
+
    res = lua_toboolean(L, -1);  /* get result */
+
    lua_pop(L, 1);          /* pop result */
+
    return res;
+
  }
+
}
+

+

+
/*
+
** Does the partition: Pivot P is at the top of the stack.
+
** precondition: a[lo] <= P == a[up-1] <= a[up],
+
** so it only needs to do the partition from lo + 1 to up - 2.
+
** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up]
+
** returns 'i'.
+
*/
+
static IdxT partition (lua_State *L, IdxT lo, IdxT up) {
+
  IdxT i = lo;  /* will be incremented before first use */
+
  IdxT j = up - 1;  /* will be decremented before first use */
+
  /* loop invariant: a[lo .. i] <= P <= a[j .. up] */
+
  for (;;) {
+
    /* next loop: repeat ++i while a[i] < P */
+
    while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) {
+
      if (i == up - 1)  /* a[i] < P  but a[up - 1] == P  ?? */
+
        luaL_error(L, "invalid order function for sorting");
+
      lua_pop(L, 1);  /* remove a[i] */
+
    }
+
    /* after the loop, a[i] >= P and a[lo .. i - 1] < P */
+
    /* next loop: repeat --j while P < a[j] */
+
    while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) {
+
      if (j < i)  /* j < i  but  a[j] > P ?? */
+
        luaL_error(L, "invalid order function for sorting");
+
      lua_pop(L, 1);  /* remove a[j] */
+
    }
+
    /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */
+
    if (j < i) {  /* no elements out of place? */
+
      /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */
+
      lua_pop(L, 1);  /* pop a[j] */
+
      /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */
+
      set2(L, up - 1, i);
+
      return i;
+
    }
+
    /* otherwise, swap a[i] - a[j] to restore invariant and repeat */
+
    set2(L, i, j);
+
  }
+
}
+

+

+
/*
+
** Choose an element in the middle (2nd-3th quarters) of [lo,up]
+
** "randomized" by 'rnd'
+
*/
+
static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) {
+
  IdxT r4 = (up - lo) / 4;  /* range/4 */
+
  IdxT p = rnd % (r4 * 2) + (lo + r4);
+
  lua_assert(lo + r4 <= p && p <= up - r4);
+
  return p;
+
}
+

+

+
/*
+
** QuickSort algorithm (recursive function)
+
*/
+
static void auxsort (lua_State *L, IdxT lo, IdxT up,
+
                                   unsigned int rnd) {
+
  while (lo < up) {  /* loop for tail recursion */
+
    IdxT p;  /* Pivot index */
+
    IdxT n;  /* to be used later */
+
    /* sort elements 'lo', 'p', and 'up' */
+
    lua_geti(L, 1, lo);
+
    lua_geti(L, 1, up);
+
    if (sort_comp(L, -1, -2))  /* a[up] < a[lo]? */
+
      set2(L, lo, up);  /* swap a[lo] - a[up] */
+
    else
+
      lua_pop(L, 2);  /* remove both values */
+
    if (up - lo == 1)  /* only 2 elements? */
+
      return;  /* already sorted */
+
    if (up - lo < RANLIMIT || rnd == 0)  /* small interval or no randomize? */
+
      p = (lo + up)/2;  /* middle element is a good pivot */
+
    else  /* for larger intervals, it is worth a random pivot */
+
      p = choosePivot(lo, up, rnd);
+
    lua_geti(L, 1, p);
+
    lua_geti(L, 1, lo);
+
    if (sort_comp(L, -2, -1))  /* a[p] < a[lo]? */
+
      set2(L, p, lo);  /* swap a[p] - a[lo] */
+
    else {
+
      lua_pop(L, 1);  /* remove a[lo] */
+
      lua_geti(L, 1, up);
+
      if (sort_comp(L, -1, -2))  /* a[up] < a[p]? */
+
        set2(L, p, up);  /* swap a[up] - a[p] */
+
      else
+
        lua_pop(L, 2);
+
    }
+
    if (up - lo == 2)  /* only 3 elements? */
+
      return;  /* already sorted */
+
    lua_geti(L, 1, p);  /* get middle element (Pivot) */
+
    lua_pushvalue(L, -1);  /* push Pivot */
+
    lua_geti(L, 1, up - 1);  /* push a[up - 1] */
+
    set2(L, p, up - 1);  /* swap Pivot (a[p]) with a[up - 1] */
+
    p = partition(L, lo, up);
+
    /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */
+
    if (p - lo < up - p) {  /* lower interval is smaller? */
+
      auxsort(L, lo, p - 1, rnd);  /* call recursively for lower interval */
+
      n = p - lo;  /* size of smaller interval */
+
      lo = p + 1;  /* tail call for [p + 1 .. up] (upper interval) */
+
    }
+
    else {
+
      auxsort(L, p + 1, up, rnd);  /* call recursively for upper interval */
+
      n = up - p;  /* size of smaller interval */
+
      up = p - 1;  /* tail call for [lo .. p - 1]  (lower interval) */
+
    }
+
    if ((up - lo) / 128 > n) /* partition too imbalanced? */
+
      rnd = l_randomizePivot();  /* try a new randomization */
+
  }  /* tail call auxsort(L, lo, up, rnd) */
+
}
+

+

+
static int sort (lua_State *L) {
+
  lua_Integer n = aux_getn(L, 1, TAB_RW);
+
  if (n > 1) {  /* non-trivial interval? */
+
    luaL_argcheck(L, n < INT_MAX, 1, "array too big");
+
    if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */
+
      luaL_checktype(L, 2, LUA_TFUNCTION);  /* must be a function */
+
    lua_settop(L, 2);  /* make sure there are two arguments */
+
    auxsort(L, 1, (IdxT)n, 0);
+
  }
+
  return 0;
+
}
+

+
/* }====================================================== */
+

+

+
static const luaL_Reg tab_funcs[] = {
+
  {"concat", tconcat},
+
#if defined(LUA_COMPAT_MAXN)
+
  {"maxn", maxn},
+
#endif
+
  {"insert", tinsert},
+
  {"pack", pack},
+
  {"unpack", unpack},
+
  {"remove", tremove},
+
  {"move", tmove},
+
  {"sort", sort},
+
  {NULL, NULL}
+
};
+

+

+
LUAMOD_API int luaopen_table (lua_State *L) {
+
  luaL_newlib(L, tab_funcs);
+
#if defined(LUA_COMPAT_UNPACK)
+
  /* _G.unpack = table.unpack */
+
  lua_getfield(L, -1, "unpack");
+
  lua_setglobal(L, "unpack");
+
#endif
+
  return 1;
+
}
+

added external/lua/src/ltm.c
@@ -0,0 +1,165 @@
+
/*
+
** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $
+
** Tag methods
+
** See Copyright Notice in lua.h
+
*/
+

+
#define ltm_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lobject.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "ltm.h"
+
#include "lvm.h"
+

+

+
static const char udatatypename[] = "userdata";
+

+
LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
+
  "no value",
+
  "nil", "boolean", udatatypename, "number",
+
  "string", "table", "function", udatatypename, "thread",
+
  "proto" /* this last case is used for tests only */
+
};
+

+

+
void luaT_init (lua_State *L) {
+
  static const char *const luaT_eventname[] = {  /* ORDER TM */
+
    "__index", "__newindex",
+
    "__gc", "__mode", "__len", "__eq",
+
    "__add", "__sub", "__mul", "__mod", "__pow",
+
    "__div", "__idiv",
+
    "__band", "__bor", "__bxor", "__shl", "__shr",
+
    "__unm", "__bnot", "__lt", "__le",
+
    "__concat", "__call"
+
  };
+
  int i;
+
  for (i=0; i<TM_N; i++) {
+
    G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
+
    luaC_fix(L, obj2gco(G(L)->tmname[i]));  /* never collect these names */
+
  }
+
}
+

+

+
/*
+
** function to be used with macro "fasttm": optimized for absence of
+
** tag methods
+
*/
+
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
+
  const TValue *tm = luaH_getshortstr(events, ename);
+
  lua_assert(event <= TM_EQ);
+
  if (ttisnil(tm)) {  /* no tag method? */
+
    events->flags |= cast_byte(1u<<event);  /* cache this fact */
+
    return NULL;
+
  }
+
  else return tm;
+
}
+

+

+
const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
+
  Table *mt;
+
  switch (ttnov(o)) {
+
    case LUA_TTABLE:
+
      mt = hvalue(o)->metatable;
+
      break;
+
    case LUA_TUSERDATA:
+
      mt = uvalue(o)->metatable;
+
      break;
+
    default:
+
      mt = G(L)->mt[ttnov(o)];
+
  }
+
  return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject);
+
}
+

+

+
/*
+
** Return the name of the type of an object. For tables and userdata
+
** with metatable, use their '__name' metafield, if present.
+
*/
+
const char *luaT_objtypename (lua_State *L, const TValue *o) {
+
  Table *mt;
+
  if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
+
      (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
+
    const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
+
    if (ttisstring(name))  /* is '__name' a string? */
+
      return getstr(tsvalue(name));  /* use it as type name */
+
  }
+
  return ttypename(ttnov(o));  /* else use standard type name */
+
}
+

+

+
void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
+
                  const TValue *p2, TValue *p3, int hasres) {
+
  ptrdiff_t result = savestack(L, p3);
+
  StkId func = L->top;
+
  setobj2s(L, func, f);  /* push function (assume EXTRA_STACK) */
+
  setobj2s(L, func + 1, p1);  /* 1st argument */
+
  setobj2s(L, func + 2, p2);  /* 2nd argument */
+
  L->top += 3;
+
  if (!hasres)  /* no result? 'p3' is third argument */
+
    setobj2s(L, L->top++, p3);  /* 3rd argument */
+
  /* metamethod may yield only when called from Lua code */
+
  if (isLua(L->ci))
+
    luaD_call(L, func, hasres);
+
  else
+
    luaD_callnoyield(L, func, hasres);
+
  if (hasres) {  /* if has result, move it to its place */
+
    p3 = restorestack(L, result);
+
    setobjs2s(L, p3, --L->top);
+
  }
+
}
+

+

+
int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
+
                    StkId res, TMS event) {
+
  const TValue *tm = luaT_gettmbyobj(L, p1, event);  /* try first operand */
+
  if (ttisnil(tm))
+
    tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
+
  if (ttisnil(tm)) return 0;
+
  luaT_callTM(L, tm, p1, p2, res, 1);
+
  return 1;
+
}
+

+

+
void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
+
                    StkId res, TMS event) {
+
  if (!luaT_callbinTM(L, p1, p2, res, event)) {
+
    switch (event) {
+
      case TM_CONCAT:
+
        luaG_concaterror(L, p1, p2);
+
      /* call never returns, but to avoid warnings: *//* FALLTHROUGH */
+
      case TM_BAND: case TM_BOR: case TM_BXOR:
+
      case TM_SHL: case TM_SHR: case TM_BNOT: {
+
        lua_Number dummy;
+
        if (tonumber(p1, &dummy) && tonumber(p2, &dummy))
+
          luaG_tointerror(L, p1, p2);
+
        else
+
          luaG_opinterror(L, p1, p2, "perform bitwise operation on");
+
      }
+
      /* calls never return, but to avoid warnings: *//* FALLTHROUGH */
+
      default:
+
        luaG_opinterror(L, p1, p2, "perform arithmetic on");
+
    }
+
  }
+
}
+

+

+
int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
+
                      TMS event) {
+
  if (!luaT_callbinTM(L, p1, p2, L->top, event))
+
    return -1;  /* no metamethod */
+
  else
+
    return !l_isfalse(L->top);
+
}
+

added external/lua/src/ltm.h
@@ -0,0 +1,76 @@
+
/*
+
** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Tag methods
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef ltm_h
+
#define ltm_h
+

+

+
#include "lobject.h"
+

+

+
/*
+
* WARNING: if you change the order of this enumeration,
+
* grep "ORDER TM" and "ORDER OP"
+
*/
+
typedef enum {
+
  TM_INDEX,
+
  TM_NEWINDEX,
+
  TM_GC,
+
  TM_MODE,
+
  TM_LEN,
+
  TM_EQ,  /* last tag method with fast access */
+
  TM_ADD,
+
  TM_SUB,
+
  TM_MUL,
+
  TM_MOD,
+
  TM_POW,
+
  TM_DIV,
+
  TM_IDIV,
+
  TM_BAND,
+
  TM_BOR,
+
  TM_BXOR,
+
  TM_SHL,
+
  TM_SHR,
+
  TM_UNM,
+
  TM_BNOT,
+
  TM_LT,
+
  TM_LE,
+
  TM_CONCAT,
+
  TM_CALL,
+
  TM_N		/* number of elements in the enum */
+
} TMS;
+

+

+

+
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
+
  ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
+

+
#define fasttm(l,et,e)	gfasttm(G(l), et, e)
+

+
#define ttypename(x)	luaT_typenames_[(x) + 1]
+

+
LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
+

+

+
LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o);
+

+
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
+
LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
+
                                                       TMS event);
+
LUAI_FUNC void luaT_init (lua_State *L);
+

+
LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
+
                            const TValue *p2, TValue *p3, int hasres);
+
LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
+
                              StkId res, TMS event);
+
LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
+
                              StkId res, TMS event);
+
LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
+
                                const TValue *p2, TMS event);
+

+

+

+
#endif
added external/lua/src/lua.c
@@ -0,0 +1,612 @@
+
/*
+
** $Id: lua.c,v 1.230.1.1 2017/04/19 17:29:57 roberto Exp $
+
** Lua stand-alone interpreter
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lua_c
+

+
#include "lprefix.h"
+

+

+
#include <signal.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+

+

+
#if !defined(LUA_PROMPT)
+
#define LUA_PROMPT		"> "
+
#define LUA_PROMPT2		">> "
+
#endif
+

+
#if !defined(LUA_PROGNAME)
+
#define LUA_PROGNAME		"lua"
+
#endif
+

+
#if !defined(LUA_MAXINPUT)
+
#define LUA_MAXINPUT		512
+
#endif
+

+
#if !defined(LUA_INIT_VAR)
+
#define LUA_INIT_VAR		"LUA_INIT"
+
#endif
+

+
#define LUA_INITVARVERSION	LUA_INIT_VAR LUA_VERSUFFIX
+

+

+
/*
+
** lua_stdin_is_tty detects whether the standard input is a 'tty' (that
+
** is, whether we're running lua interactively).
+
*/
+
#if !defined(lua_stdin_is_tty)	/* { */
+

+
#if defined(LUA_USE_POSIX)	/* { */
+

+
#include <unistd.h>
+
#define lua_stdin_is_tty()	isatty(0)
+

+
#elif defined(LUA_USE_WINDOWS)	/* }{ */
+

+
#include <io.h>
+
#include <windows.h>
+

+
#define lua_stdin_is_tty()	_isatty(_fileno(stdin))
+

+
#else				/* }{ */
+

+
/* ISO C definition */
+
#define lua_stdin_is_tty()	1  /* assume stdin is a tty */
+

+
#endif				/* } */
+

+
#endif				/* } */
+

+

+
/*
+
** lua_readline defines how to show a prompt and then read a line from
+
** the standard input.
+
** lua_saveline defines how to "save" a read line in a "history".
+
** lua_freeline defines how to free a line read by lua_readline.
+
*/
+
#if !defined(lua_readline)	/* { */
+

+
#if defined(LUA_USE_READLINE)	/* { */
+

+
#include <readline/readline.h>
+
#include <readline/history.h>
+
#define lua_readline(L,b,p)	((void)L, ((b)=readline(p)) != NULL)
+
#define lua_saveline(L,line)	((void)L, add_history(line))
+
#define lua_freeline(L,b)	((void)L, free(b))
+

+
#else				/* }{ */
+

+
#define lua_readline(L,b,p) \
+
        ((void)L, fputs(p, stdout), fflush(stdout),  /* show prompt */ \
+
        fgets(b, LUA_MAXINPUT, stdin) != NULL)  /* get line */
+
#define lua_saveline(L,line)	{ (void)L; (void)line; }
+
#define lua_freeline(L,b)	{ (void)L; (void)b; }
+

+
#endif				/* } */
+

+
#endif				/* } */
+

+

+

+

+
static lua_State *globalL = NULL;
+

+
static const char *progname = LUA_PROGNAME;
+

+

+
/*
+
** Hook set by signal function to stop the interpreter.
+
*/
+
static void lstop (lua_State *L, lua_Debug *ar) {
+
  (void)ar;  /* unused arg. */
+
  lua_sethook(L, NULL, 0, 0);  /* reset hook */
+
  luaL_error(L, "interrupted!");
+
}
+

+

+
/*
+
** Function to be called at a C signal. Because a C signal cannot
+
** just change a Lua state (as there is no proper synchronization),
+
** this function only sets a hook that, when called, will stop the
+
** interpreter.
+
*/
+
static void laction (int i) {
+
  signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */
+
  lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
+
}
+

+

+
static void print_usage (const char *badoption) {
+
  lua_writestringerror("%s: ", progname);
+
  if (badoption[1] == 'e' || badoption[1] == 'l')
+
    lua_writestringerror("'%s' needs argument\n", badoption);
+
  else
+
    lua_writestringerror("unrecognized option '%s'\n", badoption);
+
  lua_writestringerror(
+
  "usage: %s [options] [script [args]]\n"
+
  "Available options are:\n"
+
  "  -e stat  execute string 'stat'\n"
+
  "  -i       enter interactive mode after executing 'script'\n"
+
  "  -l name  require library 'name' into global 'name'\n"
+
  "  -v       show version information\n"
+
  "  -E       ignore environment variables\n"
+
  "  --       stop handling options\n"
+
  "  -        stop handling options and execute stdin\n"
+
  ,
+
  progname);
+
}
+

+

+
/*
+
** Prints an error message, adding the program name in front of it
+
** (if present)
+
*/
+
static void l_message (const char *pname, const char *msg) {
+
  if (pname) lua_writestringerror("%s: ", pname);
+
  lua_writestringerror("%s\n", msg);
+
}
+

+

+
/*
+
** Check whether 'status' is not OK and, if so, prints the error
+
** message on the top of the stack. It assumes that the error object
+
** is a string, as it was either generated by Lua or by 'msghandler'.
+
*/
+
static int report (lua_State *L, int status) {
+
  if (status != LUA_OK) {
+
    const char *msg = lua_tostring(L, -1);
+
    l_message(progname, msg);
+
    lua_pop(L, 1);  /* remove message */
+
  }
+
  return status;
+
}
+

+

+
/*
+
** Message handler used to run all chunks
+
*/
+
static int msghandler (lua_State *L) {
+
  const char *msg = lua_tostring(L, 1);
+
  if (msg == NULL) {  /* is error object not a string? */
+
    if (luaL_callmeta(L, 1, "__tostring") &&  /* does it have a metamethod */
+
        lua_type(L, -1) == LUA_TSTRING)  /* that produces a string? */
+
      return 1;  /* that is the message */
+
    else
+
      msg = lua_pushfstring(L, "(error object is a %s value)",
+
                               luaL_typename(L, 1));
+
  }
+
  luaL_traceback(L, L, msg, 1);  /* append a standard traceback */
+
  return 1;  /* return the traceback */
+
}
+

+

+
/*
+
** Interface to 'lua_pcall', which sets appropriate message function
+
** and C-signal handler. Used to run all chunks.
+
*/
+
static int docall (lua_State *L, int narg, int nres) {
+
  int status;
+
  int base = lua_gettop(L) - narg;  /* function index */
+
  lua_pushcfunction(L, msghandler);  /* push message handler */
+
  lua_insert(L, base);  /* put it under function and args */
+
  globalL = L;  /* to be available to 'laction' */
+
  signal(SIGINT, laction);  /* set C-signal handler */
+
  status = lua_pcall(L, narg, nres, base);
+
  signal(SIGINT, SIG_DFL); /* reset C-signal handler */
+
  lua_remove(L, base);  /* remove message handler from the stack */
+
  return status;
+
}
+

+

+
static void print_version (void) {
+
  lua_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT));
+
  lua_writeline();
+
}
+

+

+
/*
+
** Create the 'arg' table, which stores all arguments from the
+
** command line ('argv'). It should be aligned so that, at index 0,
+
** it has 'argv[script]', which is the script name. The arguments
+
** to the script (everything after 'script') go to positive indices;
+
** other arguments (before the script name) go to negative indices.
+
** If there is no script name, assume interpreter's name as base.
+
*/
+
static void createargtable (lua_State *L, char **argv, int argc, int script) {
+
  int i, narg;
+
  if (script == argc) script = 0;  /* no script name? */
+
  narg = argc - (script + 1);  /* number of positive indices */
+
  lua_createtable(L, narg, script + 1);
+
  for (i = 0; i < argc; i++) {
+
    lua_pushstring(L, argv[i]);
+
    lua_rawseti(L, -2, i - script);
+
  }
+
  lua_setglobal(L, "arg");
+
}
+

+

+
static int dochunk (lua_State *L, int status) {
+
  if (status == LUA_OK) status = docall(L, 0, 0);
+
  return report(L, status);
+
}
+

+

+
static int dofile (lua_State *L, const char *name) {
+
  return dochunk(L, luaL_loadfile(L, name));
+
}
+

+

+
static int dostring (lua_State *L, const char *s, const char *name) {
+
  return dochunk(L, luaL_loadbuffer(L, s, strlen(s), name));
+
}
+

+

+
/*
+
** Calls 'require(name)' and stores the result in a global variable
+
** with the given name.
+
*/
+
static int dolibrary (lua_State *L, const char *name) {
+
  int status;
+
  lua_getglobal(L, "require");
+
  lua_pushstring(L, name);
+
  status = docall(L, 1, 1);  /* call 'require(name)' */
+
  if (status == LUA_OK)
+
    lua_setglobal(L, name);  /* global[name] = require return */
+
  return report(L, status);
+
}
+

+

+
/*
+
** Returns the string to be used as a prompt by the interpreter.
+
*/
+
static const char *get_prompt (lua_State *L, int firstline) {
+
  const char *p;
+
  lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
+
  p = lua_tostring(L, -1);
+
  if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
+
  return p;
+
}
+

+
/* mark in error messages for incomplete statements */
+
#define EOFMARK		"<eof>"
+
#define marklen		(sizeof(EOFMARK)/sizeof(char) - 1)
+

+

+
/*
+
** Check whether 'status' signals a syntax error and the error
+
** message at the top of the stack ends with the above mark for
+
** incomplete statements.
+
*/
+
static int incomplete (lua_State *L, int status) {
+
  if (status == LUA_ERRSYNTAX) {
+
    size_t lmsg;
+
    const char *msg = lua_tolstring(L, -1, &lmsg);
+
    if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) {
+
      lua_pop(L, 1);
+
      return 1;
+
    }
+
  }
+
  return 0;  /* else... */
+
}
+

+

+
/*
+
** Prompt the user, read a line, and push it into the Lua stack.
+
*/
+
static int pushline (lua_State *L, int firstline) {
+
  char buffer[LUA_MAXINPUT];
+
  char *b = buffer;
+
  size_t l;
+
  const char *prmt = get_prompt(L, firstline);
+
  int readstatus = lua_readline(L, b, prmt);
+
  if (readstatus == 0)
+
    return 0;  /* no input (prompt will be popped by caller) */
+
  lua_pop(L, 1);  /* remove prompt */
+
  l = strlen(b);
+
  if (l > 0 && b[l-1] == '\n')  /* line ends with newline? */
+
    b[--l] = '\0';  /* remove it */
+
  if (firstline && b[0] == '=')  /* for compatibility with 5.2, ... */
+
    lua_pushfstring(L, "return %s", b + 1);  /* change '=' to 'return' */
+
  else
+
    lua_pushlstring(L, b, l);
+
  lua_freeline(L, b);
+
  return 1;
+
}
+

+

+
/*
+
** Try to compile line on the stack as 'return <line>;'; on return, stack
+
** has either compiled chunk or original line (if compilation failed).
+
*/
+
static int addreturn (lua_State *L) {
+
  const char *line = lua_tostring(L, -1);  /* original line */
+
  const char *retline = lua_pushfstring(L, "return %s;", line);
+
  int status = luaL_loadbuffer(L, retline, strlen(retline), "=stdin");
+
  if (status == LUA_OK) {
+
    lua_remove(L, -2);  /* remove modified line */
+
    if (line[0] != '\0')  /* non empty? */
+
      lua_saveline(L, line);  /* keep history */
+
  }
+
  else
+
    lua_pop(L, 2);  /* pop result from 'luaL_loadbuffer' and modified line */
+
  return status;
+
}
+

+

+
/*
+
** Read multiple lines until a complete Lua statement
+
*/
+
static int multiline (lua_State *L) {
+
  for (;;) {  /* repeat until gets a complete statement */
+
    size_t len;
+
    const char *line = lua_tolstring(L, 1, &len);  /* get what it has */
+
    int status = luaL_loadbuffer(L, line, len, "=stdin");  /* try it */
+
    if (!incomplete(L, status) || !pushline(L, 0)) {
+
      lua_saveline(L, line);  /* keep history */
+
      return status;  /* cannot or should not try to add continuation line */
+
    }
+
    lua_pushliteral(L, "\n");  /* add newline... */
+
    lua_insert(L, -2);  /* ...between the two lines */
+
    lua_concat(L, 3);  /* join them */
+
  }
+
}
+

+

+
/*
+
** Read a line and try to load (compile) it first as an expression (by
+
** adding "return " in front of it) and second as a statement. Return
+
** the final status of load/call with the resulting function (if any)
+
** in the top of the stack.
+
*/
+
static int loadline (lua_State *L) {
+
  int status;
+
  lua_settop(L, 0);
+
  if (!pushline(L, 1))
+
    return -1;  /* no input */
+
  if ((status = addreturn(L)) != LUA_OK)  /* 'return ...' did not work? */
+
    status = multiline(L);  /* try as command, maybe with continuation lines */
+
  lua_remove(L, 1);  /* remove line from the stack */
+
  lua_assert(lua_gettop(L) == 1);
+
  return status;
+
}
+

+

+
/*
+
** Prints (calling the Lua 'print' function) any values on the stack
+
*/
+
static void l_print (lua_State *L) {
+
  int n = lua_gettop(L);
+
  if (n > 0) {  /* any result to be printed? */
+
    luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
+
    lua_getglobal(L, "print");
+
    lua_insert(L, 1);
+
    if (lua_pcall(L, n, 0, 0) != LUA_OK)
+
      l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)",
+
                                             lua_tostring(L, -1)));
+
  }
+
}
+

+

+
/*
+
** Do the REPL: repeatedly read (load) a line, evaluate (call) it, and
+
** print any results.
+
*/
+
static void doREPL (lua_State *L) {
+
  int status;
+
  const char *oldprogname = progname;
+
  progname = NULL;  /* no 'progname' on errors in interactive mode */
+
  while ((status = loadline(L)) != -1) {
+
    if (status == LUA_OK)
+
      status = docall(L, 0, LUA_MULTRET);
+
    if (status == LUA_OK) l_print(L);
+
    else report(L, status);
+
  }
+
  lua_settop(L, 0);  /* clear stack */
+
  lua_writeline();
+
  progname = oldprogname;
+
}
+

+

+
/*
+
** Push on the stack the contents of table 'arg' from 1 to #arg
+
*/
+
static int pushargs (lua_State *L) {
+
  int i, n;
+
  if (lua_getglobal(L, "arg") != LUA_TTABLE)
+
    luaL_error(L, "'arg' is not a table");
+
  n = (int)luaL_len(L, -1);
+
  luaL_checkstack(L, n + 3, "too many arguments to script");
+
  for (i = 1; i <= n; i++)
+
    lua_rawgeti(L, -i, i);
+
  lua_remove(L, -i);  /* remove table from the stack */
+
  return n;
+
}
+

+

+
static int handle_script (lua_State *L, char **argv) {
+
  int status;
+
  const char *fname = argv[0];
+
  if (strcmp(fname, "-") == 0 && strcmp(argv[-1], "--") != 0)
+
    fname = NULL;  /* stdin */
+
  status = luaL_loadfile(L, fname);
+
  if (status == LUA_OK) {
+
    int n = pushargs(L);  /* push arguments to script */
+
    status = docall(L, n, LUA_MULTRET);
+
  }
+
  return report(L, status);
+
}
+

+

+

+
/* bits of various argument indicators in 'args' */
+
#define has_error	1	/* bad option */
+
#define has_i		2	/* -i */
+
#define has_v		4	/* -v */
+
#define has_e		8	/* -e */
+
#define has_E		16	/* -E */
+

+
/*
+
** Traverses all arguments from 'argv', returning a mask with those
+
** needed before running any Lua code (or an error code if it finds
+
** any invalid argument). 'first' returns the first not-handled argument
+
** (either the script name or a bad argument in case of error).
+
*/
+
static int collectargs (char **argv, int *first) {
+
  int args = 0;
+
  int i;
+
  for (i = 1; argv[i] != NULL; i++) {
+
    *first = i;
+
    if (argv[i][0] != '-')  /* not an option? */
+
        return args;  /* stop handling options */
+
    switch (argv[i][1]) {  /* else check option */
+
      case '-':  /* '--' */
+
        if (argv[i][2] != '\0')  /* extra characters after '--'? */
+
          return has_error;  /* invalid option */
+
        *first = i + 1;
+
        return args;
+
      case '\0':  /* '-' */
+
        return args;  /* script "name" is '-' */
+
      case 'E':
+
        if (argv[i][2] != '\0')  /* extra characters after 1st? */
+
          return has_error;  /* invalid option */
+
        args |= has_E;
+
        break;
+
      case 'i':
+
        args |= has_i;  /* (-i implies -v) *//* FALLTHROUGH */
+
      case 'v':
+
        if (argv[i][2] != '\0')  /* extra characters after 1st? */
+
          return has_error;  /* invalid option */
+
        args |= has_v;
+
        break;
+
      case 'e':
+
        args |= has_e;  /* FALLTHROUGH */
+
      case 'l':  /* both options need an argument */
+
        if (argv[i][2] == '\0') {  /* no concatenated argument? */
+
          i++;  /* try next 'argv' */
+
          if (argv[i] == NULL || argv[i][0] == '-')
+
            return has_error;  /* no next argument or it is another option */
+
        }
+
        break;
+
      default:  /* invalid option */
+
        return has_error;
+
    }
+
  }
+
  *first = i;  /* no script name */
+
  return args;
+
}
+

+

+
/*
+
** Processes options 'e' and 'l', which involve running Lua code.
+
** Returns 0 if some code raises an error.
+
*/
+
static int runargs (lua_State *L, char **argv, int n) {
+
  int i;
+
  for (i = 1; i < n; i++) {
+
    int option = argv[i][1];
+
    lua_assert(argv[i][0] == '-');  /* already checked */
+
    if (option == 'e' || option == 'l') {
+
      int status;
+
      const char *extra = argv[i] + 2;  /* both options need an argument */
+
      if (*extra == '\0') extra = argv[++i];
+
      lua_assert(extra != NULL);
+
      status = (option == 'e')
+
               ? dostring(L, extra, "=(command line)")
+
               : dolibrary(L, extra);
+
      if (status != LUA_OK) return 0;
+
    }
+
  }
+
  return 1;
+
}
+

+

+

+
static int handle_luainit (lua_State *L) {
+
  const char *name = "=" LUA_INITVARVERSION;
+
  const char *init = getenv(name + 1);
+
  if (init == NULL) {
+
    name = "=" LUA_INIT_VAR;
+
    init = getenv(name + 1);  /* try alternative name */
+
  }
+
  if (init == NULL) return LUA_OK;
+
  else if (init[0] == '@')
+
    return dofile(L, init+1);
+
  else
+
    return dostring(L, init, name);
+
}
+

+

+
/*
+
** Main body of stand-alone interpreter (to be called in protected mode).
+
** Reads the options and handles them all.
+
*/
+
static int pmain (lua_State *L) {
+
  int argc = (int)lua_tointeger(L, 1);
+
  char **argv = (char **)lua_touserdata(L, 2);
+
  int script;
+
  int args = collectargs(argv, &script);
+
  luaL_checkversion(L);  /* check that interpreter has correct version */
+
  if (argv[0] && argv[0][0]) progname = argv[0];
+
  if (args == has_error) {  /* bad arg? */
+
    print_usage(argv[script]);  /* 'script' has index of bad arg. */
+
    return 0;
+
  }
+
  if (args & has_v)  /* option '-v'? */
+
    print_version();
+
  if (args & has_E) {  /* option '-E'? */
+
    lua_pushboolean(L, 1);  /* signal for libraries to ignore env. vars. */
+
    lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
+
  }
+
  luaL_openlibs(L);  /* open standard libraries */
+
  createargtable(L, argv, argc, script);  /* create table 'arg' */
+
  if (!(args & has_E)) {  /* no option '-E'? */
+
    if (handle_luainit(L) != LUA_OK)  /* run LUA_INIT */
+
      return 0;  /* error running LUA_INIT */
+
  }
+
  if (!runargs(L, argv, script))  /* execute arguments -e and -l */
+
    return 0;  /* something failed */
+
  if (script < argc &&  /* execute main script (if there is one) */
+
      handle_script(L, argv + script) != LUA_OK)
+
    return 0;
+
  if (args & has_i)  /* -i option? */
+
    doREPL(L);  /* do read-eval-print loop */
+
  else if (script == argc && !(args & (has_e | has_v))) {  /* no arguments? */
+
    if (lua_stdin_is_tty()) {  /* running in interactive mode? */
+
      print_version();
+
      doREPL(L);  /* do read-eval-print loop */
+
    }
+
    else dofile(L, NULL);  /* executes stdin as a file */
+
  }
+
  lua_pushboolean(L, 1);  /* signal no errors */
+
  return 1;
+
}
+

+

+
int main (int argc, char **argv) {
+
  int status, result;
+
  lua_State *L = luaL_newstate();  /* create state */
+
  if (L == NULL) {
+
    l_message(argv[0], "cannot create state: not enough memory");
+
    return EXIT_FAILURE;
+
  }
+
  lua_pushcfunction(L, &pmain);  /* to call 'pmain' in protected mode */
+
  lua_pushinteger(L, argc);  /* 1st argument */
+
  lua_pushlightuserdata(L, argv); /* 2nd argument */
+
  status = lua_pcall(L, 2, 1, 0);  /* do the call */
+
  result = lua_toboolean(L, -1);  /* get result */
+
  report(L, status);
+
  lua_close(L);
+
  return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
+
}
+

added external/lua/src/lua.h
@@ -0,0 +1,486 @@
+
/*
+
** $Id: lua.h,v 1.332.1.2 2018/06/13 16:58:17 roberto Exp $
+
** Lua - A Scripting Language
+
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
+
** See Copyright Notice at the end of this file
+
*/
+

+

+
#ifndef lua_h
+
#define lua_h
+

+
#include <stdarg.h>
+
#include <stddef.h>
+

+

+
#include "luaconf.h"
+

+

+
#define LUA_VERSION_MAJOR	"5"
+
#define LUA_VERSION_MINOR	"3"
+
#define LUA_VERSION_NUM		503
+
#define LUA_VERSION_RELEASE	"5"
+

+
#define LUA_VERSION	"Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+
#define LUA_RELEASE	LUA_VERSION "." LUA_VERSION_RELEASE
+
#define LUA_COPYRIGHT	LUA_RELEASE "  Copyright (C) 1994-2018 Lua.org, PUC-Rio"
+
#define LUA_AUTHORS	"R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
+

+

+
/* mark for precompiled code ('<esc>Lua') */
+
#define LUA_SIGNATURE	"\x1bLua"
+

+
/* option for multiple returns in 'lua_pcall' and 'lua_call' */
+
#define LUA_MULTRET	(-1)
+

+

+
/*
+
** Pseudo-indices
+
** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
+
** space after that to help overflow detection)
+
*/
+
#define LUA_REGISTRYINDEX	(-LUAI_MAXSTACK - 1000)
+
#define lua_upvalueindex(i)	(LUA_REGISTRYINDEX - (i))
+

+

+
/* thread status */
+
#define LUA_OK		0
+
#define LUA_YIELD	1
+
#define LUA_ERRRUN	2
+
#define LUA_ERRSYNTAX	3
+
#define LUA_ERRMEM	4
+
#define LUA_ERRGCMM	5
+
#define LUA_ERRERR	6
+

+

+
typedef struct lua_State lua_State;
+

+

+
/*
+
** basic types
+
*/
+
#define LUA_TNONE		(-1)
+

+
#define LUA_TNIL		0
+
#define LUA_TBOOLEAN		1
+
#define LUA_TLIGHTUSERDATA	2
+
#define LUA_TNUMBER		3
+
#define LUA_TSTRING		4
+
#define LUA_TTABLE		5
+
#define LUA_TFUNCTION		6
+
#define LUA_TUSERDATA		7
+
#define LUA_TTHREAD		8
+

+
#define LUA_NUMTAGS		9
+

+

+

+
/* minimum Lua stack available to a C function */
+
#define LUA_MINSTACK	20
+

+

+
/* predefined values in the registry */
+
#define LUA_RIDX_MAINTHREAD	1
+
#define LUA_RIDX_GLOBALS	2
+
#define LUA_RIDX_LAST		LUA_RIDX_GLOBALS
+

+

+
/* type of numbers in Lua */
+
typedef LUA_NUMBER lua_Number;
+

+

+
/* type for integer functions */
+
typedef LUA_INTEGER lua_Integer;
+

+
/* unsigned integer type */
+
typedef LUA_UNSIGNED lua_Unsigned;
+

+
/* type for continuation-function contexts */
+
typedef LUA_KCONTEXT lua_KContext;
+

+

+
/*
+
** Type for C functions registered with Lua
+
*/
+
typedef int (*lua_CFunction) (lua_State *L);
+

+
/*
+
** Type for continuation functions
+
*/
+
typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
+

+

+
/*
+
** Type for functions that read/write blocks when loading/dumping Lua chunks
+
*/
+
typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
+

+
typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
+

+

+
/*
+
** Type for memory-allocation functions
+
*/
+
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
+

+

+

+
/*
+
** generic extra include file
+
*/
+
#if defined(LUA_USER_H)
+
#include LUA_USER_H
+
#endif
+

+

+
/*
+
** RCS ident string
+
*/
+
extern const char lua_ident[];
+

+

+
/*
+
** state manipulation
+
*/
+
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
+
LUA_API void       (lua_close) (lua_State *L);
+
LUA_API lua_State *(lua_newthread) (lua_State *L);
+

+
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
+

+

+
LUA_API const lua_Number *(lua_version) (lua_State *L);
+

+

+
/*
+
** basic stack manipulation
+
*/
+
LUA_API int   (lua_absindex) (lua_State *L, int idx);
+
LUA_API int   (lua_gettop) (lua_State *L);
+
LUA_API void  (lua_settop) (lua_State *L, int idx);
+
LUA_API void  (lua_pushvalue) (lua_State *L, int idx);
+
LUA_API void  (lua_rotate) (lua_State *L, int idx, int n);
+
LUA_API void  (lua_copy) (lua_State *L, int fromidx, int toidx);
+
LUA_API int   (lua_checkstack) (lua_State *L, int n);
+

+
LUA_API void  (lua_xmove) (lua_State *from, lua_State *to, int n);
+

+

+
/*
+
** access functions (stack -> C)
+
*/
+

+
LUA_API int             (lua_isnumber) (lua_State *L, int idx);
+
LUA_API int             (lua_isstring) (lua_State *L, int idx);
+
LUA_API int             (lua_iscfunction) (lua_State *L, int idx);
+
LUA_API int             (lua_isinteger) (lua_State *L, int idx);
+
LUA_API int             (lua_isuserdata) (lua_State *L, int idx);
+
LUA_API int             (lua_type) (lua_State *L, int idx);
+
LUA_API const char     *(lua_typename) (lua_State *L, int tp);
+

+
LUA_API lua_Number      (lua_tonumberx) (lua_State *L, int idx, int *isnum);
+
LUA_API lua_Integer     (lua_tointegerx) (lua_State *L, int idx, int *isnum);
+
LUA_API int             (lua_toboolean) (lua_State *L, int idx);
+
LUA_API const char     *(lua_tolstring) (lua_State *L, int idx, size_t *len);
+
LUA_API size_t          (lua_rawlen) (lua_State *L, int idx);
+
LUA_API lua_CFunction   (lua_tocfunction) (lua_State *L, int idx);
+
LUA_API void	       *(lua_touserdata) (lua_State *L, int idx);
+
LUA_API lua_State      *(lua_tothread) (lua_State *L, int idx);
+
LUA_API const void     *(lua_topointer) (lua_State *L, int idx);
+

+

+
/*
+
** Comparison and arithmetic functions
+
*/
+

+
#define LUA_OPADD	0	/* ORDER TM, ORDER OP */
+
#define LUA_OPSUB	1
+
#define LUA_OPMUL	2
+
#define LUA_OPMOD	3
+
#define LUA_OPPOW	4
+
#define LUA_OPDIV	5
+
#define LUA_OPIDIV	6
+
#define LUA_OPBAND	7
+
#define LUA_OPBOR	8
+
#define LUA_OPBXOR	9
+
#define LUA_OPSHL	10
+
#define LUA_OPSHR	11
+
#define LUA_OPUNM	12
+
#define LUA_OPBNOT	13
+

+
LUA_API void  (lua_arith) (lua_State *L, int op);
+

+
#define LUA_OPEQ	0
+
#define LUA_OPLT	1
+
#define LUA_OPLE	2
+

+
LUA_API int   (lua_rawequal) (lua_State *L, int idx1, int idx2);
+
LUA_API int   (lua_compare) (lua_State *L, int idx1, int idx2, int op);
+

+

+
/*
+
** push functions (C -> stack)
+
*/
+
LUA_API void        (lua_pushnil) (lua_State *L);
+
LUA_API void        (lua_pushnumber) (lua_State *L, lua_Number n);
+
LUA_API void        (lua_pushinteger) (lua_State *L, lua_Integer n);
+
LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len);
+
LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
+
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
+
                                                      va_list argp);
+
LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
+
LUA_API void  (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
+
LUA_API void  (lua_pushboolean) (lua_State *L, int b);
+
LUA_API void  (lua_pushlightuserdata) (lua_State *L, void *p);
+
LUA_API int   (lua_pushthread) (lua_State *L);
+

+

+
/*
+
** get functions (Lua -> stack)
+
*/
+
LUA_API int (lua_getglobal) (lua_State *L, const char *name);
+
LUA_API int (lua_gettable) (lua_State *L, int idx);
+
LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
+
LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n);
+
LUA_API int (lua_rawget) (lua_State *L, int idx);
+
LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
+
LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p);
+

+
LUA_API void  (lua_createtable) (lua_State *L, int narr, int nrec);
+
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
+
LUA_API int   (lua_getmetatable) (lua_State *L, int objindex);
+
LUA_API int  (lua_getuservalue) (lua_State *L, int idx);
+

+

+
/*
+
** set functions (stack -> Lua)
+
*/
+
LUA_API void  (lua_setglobal) (lua_State *L, const char *name);
+
LUA_API void  (lua_settable) (lua_State *L, int idx);
+
LUA_API void  (lua_setfield) (lua_State *L, int idx, const char *k);
+
LUA_API void  (lua_seti) (lua_State *L, int idx, lua_Integer n);
+
LUA_API void  (lua_rawset) (lua_State *L, int idx);
+
LUA_API void  (lua_rawseti) (lua_State *L, int idx, lua_Integer n);
+
LUA_API void  (lua_rawsetp) (lua_State *L, int idx, const void *p);
+
LUA_API int   (lua_setmetatable) (lua_State *L, int objindex);
+
LUA_API void  (lua_setuservalue) (lua_State *L, int idx);
+

+

+
/*
+
** 'load' and 'call' functions (load and run Lua code)
+
*/
+
LUA_API void  (lua_callk) (lua_State *L, int nargs, int nresults,
+
                           lua_KContext ctx, lua_KFunction k);
+
#define lua_call(L,n,r)		lua_callk(L, (n), (r), 0, NULL)
+

+
LUA_API int   (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
+
                            lua_KContext ctx, lua_KFunction k);
+
#define lua_pcall(L,n,r,f)	lua_pcallk(L, (n), (r), (f), 0, NULL)
+

+
LUA_API int   (lua_load) (lua_State *L, lua_Reader reader, void *dt,
+
                          const char *chunkname, const char *mode);
+

+
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
+

+

+
/*
+
** coroutine functions
+
*/
+
LUA_API int  (lua_yieldk)     (lua_State *L, int nresults, lua_KContext ctx,
+
                               lua_KFunction k);
+
LUA_API int  (lua_resume)     (lua_State *L, lua_State *from, int narg);
+
LUA_API int  (lua_status)     (lua_State *L);
+
LUA_API int (lua_isyieldable) (lua_State *L);
+

+
#define lua_yield(L,n)		lua_yieldk(L, (n), 0, NULL)
+

+

+
/*
+
** garbage-collection function and options
+
*/
+

+
#define LUA_GCSTOP		0
+
#define LUA_GCRESTART		1
+
#define LUA_GCCOLLECT		2
+
#define LUA_GCCOUNT		3
+
#define LUA_GCCOUNTB		4
+
#define LUA_GCSTEP		5
+
#define LUA_GCSETPAUSE		6
+
#define LUA_GCSETSTEPMUL	7
+
#define LUA_GCISRUNNING		9
+

+
LUA_API int (lua_gc) (lua_State *L, int what, int data);
+

+

+
/*
+
** miscellaneous functions
+
*/
+

+
LUA_API int   (lua_error) (lua_State *L);
+

+
LUA_API int   (lua_next) (lua_State *L, int idx);
+

+
LUA_API void  (lua_concat) (lua_State *L, int n);
+
LUA_API void  (lua_len)    (lua_State *L, int idx);
+

+
LUA_API size_t   (lua_stringtonumber) (lua_State *L, const char *s);
+

+
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
+
LUA_API void      (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
+

+

+

+
/*
+
** {==============================================================
+
** some useful macros
+
** ===============================================================
+
*/
+

+
#define lua_getextraspace(L)	((void *)((char *)(L) - LUA_EXTRASPACE))
+

+
#define lua_tonumber(L,i)	lua_tonumberx(L,(i),NULL)
+
#define lua_tointeger(L,i)	lua_tointegerx(L,(i),NULL)
+

+
#define lua_pop(L,n)		lua_settop(L, -(n)-1)
+

+
#define lua_newtable(L)		lua_createtable(L, 0, 0)
+

+
#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
+

+
#define lua_pushcfunction(L,f)	lua_pushcclosure(L, (f), 0)
+

+
#define lua_isfunction(L,n)	(lua_type(L, (n)) == LUA_TFUNCTION)
+
#define lua_istable(L,n)	(lua_type(L, (n)) == LUA_TTABLE)
+
#define lua_islightuserdata(L,n)	(lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
+
#define lua_isnil(L,n)		(lua_type(L, (n)) == LUA_TNIL)
+
#define lua_isboolean(L,n)	(lua_type(L, (n)) == LUA_TBOOLEAN)
+
#define lua_isthread(L,n)	(lua_type(L, (n)) == LUA_TTHREAD)
+
#define lua_isnone(L,n)		(lua_type(L, (n)) == LUA_TNONE)
+
#define lua_isnoneornil(L, n)	(lua_type(L, (n)) <= 0)
+

+
#define lua_pushliteral(L, s)	lua_pushstring(L, "" s)
+

+
#define lua_pushglobaltable(L)  \
+
	((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
+

+
#define lua_tostring(L,i)	lua_tolstring(L, (i), NULL)
+

+

+
#define lua_insert(L,idx)	lua_rotate(L, (idx), 1)
+

+
#define lua_remove(L,idx)	(lua_rotate(L, (idx), -1), lua_pop(L, 1))
+

+
#define lua_replace(L,idx)	(lua_copy(L, -1, (idx)), lua_pop(L, 1))
+

+
/* }============================================================== */
+

+

+
/*
+
** {==============================================================
+
** compatibility macros for unsigned conversions
+
** ===============================================================
+
*/
+
#if defined(LUA_COMPAT_APIINTCASTS)
+

+
#define lua_pushunsigned(L,n)	lua_pushinteger(L, (lua_Integer)(n))
+
#define lua_tounsignedx(L,i,is)	((lua_Unsigned)lua_tointegerx(L,i,is))
+
#define lua_tounsigned(L,i)	lua_tounsignedx(L,(i),NULL)
+

+
#endif
+
/* }============================================================== */
+

+
/*
+
** {======================================================================
+
** Debug API
+
** =======================================================================
+
*/
+

+

+
/*
+
** Event codes
+
*/
+
#define LUA_HOOKCALL	0
+
#define LUA_HOOKRET	1
+
#define LUA_HOOKLINE	2
+
#define LUA_HOOKCOUNT	3
+
#define LUA_HOOKTAILCALL 4
+

+

+
/*
+
** Event masks
+
*/
+
#define LUA_MASKCALL	(1 << LUA_HOOKCALL)
+
#define LUA_MASKRET	(1 << LUA_HOOKRET)
+
#define LUA_MASKLINE	(1 << LUA_HOOKLINE)
+
#define LUA_MASKCOUNT	(1 << LUA_HOOKCOUNT)
+

+
typedef struct lua_Debug lua_Debug;  /* activation record */
+

+

+
/* Functions to be called by the debugger in specific events */
+
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+

+

+
LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
+
LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
+
LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
+
LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
+
LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
+
LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
+

+
LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n);
+
LUA_API void  (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
+
                                               int fidx2, int n2);
+

+
LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
+
LUA_API lua_Hook (lua_gethook) (lua_State *L);
+
LUA_API int (lua_gethookmask) (lua_State *L);
+
LUA_API int (lua_gethookcount) (lua_State *L);
+

+

+
struct lua_Debug {
+
  int event;
+
  const char *name;	/* (n) */
+
  const char *namewhat;	/* (n) 'global', 'local', 'field', 'method' */
+
  const char *what;	/* (S) 'Lua', 'C', 'main', 'tail' */
+
  const char *source;	/* (S) */
+
  int currentline;	/* (l) */
+
  int linedefined;	/* (S) */
+
  int lastlinedefined;	/* (S) */
+
  unsigned char nups;	/* (u) number of upvalues */
+
  unsigned char nparams;/* (u) number of parameters */
+
  char isvararg;        /* (u) */
+
  char istailcall;	/* (t) */
+
  char short_src[LUA_IDSIZE]; /* (S) */
+
  /* private part */
+
  struct CallInfo *i_ci;  /* active function */
+
};
+

+
/* }====================================================================== */
+

+

+
/******************************************************************************
+
* Copyright (C) 1994-2018 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:
+
*
+
* 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.
+
******************************************************************************/
+

+

+
#endif
added external/lua/src/lua.hpp
@@ -0,0 +1,9 @@
+
// lua.hpp
+
// Lua header files for C++
+
// <<extern "C">> not supplied automatically because Lua also compiles as C++
+

+
extern "C" {
+
#include "lua.h"
+
#include "lualib.h"
+
#include "lauxlib.h"
+
}
added external/lua/src/luac.c
@@ -0,0 +1,450 @@
+
/*
+
** $Id: luac.c,v 1.76 2018/06/19 01:32:02 lhf Exp $
+
** Lua compiler (saves bytecodes to files; also lists bytecodes)
+
** See Copyright Notice in lua.h
+
*/
+

+
#define luac_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+
#include <ctype.h>
+
#include <errno.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+
#include "lauxlib.h"
+

+
#include "lobject.h"
+
#include "lstate.h"
+
#include "lundump.h"
+

+
static void PrintFunction(const Proto* f, int full);
+
#define luaU_print	PrintFunction
+

+
#define PROGNAME	"luac"		/* default program name */
+
#define OUTPUT		PROGNAME ".out"	/* default output file */
+

+
static int listing=0;			/* list bytecodes? */
+
static int dumping=1;			/* dump bytecodes? */
+
static int stripping=0;			/* strip debug information? */
+
static char Output[]={ OUTPUT };	/* default output file name */
+
static const char* output=Output;	/* actual output file name */
+
static const char* progname=PROGNAME;	/* actual program name */
+

+
static void fatal(const char* message)
+
{
+
 fprintf(stderr,"%s: %s\n",progname,message);
+
 exit(EXIT_FAILURE);
+
}
+

+
static void cannot(const char* what)
+
{
+
 fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
+
 exit(EXIT_FAILURE);
+
}
+

+
static void usage(const char* message)
+
{
+
 if (*message=='-')
+
  fprintf(stderr,"%s: unrecognized option '%s'\n",progname,message);
+
 else
+
  fprintf(stderr,"%s: %s\n",progname,message);
+
 fprintf(stderr,
+
  "usage: %s [options] [filenames]\n"
+
  "Available options are:\n"
+
  "  -l       list (use -l -l for full listing)\n"
+
  "  -o name  output to file 'name' (default is \"%s\")\n"
+
  "  -p       parse only\n"
+
  "  -s       strip debug information\n"
+
  "  -v       show version information\n"
+
  "  --       stop handling options\n"
+
  "  -        stop handling options and process stdin\n"
+
  ,progname,Output);
+
 exit(EXIT_FAILURE);
+
}
+

+
#define IS(s)	(strcmp(argv[i],s)==0)
+

+
static int doargs(int argc, char* argv[])
+
{
+
 int i;
+
 int version=0;
+
 if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
+
 for (i=1; i<argc; i++)
+
 {
+
  if (*argv[i]!='-')			/* end of options; keep it */
+
   break;
+
  else if (IS("--"))			/* end of options; skip it */
+
  {
+
   ++i;
+
   if (version) ++version;
+
   break;
+
  }
+
  else if (IS("-"))			/* end of options; use stdin */
+
   break;
+
  else if (IS("-l"))			/* list */
+
   ++listing;
+
  else if (IS("-o"))			/* output file */
+
  {
+
   output=argv[++i];
+
   if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
+
    usage("'-o' needs argument");
+
   if (IS("-")) output=NULL;
+
  }
+
  else if (IS("-p"))			/* parse only */
+
   dumping=0;
+
  else if (IS("-s"))			/* strip debug information */
+
   stripping=1;
+
  else if (IS("-v"))			/* show version */
+
   ++version;
+
  else					/* unknown option */
+
   usage(argv[i]);
+
 }
+
 if (i==argc && (listing || !dumping))
+
 {
+
  dumping=0;
+
  argv[--i]=Output;
+
 }
+
 if (version)
+
 {
+
  printf("%s\n",LUA_COPYRIGHT);
+
  if (version==argc-1) exit(EXIT_SUCCESS);
+
 }
+
 return i;
+
}
+

+
#define FUNCTION "(function()end)();"
+

+
static const char* reader(lua_State *L, void *ud, size_t *size)
+
{
+
 UNUSED(L);
+
 if ((*(int*)ud)--)
+
 {
+
  *size=sizeof(FUNCTION)-1;
+
  return FUNCTION;
+
 }
+
 else
+
 {
+
  *size=0;
+
  return NULL;
+
 }
+
}
+

+
#define toproto(L,i) getproto(L->top+(i))
+

+
static const Proto* combine(lua_State* L, int n)
+
{
+
 if (n==1)
+
  return toproto(L,-1);
+
 else
+
 {
+
  Proto* f;
+
  int i=n;
+
  if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1));
+
  f=toproto(L,-1);
+
  for (i=0; i<n; i++)
+
  {
+
   f->p[i]=toproto(L,i-n-1);
+
   if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
+
  }
+
  f->sizelineinfo=0;
+
  return f;
+
 }
+
}
+

+
static int writer(lua_State* L, const void* p, size_t size, void* u)
+
{
+
 UNUSED(L);
+
 return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
+
}
+

+
static int pmain(lua_State* L)
+
{
+
 int argc=(int)lua_tointeger(L,1);
+
 char** argv=(char**)lua_touserdata(L,2);
+
 const Proto* f;
+
 int i;
+
 if (!lua_checkstack(L,argc)) fatal("too many input files");
+
 for (i=0; i<argc; i++)
+
 {
+
  const char* filename=IS("-") ? NULL : argv[i];
+
  if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1));
+
 }
+
 f=combine(L,argc);
+
 if (listing) luaU_print(f,listing>1);
+
 if (dumping)
+
 {
+
  FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
+
  if (D==NULL) cannot("open");
+
  lua_lock(L);
+
  luaU_dump(L,f,writer,D,stripping);
+
  lua_unlock(L);
+
  if (ferror(D)) cannot("write");
+
  if (fclose(D)) cannot("close");
+
 }
+
 return 0;
+
}
+

+
int main(int argc, char* argv[])
+
{
+
 lua_State* L;
+
 int i=doargs(argc,argv);
+
 argc-=i; argv+=i;
+
 if (argc<=0) usage("no input files given");
+
 L=luaL_newstate();
+
 if (L==NULL) fatal("cannot create state: not enough memory");
+
 lua_pushcfunction(L,&pmain);
+
 lua_pushinteger(L,argc);
+
 lua_pushlightuserdata(L,argv);
+
 if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
+
 lua_close(L);
+
 return EXIT_SUCCESS;
+
}
+

+
/*
+
** $Id: luac.c,v 1.76 2018/06/19 01:32:02 lhf Exp $
+
** print bytecodes
+
** See Copyright Notice in lua.h
+
*/
+

+
#include <ctype.h>
+
#include <stdio.h>
+

+
#define luac_c
+
#define LUA_CORE
+

+
#include "ldebug.h"
+
#include "lobject.h"
+
#include "lopcodes.h"
+

+
#define VOID(p)		((const void*)(p))
+

+
static void PrintString(const TString* ts)
+
{
+
 const char* s=getstr(ts);
+
 size_t i,n=tsslen(ts);
+
 printf("%c",'"');
+
 for (i=0; i<n; i++)
+
 {
+
  int c=(int)(unsigned char)s[i];
+
  switch (c)
+
  {
+
   case '"':  printf("\\\""); break;
+
   case '\\': printf("\\\\"); break;
+
   case '\a': printf("\\a"); break;
+
   case '\b': printf("\\b"); break;
+
   case '\f': printf("\\f"); break;
+
   case '\n': printf("\\n"); break;
+
   case '\r': printf("\\r"); break;
+
   case '\t': printf("\\t"); break;
+
   case '\v': printf("\\v"); break;
+
   default:	if (isprint(c))
+
   			printf("%c",c);
+
		else
+
			printf("\\%03d",c);
+
  }
+
 }
+
 printf("%c",'"');
+
}
+

+
static void PrintConstant(const Proto* f, int i)
+
{
+
 const TValue* o=&f->k[i];
+
 switch (ttype(o))
+
 {
+
  case LUA_TNIL:
+
	printf("nil");
+
	break;
+
  case LUA_TBOOLEAN:
+
	printf(bvalue(o) ? "true" : "false");
+
	break;
+
  case LUA_TNUMFLT:
+
	{
+
	char buff[100];
+
	sprintf(buff,LUA_NUMBER_FMT,fltvalue(o));
+
	printf("%s",buff);
+
	if (buff[strspn(buff,"-0123456789")]=='\0') printf(".0");
+
	break;
+
	}
+
  case LUA_TNUMINT:
+
	printf(LUA_INTEGER_FMT,ivalue(o));
+
	break;
+
  case LUA_TSHRSTR: case LUA_TLNGSTR:
+
	PrintString(tsvalue(o));
+
	break;
+
  default:				/* cannot happen */
+
	printf("? type=%d",ttype(o));
+
	break;
+
 }
+
}
+

+
#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
+
#define MYK(x)		(-1-(x))
+

+
static void PrintCode(const Proto* f)
+
{
+
 const Instruction* code=f->code;
+
 int pc,n=f->sizecode;
+
 for (pc=0; pc<n; pc++)
+
 {
+
  Instruction i=code[pc];
+
  OpCode o=GET_OPCODE(i);
+
  int a=GETARG_A(i);
+
  int b=GETARG_B(i);
+
  int c=GETARG_C(i);
+
  int ax=GETARG_Ax(i);
+
  int bx=GETARG_Bx(i);
+
  int sbx=GETARG_sBx(i);
+
  int line=getfuncline(f,pc);
+
  printf("\t%d\t",pc+1);
+
  if (line>0) printf("[%d]\t",line); else printf("[-]\t");
+
  printf("%-9s\t",luaP_opnames[o]);
+
  switch (getOpMode(o))
+
  {
+
   case iABC:
+
    printf("%d",a);
+
    if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b);
+
    if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c);
+
    break;
+
   case iABx:
+
    printf("%d",a);
+
    if (getBMode(o)==OpArgK) printf(" %d",MYK(bx));
+
    if (getBMode(o)==OpArgU) printf(" %d",bx);
+
    break;
+
   case iAsBx:
+
    printf("%d %d",a,sbx);
+
    break;
+
   case iAx:
+
    printf("%d",MYK(ax));
+
    break;
+
  }
+
  switch (o)
+
  {
+
   case OP_LOADK:
+
    printf("\t; "); PrintConstant(f,bx);
+
    break;
+
   case OP_GETUPVAL:
+
   case OP_SETUPVAL:
+
    printf("\t; %s",UPVALNAME(b));
+
    break;
+
   case OP_GETTABUP:
+
    printf("\t; %s",UPVALNAME(b));
+
    if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
+
    break;
+
   case OP_SETTABUP:
+
    printf("\t; %s",UPVALNAME(a));
+
    if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
+
    if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
+
    break;
+
   case OP_GETTABLE:
+
   case OP_SELF:
+
    if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
+
    break;
+
   case OP_SETTABLE:
+
   case OP_ADD:
+
   case OP_SUB:
+
   case OP_MUL:
+
   case OP_MOD:
+
   case OP_POW:
+
   case OP_DIV:
+
   case OP_IDIV:
+
   case OP_BAND:
+
   case OP_BOR:
+
   case OP_BXOR:
+
   case OP_SHL:
+
   case OP_SHR:
+
   case OP_EQ:
+
   case OP_LT:
+
   case OP_LE:
+
    if (ISK(b) || ISK(c))
+
    {
+
     printf("\t; ");
+
     if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
+
     printf(" ");
+
     if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
+
    }
+
    break;
+
   case OP_JMP:
+
   case OP_FORLOOP:
+
   case OP_FORPREP:
+
   case OP_TFORLOOP:
+
    printf("\t; to %d",sbx+pc+2);
+
    break;
+
   case OP_CLOSURE:
+
    printf("\t; %p",VOID(f->p[bx]));
+
    break;
+
   case OP_SETLIST:
+
    if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c);
+
    break;
+
   case OP_EXTRAARG:
+
    printf("\t; "); PrintConstant(f,ax);
+
    break;
+
   default:
+
    break;
+
  }
+
  printf("\n");
+
 }
+
}
+

+
#define SS(x)	((x==1)?"":"s")
+
#define S(x)	(int)(x),SS(x)
+

+
static void PrintHeader(const Proto* f)
+
{
+
 const char* s=f->source ? getstr(f->source) : "=?";
+
 if (*s=='@' || *s=='=')
+
  s++;
+
 else if (*s==LUA_SIGNATURE[0])
+
  s="(bstring)";
+
 else
+
  s="(string)";
+
 printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
+
 	(f->linedefined==0)?"main":"function",s,
+
	f->linedefined,f->lastlinedefined,
+
	S(f->sizecode),VOID(f));
+
 printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
+
	(int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
+
	S(f->maxstacksize),S(f->sizeupvalues));
+
 printf("%d local%s, %d constant%s, %d function%s\n",
+
	S(f->sizelocvars),S(f->sizek),S(f->sizep));
+
}
+

+
static void PrintDebug(const Proto* f)
+
{
+
 int i,n;
+
 n=f->sizek;
+
 printf("constants (%d) for %p:\n",n,VOID(f));
+
 for (i=0; i<n; i++)
+
 {
+
  printf("\t%d\t",i+1);
+
  PrintConstant(f,i);
+
  printf("\n");
+
 }
+
 n=f->sizelocvars;
+
 printf("locals (%d) for %p:\n",n,VOID(f));
+
 for (i=0; i<n; i++)
+
 {
+
  printf("\t%d\t%s\t%d\t%d\n",
+
  i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
+
 }
+
 n=f->sizeupvalues;
+
 printf("upvalues (%d) for %p:\n",n,VOID(f));
+
 for (i=0; i<n; i++)
+
 {
+
  printf("\t%d\t%s\t%d\t%d\n",
+
  i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
+
 }
+
}
+

+
static void PrintFunction(const Proto* f, int full)
+
{
+
 int i,n=f->sizep;
+
 PrintHeader(f);
+
 PrintCode(f);
+
 if (full) PrintDebug(f);
+
 for (i=0; i<n; i++) PrintFunction(f->p[i],full);
+
}
added external/lua/src/luaconf.h
@@ -0,0 +1,790 @@
+
/*
+
** $Id: luaconf.h,v 1.259.1.1 2017/04/19 17:29:57 roberto Exp $
+
** Configuration file for Lua
+
** See Copyright Notice in lua.h
+
*/
+

+

+
#ifndef luaconf_h
+
#define luaconf_h
+

+
#include <limits.h>
+
#include <stddef.h>
+

+

+
/*
+
** ===================================================================
+
** Search for "@@" to find all configurable definitions.
+
** ===================================================================
+
*/
+

+

+
/*
+
** {====================================================================
+
** System Configuration: macros to adapt (if needed) Lua to some
+
** particular platform, for instance compiling it with 32-bit numbers or
+
** restricting it to C89.
+
** =====================================================================
+
*/
+

+
/*
+
@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You
+
** can also define LUA_32BITS in the make file, but changing here you
+
** ensure that all software connected to Lua will be compiled with the
+
** same configuration.
+
*/
+
/* #define LUA_32BITS */
+

+

+
/*
+
@@ LUA_USE_C89 controls the use of non-ISO-C89 features.
+
** Define it if you want Lua to avoid the use of a few C99 features
+
** or Windows-specific features on Windows.
+
*/
+
/* #define LUA_USE_C89 */
+

+

+
/*
+
** By default, Lua on Windows use (some) specific Windows features
+
*/
+
#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE)
+
#define LUA_USE_WINDOWS  /* enable goodies for regular Windows */
+
#endif
+

+

+
#if defined(LUA_USE_WINDOWS)
+
#define LUA_DL_DLL	/* enable support for DLL */
+
#define LUA_USE_C89	/* broadly, Windows is C89 */
+
#endif
+

+

+
#if defined(LUA_USE_LINUX)
+
#define LUA_USE_POSIX
+
#define LUA_USE_DLOPEN		/* needs an extra library: -ldl */
+
#define LUA_USE_READLINE	/* needs some extra libraries */
+
#endif
+

+

+
#if defined(LUA_USE_MACOSX)
+
#define LUA_USE_POSIX
+
#define LUA_USE_DLOPEN		/* MacOS does not need -ldl */
+
#define LUA_USE_READLINE	/* needs an extra library: -lreadline */
+
#endif
+

+

+
/*
+
@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
+
** C89 ('long' and 'double'); Windows always has '__int64', so it does
+
** not need to use this case.
+
*/
+
#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
+
#define LUA_C89_NUMBERS
+
#endif
+

+

+

+
/*
+
@@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'.
+
*/
+
/* avoid undefined shifts */
+
#if ((INT_MAX >> 15) >> 15) >= 1
+
#define LUAI_BITSINT	32
+
#else
+
/* 'int' always must have at least 16 bits */
+
#define LUAI_BITSINT	16
+
#endif
+

+

+
/*
+
@@ LUA_INT_TYPE defines the type for Lua integers.
+
@@ LUA_FLOAT_TYPE defines the type for Lua floats.
+
** Lua should work fine with any mix of these options (if supported
+
** by your C compiler). The usual configurations are 64-bit integers
+
** and 'double' (the default), 32-bit integers and 'float' (for
+
** restricted platforms), and 'long'/'double' (for C compilers not
+
** compliant with C99, which may not have support for 'long long').
+
*/
+

+
/* predefined options for LUA_INT_TYPE */
+
#define LUA_INT_INT		1
+
#define LUA_INT_LONG		2
+
#define LUA_INT_LONGLONG	3
+

+
/* predefined options for LUA_FLOAT_TYPE */
+
#define LUA_FLOAT_FLOAT		1
+
#define LUA_FLOAT_DOUBLE	2
+
#define LUA_FLOAT_LONGDOUBLE	3
+

+
#if defined(LUA_32BITS)		/* { */
+
/*
+
** 32-bit integers and 'float'
+
*/
+
#if LUAI_BITSINT >= 32  /* use 'int' if big enough */
+
#define LUA_INT_TYPE	LUA_INT_INT
+
#else  /* otherwise use 'long' */
+
#define LUA_INT_TYPE	LUA_INT_LONG
+
#endif
+
#define LUA_FLOAT_TYPE	LUA_FLOAT_FLOAT
+

+
#elif defined(LUA_C89_NUMBERS)	/* }{ */
+
/*
+
** largest types available for C89 ('long' and 'double')
+
*/
+
#define LUA_INT_TYPE	LUA_INT_LONG
+
#define LUA_FLOAT_TYPE	LUA_FLOAT_DOUBLE
+

+
#endif				/* } */
+

+

+
/*
+
** default configuration for 64-bit Lua ('long long' and 'double')
+
*/
+
#if !defined(LUA_INT_TYPE)
+
#define LUA_INT_TYPE	LUA_INT_LONGLONG
+
#endif
+

+
#if !defined(LUA_FLOAT_TYPE)
+
#define LUA_FLOAT_TYPE	LUA_FLOAT_DOUBLE
+
#endif
+

+
/* }================================================================== */
+

+

+

+

+
/*
+
** {==================================================================
+
** Configuration for Paths.
+
** ===================================================================
+
*/
+

+
/*
+
** LUA_PATH_SEP is the character that separates templates in a path.
+
** LUA_PATH_MARK is the string that marks the substitution points in a
+
** template.
+
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
+
** directory.
+
*/
+
#define LUA_PATH_SEP            ";"
+
#define LUA_PATH_MARK           "?"
+
#define LUA_EXEC_DIR            "!"
+

+

+
/*
+
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
+
** Lua libraries.
+
@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
+
** C libraries.
+
** CHANGE them if your machine has a non-conventional directory
+
** hierarchy or if you want to install your libraries in
+
** non-conventional directories.
+
*/
+
#define LUA_VDIR	LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+
#if defined(_WIN32)	/* { */
+
/*
+
** In Windows, any exclamation mark ('!') in the path is replaced by the
+
** path of the directory of the executable file of the current process.
+
*/
+
#define LUA_LDIR	"!\\lua\\"
+
#define LUA_CDIR	"!\\"
+
#define LUA_SHRDIR	"!\\..\\share\\lua\\" LUA_VDIR "\\"
+
#define LUA_PATH_DEFAULT  \
+
		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 \
+
		LUA_CDIR"?.dll;" \
+
		LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \
+
		LUA_CDIR"loadall.dll;" ".\\?.dll"
+

+
#else			/* }{ */
+

+
#define LUA_ROOT	"/usr/local/"
+
#define LUA_LDIR	LUA_ROOT "share/lua/" LUA_VDIR "/"
+
#define LUA_CDIR	LUA_ROOT "lib/lua/" LUA_VDIR "/"
+
#define LUA_PATH_DEFAULT  \
+
		LUA_LDIR"?.lua;"  LUA_LDIR"?/init.lua;" \
+
		LUA_CDIR"?.lua;"  LUA_CDIR"?/init.lua;" \
+
		"./?.lua;" "./?/init.lua"
+
#define LUA_CPATH_DEFAULT \
+
		LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
+
#endif			/* } */
+

+

+
/*
+
@@ LUA_DIRSEP is the directory separator (for submodules).
+
** CHANGE it if your machine does not use "/" as the directory separator
+
** and is not Windows. (On Windows Lua automatically uses "\".)
+
*/
+
#if defined(_WIN32)
+
#define LUA_DIRSEP	"\\"
+
#else
+
#define LUA_DIRSEP	"/"
+
#endif
+

+
/* }================================================================== */
+

+

+
/*
+
** {==================================================================
+
** Marks for exported symbols in the C code
+
** ===================================================================
+
*/
+

+
/*
+
@@ LUA_API is a mark for all core API functions.
+
@@ LUALIB_API is a mark for all auxiliary library functions.
+
@@ LUAMOD_API is a mark for all standard library opening functions.
+
** CHANGE them if you need to define those functions in some special way.
+
** For instance, if you want to create one Windows DLL with the core and
+
** the libraries, you may want to use the following definition (define
+
** LUA_BUILD_AS_DLL to get it).
+
*/
+
#if defined(LUA_BUILD_AS_DLL)	/* { */
+

+
#if defined(LUA_CORE) || defined(LUA_LIB)	/* { */
+
#define LUA_API __declspec(dllexport)
+
#else						/* }{ */
+
#define LUA_API __declspec(dllimport)
+
#endif						/* } */
+

+
#else				/* }{ */
+

+
#define LUA_API		extern
+

+
#endif				/* } */
+

+

+
/* more often than not the libs go together with the core */
+
#define LUALIB_API	LUA_API
+
#define LUAMOD_API	LUALIB_API
+

+

+
/*
+
@@ LUAI_FUNC is a mark for all extern functions that are not to be
+
** 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. 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(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+
    defined(__ELF__)		/* { */
+
#define LUAI_FUNC	__attribute__((visibility("hidden"))) extern
+
#else				/* }{ */
+
#define LUAI_FUNC	extern
+
#endif				/* } */
+

+
#define LUAI_DDEC	LUAI_FUNC
+
#define LUAI_DDEF	/* empty */
+

+
/* }================================================================== */
+

+

+
/*
+
** {==================================================================
+
** Compatibility with previous versions
+
** ===================================================================
+
*/
+

+
/*
+
@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2.
+
@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1.
+
** You can define it to get all options, or change specific options
+
** to fit your specific needs.
+
*/
+
#if defined(LUA_COMPAT_5_2)	/* { */
+

+
/*
+
@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated
+
** functions in the mathematical library.
+
*/
+
#define LUA_COMPAT_MATHLIB
+

+
/*
+
@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'.
+
*/
+
#define LUA_COMPAT_BITLIB
+

+
/*
+
@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod.
+
*/
+
#define LUA_COMPAT_IPAIRS
+

+
/*
+
@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
+
** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
+
** luaL_checkint, luaL_checklong, etc.)
+
*/
+
#define LUA_COMPAT_APIINTCASTS
+

+
#endif				/* } */
+

+

+
#if defined(LUA_COMPAT_5_1)	/* { */
+

+
/* Incompatibilities from 5.2 -> 5.3 */
+
#define LUA_COMPAT_MATHLIB
+
#define LUA_COMPAT_APIINTCASTS
+

+
/*
+
@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
+
** You can replace it with 'table.unpack'.
+
*/
+
#define LUA_COMPAT_UNPACK
+

+
/*
+
@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
+
** You can replace it with 'package.searchers'.
+
*/
+
#define LUA_COMPAT_LOADERS
+

+
/*
+
@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
+
** You can call your C function directly (with light C functions).
+
*/
+
#define lua_cpcall(L,f,u)  \
+
	(lua_pushcfunction(L, (f)), \
+
	 lua_pushlightuserdata(L,(u)), \
+
	 lua_pcall(L,1,0,0))
+

+

+
/*
+
@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
+
** You can rewrite 'log10(x)' as 'log(x, 10)'.
+
*/
+
#define LUA_COMPAT_LOG10
+

+
/*
+
@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
+
** library. You can rewrite 'loadstring(s)' as 'load(s)'.
+
*/
+
#define LUA_COMPAT_LOADSTRING
+

+
/*
+
@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
+
*/
+
#define LUA_COMPAT_MAXN
+

+
/*
+
@@ The following macros supply trivial compatibility for some
+
** changes in the API. The macros themselves document how to
+
** change your code to avoid using them.
+
*/
+
#define lua_strlen(L,i)		lua_rawlen(L, (i))
+

+
#define lua_objlen(L,i)		lua_rawlen(L, (i))
+

+
#define lua_equal(L,idx1,idx2)		lua_compare(L,(idx1),(idx2),LUA_OPEQ)
+
#define lua_lessthan(L,idx1,idx2)	lua_compare(L,(idx1),(idx2),LUA_OPLT)
+

+
/*
+
@@ LUA_COMPAT_MODULE controls compatibility with previous
+
** module functions 'module' (Lua) and 'luaL_register' (C).
+
*/
+
#define LUA_COMPAT_MODULE
+

+
#endif				/* } */
+

+

+
/*
+
@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
+
@@ a float mark ('.0').
+
** This macro is not on by default even in compatibility mode,
+
** because this is not really an incompatibility.
+
*/
+
/* #define LUA_COMPAT_FLOATSTRING */
+

+
/* }================================================================== */
+

+

+

+
/*
+
** {==================================================================
+
** Configuration for Numbers.
+
** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
+
** satisfy your needs.
+
** ===================================================================
+
*/
+

+
/*
+
@@ LUA_NUMBER is the floating-point type used by Lua.
+
@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
+
@@ over a floating number.
+
@@ l_mathlim(x) corrects limit name 'x' to the proper float type
+
** by prefixing it with one of FLT/DBL/LDBL.
+
@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
+
@@ LUA_NUMBER_FMT is the format for writing floats.
+
@@ lua_number2str converts a float to a string.
+
@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
+
@@ l_floor takes the floor of a float.
+
@@ lua_str2number converts a decimal numeric string to a number.
+
*/
+

+

+
/* The following definitions are good for most cases here */
+

+
#define l_floor(x)		(l_mathop(floor)(x))
+

+
#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
+
** returns 0 if float is not within the range of a lua_Integer.
+
** (The range comparisons are tricky because of rounding. The tests
+
** here assume a two-complement representation, where MININTEGER always
+
** has an exact representation as a float; MAXINTEGER may not have one,
+
** and therefore its conversion to float may have an ill-defined value.)
+
*/
+
#define lua_numbertointeger(n,p) \
+
  ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
+
   (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
+
      (*(p) = (LUA_INTEGER)(n), 1))
+

+

+
/* now the variable definitions */
+

+
#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT		/* { single float */
+

+
#define LUA_NUMBER	float
+

+
#define l_mathlim(n)		(FLT_##n)
+

+
#define LUAI_UACNUMBER	double
+

+
#define LUA_NUMBER_FRMLEN	""
+
#define LUA_NUMBER_FMT		"%.7g"
+

+
#define l_mathop(op)		op##f
+

+
#define lua_str2number(s,p)	strtof((s), (p))
+

+

+
#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE	/* }{ long double */
+

+
#define LUA_NUMBER	long double
+

+
#define l_mathlim(n)		(LDBL_##n)
+

+
#define LUAI_UACNUMBER	long double
+

+
#define LUA_NUMBER_FRMLEN	"L"
+
#define LUA_NUMBER_FMT		"%.19Lg"
+

+
#define l_mathop(op)		op##l
+

+
#define lua_str2number(s,p)	strtold((s), (p))
+

+
#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE	/* }{ double */
+

+
#define LUA_NUMBER	double
+

+
#define l_mathlim(n)		(DBL_##n)
+

+
#define LUAI_UACNUMBER	double
+

+
#define LUA_NUMBER_FRMLEN	""
+
#define LUA_NUMBER_FMT		"%.14g"
+

+
#define l_mathop(op)		op
+

+
#define lua_str2number(s,p)	strtod((s), (p))
+

+
#else						/* }{ */
+

+
#error "numeric float type not defined"
+

+
#endif					/* } */
+

+

+

+
/*
+
@@ LUA_INTEGER is the integer type used by Lua.
+
**
+
@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
+
**
+
@@ LUAI_UACINT is the result of a 'default argument promotion'
+
@@ over a lUA_INTEGER.
+
@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
+
@@ LUA_INTEGER_FMT is the format for writing integers.
+
@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
+
@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
+
@@ lua_integer2str converts an integer to a string.
+
*/
+

+

+
/* The following definitions are good for most cases here */
+

+
#define LUA_INTEGER_FMT		"%" LUA_INTEGER_FRMLEN "d"
+

+
#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
+
** can turn a comparison between unsigneds into a signed comparison)
+
*/
+
#define LUA_UNSIGNED		unsigned LUAI_UACINT
+

+

+
/* now the variable definitions */
+

+
#if LUA_INT_TYPE == LUA_INT_INT		/* { int */
+

+
#define LUA_INTEGER		int
+
#define LUA_INTEGER_FRMLEN	""
+

+
#define LUA_MAXINTEGER		INT_MAX
+
#define LUA_MININTEGER		INT_MIN
+

+
#elif LUA_INT_TYPE == LUA_INT_LONG	/* }{ long */
+

+
#define LUA_INTEGER		long
+
#define LUA_INTEGER_FRMLEN	"l"
+

+
#define LUA_MAXINTEGER		LONG_MAX
+
#define LUA_MININTEGER		LONG_MIN
+

+
#elif LUA_INT_TYPE == LUA_INT_LONGLONG	/* }{ long long */
+

+
/* use presence of macro LLONG_MAX as proxy for C99 compliance */
+
#if defined(LLONG_MAX)		/* { */
+
/* use ISO C99 stuff */
+

+
#define LUA_INTEGER		long long
+
#define LUA_INTEGER_FRMLEN	"ll"
+

+
#define LUA_MAXINTEGER		LLONG_MAX
+
#define LUA_MININTEGER		LLONG_MIN
+

+
#elif defined(LUA_USE_WINDOWS) /* }{ */
+
/* in Windows, can use specific Windows types */
+

+
#define LUA_INTEGER		__int64
+
#define LUA_INTEGER_FRMLEN	"I64"
+

+
#define LUA_MAXINTEGER		_I64_MAX
+
#define LUA_MININTEGER		_I64_MIN
+

+
#else				/* }{ */
+

+
#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
+
  or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)"
+

+
#endif				/* } */
+

+
#else				/* }{ */
+

+
#error "numeric integer type not defined"
+

+
#endif				/* } */
+

+
/* }================================================================== */
+

+

+
/*
+
** {==================================================================
+
** Dependencies with C99 and other C details
+
** ===================================================================
+
*/
+

+
/*
+
@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89.
+
** (All uses in Lua have only one format item.)
+
*/
+
#if !defined(LUA_USE_C89)
+
#define l_sprintf(s,sz,f,i)	snprintf(s,sz,f,i)
+
#else
+
#define l_sprintf(s,sz,f,i)	((void)(sz), sprintf(s,f,i))
+
#endif
+

+

+
/*
+
@@ lua_strx2number converts an hexadecimal numeric string to a number.
+
** In C99, 'strtod' does that conversion. Otherwise, you can
+
** leave 'lua_strx2number' undefined and Lua will provide its own
+
** implementation.
+
*/
+
#if !defined(LUA_USE_C89)
+
#define lua_strx2number(s,p)		lua_str2number(s,p)
+
#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.
+
** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
+
** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
+
** provide its own implementation.
+
*/
+
#if !defined(LUA_USE_C89)
+
#define lua_number2strx(L,b,sz,f,n)  \
+
	((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n)))
+
#endif
+

+

+
/*
+
** 'strtof' and 'opf' variants for math functions are not valid in
+
** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the
+
** availability of these variants. ('math.h' is already included in
+
** all files that use these macros.)
+
*/
+
#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF))
+
#undef l_mathop  /* variants not available */
+
#undef lua_str2number
+
#define l_mathop(op)		(lua_Number)op  /* no variant */
+
#define lua_str2number(s,p)	((lua_Number)strtod((s), (p)))
+
#endif
+

+

+
/*
+
@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation
+
** functions.  It must be a numerical type; Lua will use 'intptr_t' if
+
** available, otherwise it will use 'ptrdiff_t' (the nearest thing to
+
** 'intptr_t' in C89)
+
*/
+
#define LUA_KCONTEXT	ptrdiff_t
+

+
#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
+
    __STDC_VERSION__ >= 199901L
+
#include <stdint.h>
+
#if defined(INTPTR_MAX)  /* even in C99 this type is optional */
+
#undef LUA_KCONTEXT
+
#define LUA_KCONTEXT	intptr_t
+
#endif
+
#endif
+

+

+
/*
+
@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
+
** Change that if you do not want to use C locales. (Code using this
+
** macro must include header 'locale.h'.)
+
*/
+
#if !defined(lua_getlocaledecpoint)
+
#define lua_getlocaledecpoint()		(localeconv()->decimal_point[0])
+
#endif
+

+
/* }================================================================== */
+

+

+
/*
+
** {==================================================================
+
** Language Variations
+
** =====================================================================
+
*/
+

+
/*
+
@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
+
** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
+
** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
+
** coercion from strings to numbers.
+
*/
+
/* #define LUA_NOCVTN2S */
+
/* #define LUA_NOCVTS2N */
+

+

+
/*
+
@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
+
** Define it as a help when debugging C code.
+
*/
+
#if defined(LUA_USE_APICHECK)
+
#include <assert.h>
+
#define luai_apicheck(l,e)	assert(e)
+
#endif
+

+
/* }================================================================== */
+

+

+
/*
+
** {==================================================================
+
** Macros that affect the API and must be stable (that is, must be the
+
** same when you compile Lua and when you compile code that links to
+
** Lua). You probably do not want/need to change them.
+
** =====================================================================
+
*/
+

+
/*
+
@@ LUAI_MAXSTACK limits the size of the Lua stack.
+
** CHANGE it if you need a different limit. This limit is arbitrary;
+
** its only purpose is to stop Lua from consuming unlimited stack
+
** space (and to reserve some numbers for pseudo-indices).
+
*/
+
#if LUAI_BITSINT >= 32
+
#define LUAI_MAXSTACK		1000000
+
#else
+
#define LUAI_MAXSTACK		15000
+
#endif
+

+

+
/*
+
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
+
** a Lua state with very fast access.
+
** CHANGE it if you need a different size.
+
*/
+
#define LUA_EXTRASPACE		(sizeof(void *))
+

+

+
/*
+
@@ 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
+

+

+
/*
+
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
+
** CHANGE it if it uses too much C-stack space. (For long double,
+
** 'string.format("%.99f", -1e4932)' needs 5034 bytes, so a
+
** smaller buffer would force a memory allocation for each call to
+
** 'string.format'.)
+
*/
+
#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
+
#define LUAL_BUFFERSIZE		8192
+
#else
+
#define LUAL_BUFFERSIZE   ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
+
#endif
+

+
/* }================================================================== */
+

+

+
/*
+
@@ LUA_QL describes how error messages quote program elements.
+
** Lua does not use these macros anymore; they are here for
+
** compatibility only.
+
*/
+
#define LUA_QL(x)	"'" x "'"
+
#define LUA_QS		LUA_QL("%s")
+

+

+

+

+
/* =================================================================== */
+

+
/*
+
** Local configuration. You can use this space to add your redefinitions
+
** without modifying the main part of the file.
+
*/
+

+

+

+

+

+
#endif
+

added external/lua/src/lualib.h
@@ -0,0 +1,61 @@
+
/*
+
** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Lua standard libraries
+
** See Copyright Notice in lua.h
+
*/
+

+

+
#ifndef lualib_h
+
#define lualib_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);
+

+
#define LUA_COLIBNAME	"coroutine"
+
LUAMOD_API int (luaopen_coroutine) (lua_State *L);
+

+
#define LUA_TABLIBNAME	"table"
+
LUAMOD_API int (luaopen_table) (lua_State *L);
+

+
#define LUA_IOLIBNAME	"io"
+
LUAMOD_API int (luaopen_io) (lua_State *L);
+

+
#define LUA_OSLIBNAME	"os"
+
LUAMOD_API int (luaopen_os) (lua_State *L);
+

+
#define LUA_STRLIBNAME	"string"
+
LUAMOD_API int (luaopen_string) (lua_State *L);
+

+
#define LUA_UTF8LIBNAME	"utf8"
+
LUAMOD_API int (luaopen_utf8) (lua_State *L);
+

+
#define LUA_BITLIBNAME	"bit32"
+
LUAMOD_API int (luaopen_bit32) (lua_State *L);
+

+
#define LUA_MATHLIBNAME	"math"
+
LUAMOD_API int (luaopen_math) (lua_State *L);
+

+
#define LUA_DBLIBNAME	"debug"
+
LUAMOD_API int (luaopen_debug) (lua_State *L);
+

+
#define LUA_LOADLIBNAME	"package"
+
LUAMOD_API int (luaopen_package) (lua_State *L);
+

+

+
/* open all previous libraries */
+
LUALIB_API void (luaL_openlibs) (lua_State *L);
+

+

+

+
#if !defined(lua_assert)
+
#define lua_assert(x)	((void)0)
+
#endif
+

+

+
#endif
added external/lua/src/lundump.c
@@ -0,0 +1,279 @@
+
/*
+
** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $
+
** load precompiled Lua chunks
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lundump_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lfunc.h"
+
#include "lmem.h"
+
#include "lobject.h"
+
#include "lstring.h"
+
#include "lundump.h"
+
#include "lzio.h"
+

+

+
#if !defined(luai_verifycode)
+
#define luai_verifycode(L,b,f)  /* empty */
+
#endif
+

+

+
typedef struct {
+
  lua_State *L;
+
  ZIO *Z;
+
  const char *name;
+
} LoadState;
+

+

+
static l_noret error(LoadState *S, const char *why) {
+
  luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why);
+
  luaD_throw(S->L, LUA_ERRSYNTAX);
+
}
+

+

+
/*
+
** All high-level loads go through LoadVector; you can change it to
+
** adapt to the endianness of the input
+
*/
+
#define LoadVector(S,b,n)	LoadBlock(S,b,(n)*sizeof((b)[0]))
+

+
static void LoadBlock (LoadState *S, void *b, size_t size) {
+
  if (luaZ_read(S->Z, b, size) != 0)
+
    error(S, "truncated");
+
}
+

+

+
#define LoadVar(S,x)		LoadVector(S,&x,1)
+

+

+
static lu_byte LoadByte (LoadState *S) {
+
  lu_byte x;
+
  LoadVar(S, x);
+
  return x;
+
}
+

+

+
static int LoadInt (LoadState *S) {
+
  int x;
+
  LoadVar(S, x);
+
  return x;
+
}
+

+

+
static lua_Number LoadNumber (LoadState *S) {
+
  lua_Number x;
+
  LoadVar(S, x);
+
  return x;
+
}
+

+

+
static lua_Integer LoadInteger (LoadState *S) {
+
  lua_Integer x;
+
  LoadVar(S, x);
+
  return x;
+
}
+

+

+
static TString *LoadString (LoadState *S) {
+
  size_t size = LoadByte(S);
+
  if (size == 0xFF)
+
    LoadVar(S, size);
+
  if (size == 0)
+
    return NULL;
+
  else if (--size <= LUAI_MAXSHORTLEN) {  /* short string? */
+
    char buff[LUAI_MAXSHORTLEN];
+
    LoadVector(S, buff, size);
+
    return luaS_newlstr(S->L, buff, size);
+
  }
+
  else {  /* long string */
+
    TString *ts = luaS_createlngstrobj(S->L, size);
+
    LoadVector(S, getstr(ts), size);  /* load directly in final place */
+
    return ts;
+
  }
+
}
+

+

+
static void LoadCode (LoadState *S, Proto *f) {
+
  int n = LoadInt(S);
+
  f->code = luaM_newvector(S->L, n, Instruction);
+
  f->sizecode = n;
+
  LoadVector(S, f->code, n);
+
}
+

+

+
static void LoadFunction(LoadState *S, Proto *f, TString *psource);
+

+

+
static void LoadConstants (LoadState *S, Proto *f) {
+
  int i;
+
  int n = LoadInt(S);
+
  f->k = luaM_newvector(S->L, n, TValue);
+
  f->sizek = n;
+
  for (i = 0; i < n; i++)
+
    setnilvalue(&f->k[i]);
+
  for (i = 0; i < n; i++) {
+
    TValue *o = &f->k[i];
+
    int t = LoadByte(S);
+
    switch (t) {
+
    case LUA_TNIL:
+
      setnilvalue(o);
+
      break;
+
    case LUA_TBOOLEAN:
+
      setbvalue(o, LoadByte(S));
+
      break;
+
    case LUA_TNUMFLT:
+
      setfltvalue(o, LoadNumber(S));
+
      break;
+
    case LUA_TNUMINT:
+
      setivalue(o, LoadInteger(S));
+
      break;
+
    case LUA_TSHRSTR:
+
    case LUA_TLNGSTR:
+
      setsvalue2n(S->L, o, LoadString(S));
+
      break;
+
    default:
+
      lua_assert(0);
+
    }
+
  }
+
}
+

+

+
static void LoadProtos (LoadState *S, Proto *f) {
+
  int i;
+
  int n = LoadInt(S);
+
  f->p = luaM_newvector(S->L, n, Proto *);
+
  f->sizep = n;
+
  for (i = 0; i < n; i++)
+
    f->p[i] = NULL;
+
  for (i = 0; i < n; i++) {
+
    f->p[i] = luaF_newproto(S->L);
+
    LoadFunction(S, f->p[i], f->source);
+
  }
+
}
+

+

+
static void LoadUpvalues (LoadState *S, Proto *f) {
+
  int i, n;
+
  n = LoadInt(S);
+
  f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
+
  f->sizeupvalues = n;
+
  for (i = 0; i < n; i++)
+
    f->upvalues[i].name = NULL;
+
  for (i = 0; i < n; i++) {
+
    f->upvalues[i].instack = LoadByte(S);
+
    f->upvalues[i].idx = LoadByte(S);
+
  }
+
}
+

+

+
static void LoadDebug (LoadState *S, Proto *f) {
+
  int i, n;
+
  n = LoadInt(S);
+
  f->lineinfo = luaM_newvector(S->L, n, int);
+
  f->sizelineinfo = n;
+
  LoadVector(S, f->lineinfo, n);
+
  n = LoadInt(S);
+
  f->locvars = luaM_newvector(S->L, n, LocVar);
+
  f->sizelocvars = n;
+
  for (i = 0; i < n; i++)
+
    f->locvars[i].varname = NULL;
+
  for (i = 0; i < n; i++) {
+
    f->locvars[i].varname = LoadString(S);
+
    f->locvars[i].startpc = LoadInt(S);
+
    f->locvars[i].endpc = LoadInt(S);
+
  }
+
  n = LoadInt(S);
+
  for (i = 0; i < n; i++)
+
    f->upvalues[i].name = LoadString(S);
+
}
+

+

+
static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
+
  f->source = LoadString(S);
+
  if (f->source == NULL)  /* no source in dump? */
+
    f->source = psource;  /* reuse parent's source */
+
  f->linedefined = LoadInt(S);
+
  f->lastlinedefined = LoadInt(S);
+
  f->numparams = LoadByte(S);
+
  f->is_vararg = LoadByte(S);
+
  f->maxstacksize = LoadByte(S);
+
  LoadCode(S, f);
+
  LoadConstants(S, f);
+
  LoadUpvalues(S, f);
+
  LoadProtos(S, f);
+
  LoadDebug(S, f);
+
}
+

+

+
static void checkliteral (LoadState *S, const char *s, const char *msg) {
+
  char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
+
  size_t len = strlen(s);
+
  LoadVector(S, buff, len);
+
  if (memcmp(s, buff, len) != 0)
+
    error(S, msg);
+
}
+

+

+
static void fchecksize (LoadState *S, size_t size, const char *tname) {
+
  if (LoadByte(S) != size)
+
    error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
+
}
+

+

+
#define checksize(S,t)	fchecksize(S,sizeof(t),#t)
+

+
static void checkHeader (LoadState *S) {
+
  checkliteral(S, LUA_SIGNATURE + 1, "not a");  /* 1st char already checked */
+
  if (LoadByte(S) != LUAC_VERSION)
+
    error(S, "version mismatch in");
+
  if (LoadByte(S) != LUAC_FORMAT)
+
    error(S, "format mismatch in");
+
  checkliteral(S, LUAC_DATA, "corrupted");
+
  checksize(S, int);
+
  checksize(S, size_t);
+
  checksize(S, Instruction);
+
  checksize(S, lua_Integer);
+
  checksize(S, lua_Number);
+
  if (LoadInteger(S) != LUAC_INT)
+
    error(S, "endianness mismatch in");
+
  if (LoadNumber(S) != LUAC_NUM)
+
    error(S, "float format mismatch in");
+
}
+

+

+
/*
+
** load precompiled chunk
+
*/
+
LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
+
  LoadState S;
+
  LClosure *cl;
+
  if (*name == '@' || *name == '=')
+
    S.name = name + 1;
+
  else if (*name == LUA_SIGNATURE[0])
+
    S.name = "binary string";
+
  else
+
    S.name = name;
+
  S.L = L;
+
  S.Z = Z;
+
  checkHeader(&S);
+
  cl = luaF_newLclosure(L, LoadByte(&S));
+
  setclLvalue(L, L->top, cl);
+
  luaD_inctop(L);
+
  cl->p = luaF_newproto(L);
+
  LoadFunction(&S, cl->p, NULL);
+
  lua_assert(cl->nupvalues == cl->p->sizeupvalues);
+
  luai_verifycode(L, buff, cl->p);
+
  return cl;
+
}
+

added external/lua/src/lundump.h
@@ -0,0 +1,32 @@
+
/*
+
** $Id: lundump.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
+
** load precompiled Lua chunks
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lundump_h
+
#define lundump_h
+

+
#include "llimits.h"
+
#include "lobject.h"
+
#include "lzio.h"
+

+

+
/* data to catch conversion errors */
+
#define LUAC_DATA	"\x19\x93\r\n\x1a\n"
+

+
#define LUAC_INT	0x5678
+
#define LUAC_NUM	cast_num(370.5)
+

+
#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 */
+

+
/* load one chunk; from lundump.c */
+
LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name);
+

+
/* dump one chunk; from ldump.c */
+
LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
+
                         void* data, int strip);
+

+
#endif
added external/lua/src/lutf8lib.c
@@ -0,0 +1,256 @@
+
/*
+
** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $
+
** Standard library for UTF-8 manipulation
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lutf8lib_c
+
#define LUA_LIB
+

+
#include "lprefix.h"
+

+

+
#include <assert.h>
+
#include <limits.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "lauxlib.h"
+
#include "lualib.h"
+

+
#define MAXUNICODE	0x10FFFF
+

+
#define iscont(p)	((*(p) & 0xC0) == 0x80)
+

+

+
/* from strlib */
+
/* translate a relative string position: negative means back from end */
+
static lua_Integer u_posrelat (lua_Integer pos, size_t len) {
+
  if (pos >= 0) return pos;
+
  else if (0u - (size_t)pos > len) return 0;
+
  else return (lua_Integer)len + pos + 1;
+
}
+

+

+
/*
+
** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid.
+
*/
+
static const char *utf8_decode (const char *o, int *val) {
+
  static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
+
  const unsigned char *s = (const unsigned char *)o;
+
  unsigned int c = s[0];
+
  unsigned int res = 0;  /* final result */
+
  if (c < 0x80)  /* ascii? */
+
    res = c;
+
  else {
+
    int count = 0;  /* to count number of continuation bytes */
+
    while (c & 0x40) {  /* still have continuation bytes? */
+
      int cc = s[++count];  /* read next byte */
+
      if ((cc & 0xC0) != 0x80)  /* not a continuation byte? */
+
        return NULL;  /* invalid byte sequence */
+
      res = (res << 6) | (cc & 0x3F);  /* add lower 6 bits from cont. byte */
+
      c <<= 1;  /* to test next bit */
+
    }
+
    res |= ((c & 0x7F) << (count * 5));  /* add first byte */
+
    if (count > 3 || res > MAXUNICODE || res <= limits[count])
+
      return NULL;  /* invalid byte sequence */
+
    s += count;  /* skip continuation bytes read */
+
  }
+
  if (val) *val = res;
+
  return (const char *)s + 1;  /* +1 to include first byte */
+
}
+

+

+
/*
+
** utf8len(s [, i [, j]]) --> number of characters that start in the
+
** range [i,j], or nil + current position if 's' is not well formed in
+
** that interval
+
*/
+
static int utflen (lua_State *L) {
+
  int n = 0;
+
  size_t len;
+
  const char *s = luaL_checklstring(L, 1, &len);
+
  lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len);
+
  lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len);
+
  luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2,
+
                   "initial position out of string");
+
  luaL_argcheck(L, --posj < (lua_Integer)len, 3,
+
                   "final position out of string");
+
  while (posi <= posj) {
+
    const char *s1 = utf8_decode(s + posi, NULL);
+
    if (s1 == NULL) {  /* conversion error? */
+
      lua_pushnil(L);  /* return nil ... */
+
      lua_pushinteger(L, posi + 1);  /* ... and current position */
+
      return 2;
+
    }
+
    posi = s1 - s;
+
    n++;
+
  }
+
  lua_pushinteger(L, n);
+
  return 1;
+
}
+

+

+
/*
+
** codepoint(s, [i, [j]])  -> returns codepoints for all characters
+
** that start in the range [i,j]
+
*/
+
static int codepoint (lua_State *L) {
+
  size_t len;
+
  const char *s = luaL_checklstring(L, 1, &len);
+
  lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len);
+
  lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len);
+
  int n;
+
  const char *se;
+
  luaL_argcheck(L, posi >= 1, 2, "out of range");
+
  luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range");
+
  if (posi > pose) return 0;  /* empty interval; return no values */
+
  if (pose - posi >= INT_MAX)  /* (lua_Integer -> int) overflow? */
+
    return luaL_error(L, "string slice too long");
+
  n = (int)(pose -  posi) + 1;
+
  luaL_checkstack(L, n, "string slice too long");
+
  n = 0;
+
  se = s + pose;
+
  for (s += posi - 1; s < se;) {
+
    int code;
+
    s = utf8_decode(s, &code);
+
    if (s == NULL)
+
      return luaL_error(L, "invalid UTF-8 code");
+
    lua_pushinteger(L, code);
+
    n++;
+
  }
+
  return n;
+
}
+

+

+
static void pushutfchar (lua_State *L, int arg) {
+
  lua_Integer code = luaL_checkinteger(L, arg);
+
  luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range");
+
  lua_pushfstring(L, "%U", (long)code);
+
}
+

+

+
/*
+
** utfchar(n1, n2, ...)  -> char(n1)..char(n2)...
+
*/
+
static int utfchar (lua_State *L) {
+
  int n = lua_gettop(L);  /* number of arguments */
+
  if (n == 1)  /* optimize common case of single char */
+
    pushutfchar(L, 1);
+
  else {
+
    int i;
+
    luaL_Buffer b;
+
    luaL_buffinit(L, &b);
+
    for (i = 1; i <= n; i++) {
+
      pushutfchar(L, i);
+
      luaL_addvalue(&b);
+
    }
+
    luaL_pushresult(&b);
+
  }
+
  return 1;
+
}
+

+

+
/*
+
** offset(s, n, [i])  -> index where n-th character counting from
+
**   position 'i' starts; 0 means character at 'i'.
+
*/
+
static int byteoffset (lua_State *L) {
+
  size_t len;
+
  const char *s = luaL_checklstring(L, 1, &len);
+
  lua_Integer n  = luaL_checkinteger(L, 2);
+
  lua_Integer posi = (n >= 0) ? 1 : len + 1;
+
  posi = u_posrelat(luaL_optinteger(L, 3, posi), len);
+
  luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3,
+
                   "position out of range");
+
  if (n == 0) {
+
    /* find beginning of current byte sequence */
+
    while (posi > 0 && iscont(s + posi)) posi--;
+
  }
+
  else {
+
    if (iscont(s + posi))
+
      return luaL_error(L, "initial position is a continuation byte");
+
    if (n < 0) {
+
       while (n < 0 && posi > 0) {  /* move back */
+
         do {  /* find beginning of previous character */
+
           posi--;
+
         } while (posi > 0 && iscont(s + posi));
+
         n++;
+
       }
+
     }
+
     else {
+
       n--;  /* do not move for 1st character */
+
       while (n > 0 && posi < (lua_Integer)len) {
+
         do {  /* find beginning of next character */
+
           posi++;
+
         } while (iscont(s + posi));  /* (cannot pass final '\0') */
+
         n--;
+
       }
+
     }
+
  }
+
  if (n == 0)  /* did it find given character? */
+
    lua_pushinteger(L, posi + 1);
+
  else  /* no such character */
+
    lua_pushnil(L);
+
  return 1;
+
}
+

+

+
static int iter_aux (lua_State *L) {
+
  size_t len;
+
  const char *s = luaL_checklstring(L, 1, &len);
+
  lua_Integer n = lua_tointeger(L, 2) - 1;
+
  if (n < 0)  /* first iteration? */
+
    n = 0;  /* start from here */
+
  else if (n < (lua_Integer)len) {
+
    n++;  /* skip current byte */
+
    while (iscont(s + n)) n++;  /* and its continuations */
+
  }
+
  if (n >= (lua_Integer)len)
+
    return 0;  /* no more codepoints */
+
  else {
+
    int code;
+
    const char *next = utf8_decode(s + n, &code);
+
    if (next == NULL || iscont(next))
+
      return luaL_error(L, "invalid UTF-8 code");
+
    lua_pushinteger(L, n + 1);
+
    lua_pushinteger(L, code);
+
    return 2;
+
  }
+
}
+

+

+
static int iter_codes (lua_State *L) {
+
  luaL_checkstring(L, 1);
+
  lua_pushcfunction(L, iter_aux);
+
  lua_pushvalue(L, 1);
+
  lua_pushinteger(L, 0);
+
  return 3;
+
}
+

+

+
/* pattern to match a single UTF-8 character */
+
#define UTF8PATT	"[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
+

+

+
static const luaL_Reg funcs[] = {
+
  {"offset", byteoffset},
+
  {"codepoint", codepoint},
+
  {"char", utfchar},
+
  {"len", utflen},
+
  {"codes", iter_codes},
+
  /* placeholders */
+
  {"charpattern", NULL},
+
  {NULL, NULL}
+
};
+

+

+
LUAMOD_API int luaopen_utf8 (lua_State *L) {
+
  luaL_newlib(L, funcs);
+
  lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1);
+
  lua_setfield(L, -2, "charpattern");
+
  return 1;
+
}
+

added external/lua/src/lvm.c
@@ -0,0 +1,1322 @@
+
/*
+
** $Id: lvm.c,v 2.268.1.1 2017/04/19 17:39:34 roberto Exp $
+
** Lua virtual machine
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lvm_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+
#include <float.h>
+
#include <limits.h>
+
#include <math.h>
+
#include <stdio.h>
+
#include <stdlib.h>
+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "ldebug.h"
+
#include "ldo.h"
+
#include "lfunc.h"
+
#include "lgc.h"
+
#include "lobject.h"
+
#include "lopcodes.h"
+
#include "lstate.h"
+
#include "lstring.h"
+
#include "ltable.h"
+
#include "ltm.h"
+
#include "lvm.h"
+

+

+
/* limit for table tag-method chains (to avoid loops) */
+
#define MAXTAGLOOP	2000
+

+

+

+
/*
+
** 'l_intfitsf' checks whether a given integer can be converted to a
+
** float without rounding. Used in comparisons. Left undefined if
+
** all integers fit in a float precisely.
+
*/
+
#if !defined(l_intfitsf)
+

+
/* number of bits in the mantissa of a float */
+
#define NBM		(l_mathlim(MANT_DIG))
+

+
/*
+
** Check whether some integers may not fit in a float, that is, whether
+
** (maxinteger >> NBM) > 0 (that implies (1 << NBM) <= maxinteger).
+
** (The shifts are done in parts to avoid shifting by more than the size
+
** of an integer. In a worst case, NBM == 113 for long double and
+
** sizeof(integer) == 32.)
+
*/
+
#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \
+
	>> (NBM - (3 * (NBM / 4))))  >  0
+

+
#define l_intfitsf(i)  \
+
  (-((lua_Integer)1 << NBM) <= (i) && (i) <= ((lua_Integer)1 << NBM))
+

+
#endif
+

+
#endif
+

+

+

+
/*
+
** Try to convert a value to a float. The float case is already handled
+
** by the macro 'tonumber'.
+
*/
+
int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
+
  TValue v;
+
  if (ttisinteger(obj)) {
+
    *n = cast_num(ivalue(obj));
+
    return 1;
+
  }
+
  else if (cvt2num(obj) &&  /* string convertible to number? */
+
            luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
+
    *n = nvalue(&v);  /* convert result of 'luaO_str2num' to a float */
+
    return 1;
+
  }
+
  else
+
    return 0;  /* conversion failed */
+
}
+

+

+
/*
+
** try to convert a value to an integer, rounding according to 'mode':
+
** mode == 0: accepts only integral values
+
** mode == 1: takes the floor of the number
+
** mode == 2: takes the ceil of the number
+
*/
+
int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
+
  TValue v;
+
 again:
+
  if (ttisfloat(obj)) {
+
    lua_Number n = fltvalue(obj);
+
    lua_Number f = l_floor(n);
+
    if (n != f) {  /* not an integral value? */
+
      if (mode == 0) return 0;  /* fails if mode demands integral value */
+
      else if (mode > 1)  /* needs ceil? */
+
        f += 1;  /* convert floor to ceil (remember: n != f) */
+
    }
+
    return lua_numbertointeger(f, p);
+
  }
+
  else if (ttisinteger(obj)) {
+
    *p = ivalue(obj);
+
    return 1;
+
  }
+
  else if (cvt2num(obj) &&
+
            luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
+
    obj = &v;
+
    goto again;  /* convert result from 'luaO_str2num' to an integer */
+
  }
+
  return 0;  /* conversion failed */
+
}
+

+

+
/*
+
** Try to convert a 'for' limit to an integer, preserving the
+
** semantics of the loop.
+
** (The following explanation assumes a non-negative step; it is valid
+
** for negative steps mutatis mutandis.)
+
** If the limit can be converted to an integer, rounding down, that is
+
** it.
+
** Otherwise, check whether the limit can be converted to a number.  If
+
** the number is too large, it is OK to set the limit as LUA_MAXINTEGER,
+
** which means no limit.  If the number is too negative, the loop
+
** should not run, because any initial integer value is larger than the
+
** limit. So, it sets the limit to LUA_MININTEGER. 'stopnow' corrects
+
** the extreme case when the initial value is LUA_MININTEGER, in which
+
** case the LUA_MININTEGER limit would still run the loop once.
+
*/
+
static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
+
                     int *stopnow) {
+
  *stopnow = 0;  /* usually, let loops run */
+
  if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) {  /* not fit in integer? */
+
    lua_Number n;  /* try to convert to float */
+
    if (!tonumber(obj, &n)) /* cannot convert to float? */
+
      return 0;  /* not a number */
+
    if (luai_numlt(0, n)) {  /* if true, float is larger than max integer */
+
      *p = LUA_MAXINTEGER;
+
      if (step < 0) *stopnow = 1;
+
    }
+
    else {  /* float is smaller than min integer */
+
      *p = LUA_MININTEGER;
+
      if (step >= 0) *stopnow = 1;
+
    }
+
  }
+
  return 1;
+
}
+

+

+
/*
+
** Finish the table access 'val = t[key]'.
+
** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
+
** t[k] entry (which must be nil).
+
*/
+
void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
+
                      const TValue *slot) {
+
  int loop;  /* counter to avoid infinite loops */
+
  const TValue *tm;  /* metamethod */
+
  for (loop = 0; loop < MAXTAGLOOP; loop++) {
+
    if (slot == NULL) {  /* 't' is not a table? */
+
      lua_assert(!ttistable(t));
+
      tm = luaT_gettmbyobj(L, t, TM_INDEX);
+
      if (ttisnil(tm))
+
        luaG_typeerror(L, t, "index");  /* no metamethod */
+
      /* else will try the metamethod */
+
    }
+
    else {  /* 't' is a table */
+
      lua_assert(ttisnil(slot));
+
      tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);  /* table's metamethod */
+
      if (tm == NULL) {  /* no metamethod? */
+
        setnilvalue(val);  /* result is nil */
+
        return;
+
      }
+
      /* else will try the metamethod */
+
    }
+
    if (ttisfunction(tm)) {  /* is metamethod a function? */
+
      luaT_callTM(L, tm, t, key, val, 1);  /* call it */
+
      return;
+
    }
+
    t = tm;  /* else try to access 'tm[key]' */
+
    if (luaV_fastget(L,t,key,slot,luaH_get)) {  /* fast track? */
+
      setobj2s(L, val, slot);  /* done */
+
      return;
+
    }
+
    /* else repeat (tail call 'luaV_finishget') */
+
  }
+
  luaG_runerror(L, "'__index' chain too long; possible loop");
+
}
+

+

+
/*
+
** 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;  /* '__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 metamethod */
+
    }
+
    else {  /* not a table; check metamethod */
+
      if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
+
        luaG_typeerror(L, t, "index");
+
    }
+
    /* try the metamethod */
+
    if (ttisfunction(tm)) {
+
      luaT_callTM(L, tm, t, key, val, 0);
+
      return;
+
    }
+
    t = tm;  /* else repeat assignment over 'tm' */
+
    if (luaV_fastset(L, t, key, slot, luaH_get, val))
+
      return;  /* done */
+
    /* else loop */
+
  }
+
  luaG_runerror(L, "'__newindex' chain too long; possible loop");
+
}
+

+

+
/*
+
** Compare two strings 'ls' x 'rs', returning an integer smaller-equal-
+
** -larger than zero if 'ls' is smaller-equal-larger than 'rs'.
+
** The code is a little tricky because it allows '\0' in the strings
+
** and it uses 'strcoll' (to respect locales) for each segments
+
** of the strings.
+
*/
+
static int l_strcmp (const TString *ls, const TString *rs) {
+
  const char *l = getstr(ls);
+
  size_t ll = tsslen(ls);
+
  const char *r = getstr(rs);
+
  size_t lr = tsslen(rs);
+
  for (;;) {  /* for each segment */
+
    int temp = strcoll(l, r);
+
    if (temp != 0)  /* not equal? */
+
      return temp;  /* done */
+
    else {  /* strings are equal up to a '\0' */
+
      size_t len = strlen(l);  /* index of first '\0' in both strings */
+
      if (len == lr)  /* 'rs' is finished? */
+
        return (len == ll) ? 0 : 1;  /* check 'ls' */
+
      else if (len == ll)  /* 'ls' is finished? */
+
        return -1;  /* 'ls' is smaller than 'rs' ('rs' is not finished) */
+
      /* both strings longer than 'len'; go on comparing after the '\0' */
+
      len++;
+
      l += len; ll -= len; r += len; lr -= len;
+
    }
+
  }
+
}
+

+

+
/*
+
** Check whether integer 'i' is less than float 'f'. If 'i' has an
+
** exact representation as a float ('l_intfitsf'), compare numbers as
+
** floats. Otherwise, if 'f' is outside the range for integers, result
+
** is trivial. Otherwise, compare them as integers. (When 'i' has no
+
** float representation, either 'f' is "far away" from 'i' or 'f' has
+
** no precision left for a fractional part; either way, how 'f' is
+
** truncated is irrelevant.) When 'f' is NaN, comparisons must result
+
** in false.
+
*/
+
static int LTintfloat (lua_Integer i, lua_Number f) {
+
#if defined(l_intfitsf)
+
  if (!l_intfitsf(i)) {
+
    if (f >= -cast_num(LUA_MININTEGER))  /* -minint == maxint + 1 */
+
      return 1;  /* f >= maxint + 1 > i */
+
    else if (f > cast_num(LUA_MININTEGER))  /* minint < f <= maxint ? */
+
      return (i < cast(lua_Integer, f));  /* compare them as integers */
+
    else  /* f <= minint <= i (or 'f' is NaN)  -->  not(i < f) */
+
      return 0;
+
  }
+
#endif
+
  return luai_numlt(cast_num(i), f);  /* compare them as floats */
+
}
+

+

+
/*
+
** Check whether integer 'i' is less than or equal to float 'f'.
+
** See comments on previous function.
+
*/
+
static int LEintfloat (lua_Integer i, lua_Number f) {
+
#if defined(l_intfitsf)
+
  if (!l_intfitsf(i)) {
+
    if (f >= -cast_num(LUA_MININTEGER))  /* -minint == maxint + 1 */
+
      return 1;  /* f >= maxint + 1 > i */
+
    else if (f >= cast_num(LUA_MININTEGER))  /* minint <= f <= maxint ? */
+
      return (i <= cast(lua_Integer, f));  /* compare them as integers */
+
    else  /* f < minint <= i (or 'f' is NaN)  -->  not(i <= f) */
+
      return 0;
+
  }
+
#endif
+
  return luai_numle(cast_num(i), f);  /* compare them as floats */
+
}
+

+

+
/*
+
** Return 'l < r', for numbers.
+
*/
+
static int LTnum (const TValue *l, const TValue *r) {
+
  if (ttisinteger(l)) {
+
    lua_Integer li = ivalue(l);
+
    if (ttisinteger(r))
+
      return li < ivalue(r);  /* both are integers */
+
    else  /* 'l' is int and 'r' is float */
+
      return LTintfloat(li, fltvalue(r));  /* l < r ? */
+
  }
+
  else {
+
    lua_Number lf = fltvalue(l);  /* 'l' must be float */
+
    if (ttisfloat(r))
+
      return luai_numlt(lf, fltvalue(r));  /* both are float */
+
    else if (luai_numisnan(lf))  /* 'r' is int and 'l' is float */
+
      return 0;  /* NaN < i is always false */
+
    else  /* without NaN, (l < r)  <-->  not(r <= l) */
+
      return !LEintfloat(ivalue(r), lf);  /* not (r <= l) ? */
+
  }
+
}
+

+

+
/*
+
** Return 'l <= r', for numbers.
+
*/
+
static int LEnum (const TValue *l, const TValue *r) {
+
  if (ttisinteger(l)) {
+
    lua_Integer li = ivalue(l);
+
    if (ttisinteger(r))
+
      return li <= ivalue(r);  /* both are integers */
+
    else  /* 'l' is int and 'r' is float */
+
      return LEintfloat(li, fltvalue(r));  /* l <= r ? */
+
  }
+
  else {
+
    lua_Number lf = fltvalue(l);  /* 'l' must be float */
+
    if (ttisfloat(r))
+
      return luai_numle(lf, fltvalue(r));  /* both are float */
+
    else if (luai_numisnan(lf))  /* 'r' is int and 'l' is float */
+
      return 0;  /*  NaN <= i is always false */
+
    else  /* without NaN, (l <= r)  <-->  not(r < l) */
+
      return !LTintfloat(ivalue(r), lf);  /* not (r < l) ? */
+
  }
+
}
+

+

+
/*
+
** Main operation less than; return 'l < r'.
+
*/
+
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
+
  int res;
+
  if (ttisnumber(l) && ttisnumber(r))  /* both operands are numbers? */
+
    return LTnum(l, r);
+
  else if (ttisstring(l) && ttisstring(r))  /* both are strings? */
+
    return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
+
  else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0)  /* no metamethod? */
+
    luaG_ordererror(L, l, r);  /* error */
+
  return res;
+
}
+

+

+
/*
+
** Main operation less than or equal to; return 'l <= r'. If it needs
+
** a metamethod and there is no '__le', try '__lt', based on
+
** l <= r iff !(r < l) (assuming a total order). If the metamethod
+
** yields during this substitution, the continuation has to know
+
** about it (to negate the result of r<l); bit CIST_LEQ in the call
+
** status keeps that information.
+
*/
+
int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
+
  int res;
+
  if (ttisnumber(l) && ttisnumber(r))  /* both operands are numbers? */
+
    return LEnum(l, r);
+
  else if (ttisstring(l) && ttisstring(r))  /* both are strings? */
+
    return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
+
  else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0)  /* try 'le' */
+
    return res;
+
  else {  /* try 'lt': */
+
    L->ci->callstatus |= CIST_LEQ;  /* mark it is doing 'lt' for 'le' */
+
    res = luaT_callorderTM(L, r, l, TM_LT);
+
    L->ci->callstatus ^= CIST_LEQ;  /* clear mark */
+
    if (res < 0)
+
      luaG_ordererror(L, l, r);
+
    return !res;  /* result is negated */
+
  }
+
}
+

+

+
/*
+
** Main operation for equality of Lua values; return 't1 == t2'.
+
** L == NULL means raw equality (no metamethods)
+
*/
+
int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
+
  const TValue *tm;
+
  if (ttype(t1) != ttype(t2)) {  /* not the same variant? */
+
    if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER)
+
      return 0;  /* only numbers can be equal with different variants */
+
    else {  /* two numbers with different variants */
+
      lua_Integer i1, i2;  /* compare them as integers */
+
      return (tointeger(t1, &i1) && tointeger(t2, &i2) && i1 == i2);
+
    }
+
  }
+
  /* values have same type and same variant */
+
  switch (ttype(t1)) {
+
    case LUA_TNIL: return 1;
+
    case LUA_TNUMINT: return (ivalue(t1) == ivalue(t2));
+
    case LUA_TNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2));
+
    case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
+
    case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
+
    case LUA_TLCF: return fvalue(t1) == fvalue(t2);
+
    case LUA_TSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2));
+
    case LUA_TLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2));
+
    case LUA_TUSERDATA: {
+
      if (uvalue(t1) == uvalue(t2)) return 1;
+
      else if (L == NULL) return 0;
+
      tm = fasttm(L, uvalue(t1)->metatable, TM_EQ);
+
      if (tm == NULL)
+
        tm = fasttm(L, uvalue(t2)->metatable, TM_EQ);
+
      break;  /* will try TM */
+
    }
+
    case LUA_TTABLE: {
+
      if (hvalue(t1) == hvalue(t2)) return 1;
+
      else if (L == NULL) return 0;
+
      tm = fasttm(L, hvalue(t1)->metatable, TM_EQ);
+
      if (tm == NULL)
+
        tm = fasttm(L, hvalue(t2)->metatable, TM_EQ);
+
      break;  /* will try TM */
+
    }
+
    default:
+
      return gcvalue(t1) == gcvalue(t2);
+
  }
+
  if (tm == NULL)  /* no TM? */
+
    return 0;  /* objects are different */
+
  luaT_callTM(L, tm, t1, t2, L->top, 1);  /* call TM */
+
  return !l_isfalse(L->top);
+
}
+

+

+
/* macro used by 'luaV_concat' to ensure that element at 'o' is a string */
+
#define tostring(L,o)  \
+
	(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
+

+
#define isemptystr(o)	(ttisshrstring(o) && tsvalue(o)->shrlen == 0)
+

+
/* copy strings in stack from top - n up to top - 1 to buffer */
+
static void copy2buff (StkId top, int n, char *buff) {
+
  size_t tl = 0;  /* size already copied */
+
  do {
+
    size_t l = vslen(top - n);  /* length of string being copied */
+
    memcpy(buff + tl, svalue(top - n), l * sizeof(char));
+
    tl += l;
+
  } while (--n > 0);
+
}
+

+

+
/*
+
** Main operation for concatenation: concat 'total' values in the stack,
+
** from 'L->top - total' up to 'L->top - 1'.
+
*/
+
void luaV_concat (lua_State *L, int total) {
+
  lua_assert(total >= 2);
+
  do {
+
    StkId top = L->top;
+
    int n = 2;  /* number of elements handled in this pass (at least 2) */
+
    if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
+
      luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
+
    else if (isemptystr(top - 1))  /* second operand is empty? */
+
      cast_void(tostring(L, top - 2));  /* result is first operand */
+
    else if (isemptystr(top - 2)) {  /* first operand is an empty string? */
+
      setobjs2s(L, top - 2, top - 1);  /* result is second op. */
+
    }
+
    else {
+
      /* at least two non-empty string values; get as many as possible */
+
      size_t tl = vslen(top - 1);
+
      TString *ts;
+
      /* collect total length and number of strings */
+
      for (n = 1; n < total && tostring(L, top - n - 1); n++) {
+
        size_t l = vslen(top - n - 1);
+
        if (l >= (MAX_SIZE/sizeof(char)) - tl)
+
          luaG_runerror(L, "string length overflow");
+
        tl += l;
+
      }
+
      if (tl <= LUAI_MAXSHORTLEN) {  /* is result a short string? */
+
        char buff[LUAI_MAXSHORTLEN];
+
        copy2buff(top, n, buff);  /* copy strings to buffer */
+
        ts = luaS_newlstr(L, buff, tl);
+
      }
+
      else {  /* long string; copy strings directly to final result */
+
        ts = luaS_createlngstrobj(L, tl);
+
        copy2buff(top, n, getstr(ts));
+
      }
+
      setsvalue2s(L, top - n, ts);  /* create result */
+
    }
+
    total -= n-1;  /* got 'n' strings to create 1 new */
+
    L->top -= n-1;  /* popped 'n' strings and pushed one */
+
  } while (total > 1);  /* repeat until only 1 result left */
+
}
+

+

+
/*
+
** Main operation 'ra' = #rb'.
+
*/
+
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
+
  const TValue *tm;
+
  switch (ttype(rb)) {
+
    case LUA_TTABLE: {
+
      Table *h = hvalue(rb);
+
      tm = fasttm(L, h->metatable, TM_LEN);
+
      if (tm) break;  /* metamethod? break switch to call it */
+
      setivalue(ra, luaH_getn(h));  /* else primitive len */
+
      return;
+
    }
+
    case LUA_TSHRSTR: {
+
      setivalue(ra, tsvalue(rb)->shrlen);
+
      return;
+
    }
+
    case LUA_TLNGSTR: {
+
      setivalue(ra, tsvalue(rb)->u.lnglen);
+
      return;
+
    }
+
    default: {  /* try metamethod */
+
      tm = luaT_gettmbyobj(L, rb, TM_LEN);
+
      if (ttisnil(tm))  /* no metamethod? */
+
        luaG_typeerror(L, rb, "get length of");
+
      break;
+
    }
+
  }
+
  luaT_callTM(L, tm, rb, rb, ra, 1);
+
}
+

+

+
/*
+
** Integer division; return 'm // n', that is, floor(m/n).
+
** C division truncates its result (rounds towards zero).
+
** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer,
+
** otherwise 'floor(q) == trunc(q) - 1'.
+
*/
+
lua_Integer luaV_div (lua_State *L, lua_Integer m, lua_Integer n) {
+
  if (l_castS2U(n) + 1u <= 1u) {  /* special cases: -1 or 0 */
+
    if (n == 0)
+
      luaG_runerror(L, "attempt to divide by zero");
+
    return intop(-, 0, m);   /* n==-1; avoid overflow with 0x80000...//-1 */
+
  }
+
  else {
+
    lua_Integer q = m / n;  /* perform C division */
+
    if ((m ^ n) < 0 && m % n != 0)  /* 'm/n' would be negative non-integer? */
+
      q -= 1;  /* correct result for different rounding */
+
    return q;
+
  }
+
}
+

+

+
/*
+
** Integer modulus; return 'm % n'. (Assume that C '%' with
+
** negative operands follows C99 behavior. See previous comment
+
** about luaV_div.)
+
*/
+
lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) {
+
  if (l_castS2U(n) + 1u <= 1u) {  /* special cases: -1 or 0 */
+
    if (n == 0)
+
      luaG_runerror(L, "attempt to perform 'n%%0'");
+
    return 0;   /* m % -1 == 0; avoid overflow with 0x80000...%-1 */
+
  }
+
  else {
+
    lua_Integer r = m % n;
+
    if (r != 0 && (m ^ n) < 0)  /* 'm/n' would be non-integer negative? */
+
      r += n;  /* correct result for different rounding */
+
    return r;
+
  }
+
}
+

+

+
/* number of bits in an integer */
+
#define NBITS	cast_int(sizeof(lua_Integer) * CHAR_BIT)
+

+
/*
+
** Shift left operation. (Shift right just negates 'y'.)
+
*/
+
lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
+
  if (y < 0) {  /* shift right? */
+
    if (y <= -NBITS) return 0;
+
    else return intop(>>, x, -y);
+
  }
+
  else {  /* shift left */
+
    if (y >= NBITS) return 0;
+
    else return intop(<<, x, y);
+
  }
+
}
+

+

+
/*
+
** check whether cached closure in prototype 'p' may be reused, that is,
+
** whether there is a cached closure with the same upvalues needed by
+
** new closure to be created.
+
*/
+
static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
+
  LClosure *c = p->cache;
+
  if (c != NULL) {  /* is there a cached closure? */
+
    int nup = p->sizeupvalues;
+
    Upvaldesc *uv = p->upvalues;
+
    int i;
+
    for (i = 0; i < nup; i++) {  /* check whether it has right upvalues */
+
      TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
+
      if (c->upvals[i]->v != v)
+
        return NULL;  /* wrong upvalue; cannot reuse closure */
+
    }
+
  }
+
  return c;  /* return cached closure (or NULL if no cached closure) */
+
}
+

+

+
/*
+
** create a new Lua closure, push it in the stack, and initialize
+
** its upvalues. Note that the closure is not cached if prototype is
+
** already black (which means that 'cache' was already cleared by the
+
** GC).
+
*/
+
static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
+
                         StkId ra) {
+
  int nup = p->sizeupvalues;
+
  Upvaldesc *uv = p->upvalues;
+
  int i;
+
  LClosure *ncl = luaF_newLclosure(L, nup);
+
  ncl->p = p;
+
  setclLvalue(L, ra, ncl);  /* anchor new closure in stack */
+
  for (i = 0; i < nup; i++) {  /* fill in its upvalues */
+
    if (uv[i].instack)  /* upvalue refers to local variable? */
+
      ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx);
+
    else  /* get upvalue from enclosing function */
+
      ncl->upvals[i] = encup[uv[i].idx];
+
    ncl->upvals[i]->refcount++;
+
    /* new closure is white, so we do not need a barrier here */
+
  }
+
  if (!isblack(p))  /* cache will not break GC invariant? */
+
    p->cache = ncl;  /* save it on cache for reuse */
+
}
+

+

+
/*
+
** finish execution of an opcode interrupted by an yield
+
*/
+
void luaV_finishOp (lua_State *L) {
+
  CallInfo *ci = L->ci;
+
  StkId base = ci->u.l.base;
+
  Instruction inst = *(ci->u.l.savedpc - 1);  /* interrupted instruction */
+
  OpCode op = GET_OPCODE(inst);
+
  switch (op) {  /* finish its execution */
+
    case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV:
+
    case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR:
+
    case OP_MOD: case OP_POW:
+
    case OP_UNM: case OP_BNOT: case OP_LEN:
+
    case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
+
      setobjs2s(L, base + GETARG_A(inst), --L->top);
+
      break;
+
    }
+
    case OP_LE: case OP_LT: case OP_EQ: {
+
      int res = !l_isfalse(L->top - 1);
+
      L->top--;
+
      if (ci->callstatus & CIST_LEQ) {  /* "<=" using "<" instead? */
+
        lua_assert(op == OP_LE);
+
        ci->callstatus ^= CIST_LEQ;  /* clear mark */
+
        res = !res;  /* negate result */
+
      }
+
      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
+
      if (res != GETARG_A(inst))  /* condition failed? */
+
        ci->u.l.savedpc++;  /* skip jump instruction */
+
      break;
+
    }
+
    case OP_CONCAT: {
+
      StkId top = L->top - 1;  /* top when 'luaT_trybinTM' was called */
+
      int b = GETARG_B(inst);      /* first element to concatenate */
+
      int total = cast_int(top - 1 - (base + b));  /* yet to concatenate */
+
      setobj2s(L, top - 2, top);  /* put TM result in proper position */
+
      if (total > 1) {  /* are there elements to concat? */
+
        L->top = top - 1;  /* top is one after last element (at top-2) */
+
        luaV_concat(L, total);  /* concat them (may yield again) */
+
      }
+
      /* move final result to final position */
+
      setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1);
+
      L->top = ci->top;  /* restore top */
+
      break;
+
    }
+
    case OP_TFORCALL: {
+
      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
+
      L->top = ci->top;  /* correct top */
+
      break;
+
    }
+
    case OP_CALL: {
+
      if (GETARG_C(inst) - 1 >= 0)  /* nresults >= 0? */
+
        L->top = ci->top;  /* adjust results */
+
      break;
+
    }
+
    case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
+
      break;
+
    default: lua_assert(0);
+
  }
+
}
+

+

+

+

+
/*
+
** {==================================================================
+
** Function 'luaV_execute': main interpreter loop
+
** ===================================================================
+
*/
+

+

+
/*
+
** some macros for common tasks in 'luaV_execute'
+
*/
+

+

+
#define RA(i)	(base+GETARG_A(i))
+
#define RB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
+
#define RC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
+
#define RKB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
+
	ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
+
#define RKC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
+
	ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
+

+

+
/* execute a jump instruction */
+
#define dojump(ci,i,e) \
+
  { int a = GETARG_A(i); \
+
    if (a != 0) luaF_close(L, ci->u.l.base + a - 1); \
+
    ci->u.l.savedpc += GETARG_sBx(i) + e; }
+

+
/* for test instructions, execute the jump instruction that follows it */
+
#define donextjump(ci)	{ i = *ci->u.l.savedpc; dojump(ci, i, 1); }
+

+

+
#define Protect(x)	{ {x;}; base = ci->u.l.base; }
+

+
#define checkGC(L,c)  \
+
	{ luaC_condGC(L, L->top = (c),  /* limit of live values */ \
+
                         Protect(L->top = ci->top));  /* restore top */ \
+
           luai_threadyield(L); }
+

+

+
/* fetch an instruction and prepare its execution */
+
#define vmfetch()	{ \
+
  i = *(ci->u.l.savedpc++); \
+
  if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) \
+
    Protect(luaG_traceexec(L)); \
+
  ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \
+
  lua_assert(base == ci->u.l.base); \
+
  lua_assert(base <= L->top && L->top < L->stack + L->stacksize); \
+
}
+

+
#define vmdispatch(o)	switch(o)
+
#define vmcase(l)	case l:
+
#define vmbreak		break
+

+

+
/*
+
** copy of 'luaV_gettable', but protecting the call to potential
+
** metamethod (which can reallocate the stack)
+
*/
+
#define gettableProtected(L,t,k,v)  { const TValue *slot; \
+
  if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
+
  else Protect(luaV_finishget(L,t,k,v,slot)); }
+

+

+
/* same for 'luaV_settable' */
+
#define settableProtected(L,t,k,v) { const TValue *slot; \
+
  if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
+
    Protect(luaV_finishset(L,t,k,v,slot)); }
+

+

+

+
void luaV_execute (lua_State *L) {
+
  CallInfo *ci = L->ci;
+
  LClosure *cl;
+
  TValue *k;
+
  StkId base;
+
  ci->callstatus |= CIST_FRESH;  /* fresh invocation of 'luaV_execute" */
+
 newframe:  /* reentry point when frame changes (call/return) */
+
  lua_assert(ci == L->ci);
+
  cl = clLvalue(ci->func);  /* local reference to function's closure */
+
  k = cl->p->k;  /* local reference to function's constant table */
+
  base = ci->u.l.base;  /* local copy of function's base */
+
  /* main loop of interpreter */
+
  for (;;) {
+
    Instruction i;
+
    StkId ra;
+
    vmfetch();
+
    vmdispatch (GET_OPCODE(i)) {
+
      vmcase(OP_MOVE) {
+
        setobjs2s(L, ra, RB(i));
+
        vmbreak;
+
      }
+
      vmcase(OP_LOADK) {
+
        TValue *rb = k + GETARG_Bx(i);
+
        setobj2s(L, ra, rb);
+
        vmbreak;
+
      }
+
      vmcase(OP_LOADKX) {
+
        TValue *rb;
+
        lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
+
        rb = k + GETARG_Ax(*ci->u.l.savedpc++);
+
        setobj2s(L, ra, rb);
+
        vmbreak;
+
      }
+
      vmcase(OP_LOADBOOL) {
+
        setbvalue(ra, GETARG_B(i));
+
        if (GETARG_C(i)) ci->u.l.savedpc++;  /* skip next instruction (if C) */
+
        vmbreak;
+
      }
+
      vmcase(OP_LOADNIL) {
+
        int b = GETARG_B(i);
+
        do {
+
          setnilvalue(ra++);
+
        } while (b--);
+
        vmbreak;
+
      }
+
      vmcase(OP_GETUPVAL) {
+
        int b = GETARG_B(i);
+
        setobj2s(L, ra, cl->upvals[b]->v);
+
        vmbreak;
+
      }
+
      vmcase(OP_GETTABUP) {
+
        TValue *upval = cl->upvals[GETARG_B(i)]->v;
+
        TValue *rc = RKC(i);
+
        gettableProtected(L, upval, rc, ra);
+
        vmbreak;
+
      }
+
      vmcase(OP_GETTABLE) {
+
        StkId rb = RB(i);
+
        TValue *rc = RKC(i);
+
        gettableProtected(L, rb, rc, ra);
+
        vmbreak;
+
      }
+
      vmcase(OP_SETTABUP) {
+
        TValue *upval = cl->upvals[GETARG_A(i)]->v;
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        settableProtected(L, upval, rb, rc);
+
        vmbreak;
+
      }
+
      vmcase(OP_SETUPVAL) {
+
        UpVal *uv = cl->upvals[GETARG_B(i)];
+
        setobj(L, uv->v, ra);
+
        luaC_upvalbarrier(L, uv);
+
        vmbreak;
+
      }
+
      vmcase(OP_SETTABLE) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        settableProtected(L, ra, rb, rc);
+
        vmbreak;
+
      }
+
      vmcase(OP_NEWTABLE) {
+
        int b = GETARG_B(i);
+
        int c = GETARG_C(i);
+
        Table *t = luaH_new(L);
+
        sethvalue(L, ra, t);
+
        if (b != 0 || c != 0)
+
          luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
+
        checkGC(L, ra + 1);
+
        vmbreak;
+
      }
+
      vmcase(OP_SELF) {
+
        const TValue *aux;
+
        StkId rb = RB(i);
+
        TValue *rc = RKC(i);
+
        TString *key = tsvalue(rc);  /* key must be a string */
+
        setobjs2s(L, ra + 1, rb);
+
        if (luaV_fastget(L, rb, key, aux, luaH_getstr)) {
+
          setobj2s(L, ra, aux);
+
        }
+
        else Protect(luaV_finishget(L, rb, rc, ra, aux));
+
        vmbreak;
+
      }
+
      vmcase(OP_ADD) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Number nb; lua_Number nc;
+
        if (ttisinteger(rb) && ttisinteger(rc)) {
+
          lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
+
          setivalue(ra, intop(+, ib, ic));
+
        }
+
        else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+
          setfltvalue(ra, luai_numadd(L, nb, nc));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_SUB) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Number nb; lua_Number nc;
+
        if (ttisinteger(rb) && ttisinteger(rc)) {
+
          lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
+
          setivalue(ra, intop(-, ib, ic));
+
        }
+
        else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+
          setfltvalue(ra, luai_numsub(L, nb, nc));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_MUL) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Number nb; lua_Number nc;
+
        if (ttisinteger(rb) && ttisinteger(rc)) {
+
          lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
+
          setivalue(ra, intop(*, ib, ic));
+
        }
+
        else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+
          setfltvalue(ra, luai_nummul(L, nb, nc));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_DIV) {  /* float division (always with floats) */
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Number nb; lua_Number nc;
+
        if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+
          setfltvalue(ra, luai_numdiv(L, nb, nc));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_BAND) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Integer ib; lua_Integer ic;
+
        if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
+
          setivalue(ra, intop(&, ib, ic));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_BOR) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Integer ib; lua_Integer ic;
+
        if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
+
          setivalue(ra, intop(|, ib, ic));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_BXOR) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Integer ib; lua_Integer ic;
+
        if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
+
          setivalue(ra, intop(^, ib, ic));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_SHL) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Integer ib; lua_Integer ic;
+
        if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
+
          setivalue(ra, luaV_shiftl(ib, ic));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_SHR) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Integer ib; lua_Integer ic;
+
        if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
+
          setivalue(ra, luaV_shiftl(ib, -ic));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_MOD) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Number nb; lua_Number nc;
+
        if (ttisinteger(rb) && ttisinteger(rc)) {
+
          lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
+
          setivalue(ra, luaV_mod(L, ib, ic));
+
        }
+
        else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+
          lua_Number m;
+
          luai_nummod(L, nb, nc, m);
+
          setfltvalue(ra, m);
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_IDIV) {  /* floor division */
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Number nb; lua_Number nc;
+
        if (ttisinteger(rb) && ttisinteger(rc)) {
+
          lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
+
          setivalue(ra, luaV_div(L, ib, ic));
+
        }
+
        else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+
          setfltvalue(ra, luai_numidiv(L, nb, nc));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_POW) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        lua_Number nb; lua_Number nc;
+
        if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+
          setfltvalue(ra, luai_numpow(L, nb, nc));
+
        }
+
        else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); }
+
        vmbreak;
+
      }
+
      vmcase(OP_UNM) {
+
        TValue *rb = RB(i);
+
        lua_Number nb;
+
        if (ttisinteger(rb)) {
+
          lua_Integer ib = ivalue(rb);
+
          setivalue(ra, intop(-, 0, ib));
+
        }
+
        else if (tonumber(rb, &nb)) {
+
          setfltvalue(ra, luai_numunm(L, nb));
+
        }
+
        else {
+
          Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM));
+
        }
+
        vmbreak;
+
      }
+
      vmcase(OP_BNOT) {
+
        TValue *rb = RB(i);
+
        lua_Integer ib;
+
        if (tointeger(rb, &ib)) {
+
          setivalue(ra, intop(^, ~l_castS2U(0), ib));
+
        }
+
        else {
+
          Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT));
+
        }
+
        vmbreak;
+
      }
+
      vmcase(OP_NOT) {
+
        TValue *rb = RB(i);
+
        int res = l_isfalse(rb);  /* next assignment may change this value */
+
        setbvalue(ra, res);
+
        vmbreak;
+
      }
+
      vmcase(OP_LEN) {
+
        Protect(luaV_objlen(L, ra, RB(i)));
+
        vmbreak;
+
      }
+
      vmcase(OP_CONCAT) {
+
        int b = GETARG_B(i);
+
        int c = GETARG_C(i);
+
        StkId rb;
+
        L->top = base + c + 1;  /* mark the end of concat operands */
+
        Protect(luaV_concat(L, c - b + 1));
+
        ra = RA(i);  /* 'luaV_concat' may invoke TMs and move the stack */
+
        rb = base + b;
+
        setobjs2s(L, ra, rb);
+
        checkGC(L, (ra >= rb ? ra + 1 : rb));
+
        L->top = ci->top;  /* restore top */
+
        vmbreak;
+
      }
+
      vmcase(OP_JMP) {
+
        dojump(ci, i, 0);
+
        vmbreak;
+
      }
+
      vmcase(OP_EQ) {
+
        TValue *rb = RKB(i);
+
        TValue *rc = RKC(i);
+
        Protect(
+
          if (luaV_equalobj(L, rb, rc) != GETARG_A(i))
+
            ci->u.l.savedpc++;
+
          else
+
            donextjump(ci);
+
        )
+
        vmbreak;
+
      }
+
      vmcase(OP_LT) {
+
        Protect(
+
          if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i))
+
            ci->u.l.savedpc++;
+
          else
+
            donextjump(ci);
+
        )
+
        vmbreak;
+
      }
+
      vmcase(OP_LE) {
+
        Protect(
+
          if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i))
+
            ci->u.l.savedpc++;
+
          else
+
            donextjump(ci);
+
        )
+
        vmbreak;
+
      }
+
      vmcase(OP_TEST) {
+
        if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra))
+
            ci->u.l.savedpc++;
+
          else
+
          donextjump(ci);
+
        vmbreak;
+
      }
+
      vmcase(OP_TESTSET) {
+
        TValue *rb = RB(i);
+
        if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb))
+
          ci->u.l.savedpc++;
+
        else {
+
          setobjs2s(L, ra, rb);
+
          donextjump(ci);
+
        }
+
        vmbreak;
+
      }
+
      vmcase(OP_CALL) {
+
        int b = GETARG_B(i);
+
        int nresults = GETARG_C(i) - 1;
+
        if (b != 0) L->top = ra+b;  /* else previous instruction set top */
+
        if (luaD_precall(L, ra, nresults)) {  /* C function? */
+
          if (nresults >= 0)
+
            L->top = ci->top;  /* adjust results */
+
          Protect((void)0);  /* update 'base' */
+
        }
+
        else {  /* Lua function */
+
          ci = L->ci;
+
          goto newframe;  /* restart luaV_execute over new Lua function */
+
        }
+
        vmbreak;
+
      }
+
      vmcase(OP_TAILCALL) {
+
        int b = GETARG_B(i);
+
        if (b != 0) L->top = ra+b;  /* else previous instruction set top */
+
        lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
+
        if (luaD_precall(L, ra, LUA_MULTRET)) {  /* C function? */
+
          Protect((void)0);  /* update 'base' */
+
        }
+
        else {
+
          /* tail call: put called frame (n) in place of caller one (o) */
+
          CallInfo *nci = L->ci;  /* called frame */
+
          CallInfo *oci = nci->previous;  /* caller frame */
+
          StkId nfunc = nci->func;  /* called function */
+
          StkId ofunc = oci->func;  /* caller function */
+
          /* last stack slot filled by 'precall' */
+
          StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
+
          int aux;
+
          /* close all upvalues from previous call */
+
          if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
+
          /* move new frame into old one */
+
          for (aux = 0; nfunc + aux < lim; aux++)
+
            setobjs2s(L, ofunc + aux, nfunc + aux);
+
          oci->u.l.base = ofunc + (nci->u.l.base - nfunc);  /* correct base */
+
          oci->top = L->top = ofunc + (L->top - nfunc);  /* correct top */
+
          oci->u.l.savedpc = nci->u.l.savedpc;
+
          oci->callstatus |= CIST_TAIL;  /* function was tail called */
+
          ci = L->ci = oci;  /* remove new frame */
+
          lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
+
          goto newframe;  /* restart luaV_execute over new Lua function */
+
        }
+
        vmbreak;
+
      }
+
      vmcase(OP_RETURN) {
+
        int b = GETARG_B(i);
+
        if (cl->p->sizep > 0) luaF_close(L, base);
+
        b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
+
        if (ci->callstatus & CIST_FRESH)  /* local 'ci' still from callee */
+
          return;  /* external invocation: return */
+
        else {  /* invocation via reentry: continue execution */
+
          ci = L->ci;
+
          if (b) L->top = ci->top;
+
          lua_assert(isLua(ci));
+
          lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
+
          goto newframe;  /* restart luaV_execute over new Lua function */
+
        }
+
      }
+
      vmcase(OP_FORLOOP) {
+
        if (ttisinteger(ra)) {  /* integer loop? */
+
          lua_Integer step = ivalue(ra + 2);
+
          lua_Integer idx = intop(+, ivalue(ra), step); /* increment index */
+
          lua_Integer limit = ivalue(ra + 1);
+
          if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
+
            ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
+
            chgivalue(ra, idx);  /* update internal index... */
+
            setivalue(ra + 3, idx);  /* ...and external index */
+
          }
+
        }
+
        else {  /* floating loop */
+
          lua_Number step = fltvalue(ra + 2);
+
          lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */
+
          lua_Number limit = fltvalue(ra + 1);
+
          if (luai_numlt(0, step) ? luai_numle(idx, limit)
+
                                  : luai_numle(limit, idx)) {
+
            ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
+
            chgfltvalue(ra, idx);  /* update internal index... */
+
            setfltvalue(ra + 3, idx);  /* ...and external index */
+
          }
+
        }
+
        vmbreak;
+
      }
+
      vmcase(OP_FORPREP) {
+
        TValue *init = ra;
+
        TValue *plimit = ra + 1;
+
        TValue *pstep = ra + 2;
+
        lua_Integer ilimit;
+
        int stopnow;
+
        if (ttisinteger(init) && ttisinteger(pstep) &&
+
            forlimit(plimit, &ilimit, ivalue(pstep), &stopnow)) {
+
          /* all values are integer */
+
          lua_Integer initv = (stopnow ? 0 : ivalue(init));
+
          setivalue(plimit, ilimit);
+
          setivalue(init, intop(-, initv, ivalue(pstep)));
+
        }
+
        else {  /* try making all values floats */
+
          lua_Number ninit; lua_Number nlimit; lua_Number nstep;
+
          if (!tonumber(plimit, &nlimit))
+
            luaG_runerror(L, "'for' limit must be a number");
+
          setfltvalue(plimit, nlimit);
+
          if (!tonumber(pstep, &nstep))
+
            luaG_runerror(L, "'for' step must be a number");
+
          setfltvalue(pstep, nstep);
+
          if (!tonumber(init, &ninit))
+
            luaG_runerror(L, "'for' initial value must be a number");
+
          setfltvalue(init, luai_numsub(L, ninit, nstep));
+
        }
+
        ci->u.l.savedpc += GETARG_sBx(i);
+
        vmbreak;
+
      }
+
      vmcase(OP_TFORCALL) {
+
        StkId cb = ra + 3;  /* call base */
+
        setobjs2s(L, cb+2, ra+2);
+
        setobjs2s(L, cb+1, ra+1);
+
        setobjs2s(L, cb, ra);
+
        L->top = cb + 3;  /* func. + 2 args (state and index) */
+
        Protect(luaD_call(L, cb, GETARG_C(i)));
+
        L->top = ci->top;
+
        i = *(ci->u.l.savedpc++);  /* go to next instruction */
+
        ra = RA(i);
+
        lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
+
        goto l_tforloop;
+
      }
+
      vmcase(OP_TFORLOOP) {
+
        l_tforloop:
+
        if (!ttisnil(ra + 1)) {  /* continue loop? */
+
          setobjs2s(L, ra, ra + 1);  /* save control variable */
+
           ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
+
        }
+
        vmbreak;
+
      }
+
      vmcase(OP_SETLIST) {
+
        int n = GETARG_B(i);
+
        int c = GETARG_C(i);
+
        unsigned int last;
+
        Table *h;
+
        if (n == 0) n = cast_int(L->top - ra) - 1;
+
        if (c == 0) {
+
          lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
+
          c = GETARG_Ax(*ci->u.l.savedpc++);
+
        }
+
        h = hvalue(ra);
+
        last = ((c-1)*LFIELDS_PER_FLUSH) + n;
+
        if (last > h->sizearray)  /* needs more space? */
+
          luaH_resizearray(L, h, last);  /* preallocate it at once */
+
        for (; n > 0; n--) {
+
          TValue *val = ra+n;
+
          luaH_setint(L, h, last--, val);
+
          luaC_barrierback(L, h, val);
+
        }
+
        L->top = ci->top;  /* correct top (in case of previous open call) */
+
        vmbreak;
+
      }
+
      vmcase(OP_CLOSURE) {
+
        Proto *p = cl->p->p[GETARG_Bx(i)];
+
        LClosure *ncl = getcached(p, cl->upvals, base);  /* cached closure */
+
        if (ncl == NULL)  /* no match? */
+
          pushclosure(L, p, cl->upvals, base, ra);  /* create a new one */
+
        else
+
          setclLvalue(L, ra, ncl);  /* push cashed closure */
+
        checkGC(L, ra + 1);
+
        vmbreak;
+
      }
+
      vmcase(OP_VARARG) {
+
        int b = GETARG_B(i) - 1;  /* required results */
+
        int j;
+
        int n = cast_int(base - ci->func) - cl->p->numparams - 1;
+
        if (n < 0)  /* less arguments than parameters? */
+
          n = 0;  /* no vararg arguments */
+
        if (b < 0) {  /* B == 0? */
+
          b = n;  /* get all var. arguments */
+
          Protect(luaD_checkstack(L, n));
+
          ra = RA(i);  /* previous call may change the stack */
+
          L->top = ra + n;
+
        }
+
        for (j = 0; j < b && j < n; j++)
+
          setobjs2s(L, ra + j, base - n + j);
+
        for (; j < b; j++)  /* complete required results with nil */
+
          setnilvalue(ra + j);
+
        vmbreak;
+
      }
+
      vmcase(OP_EXTRAARG) {
+
        lua_assert(0);
+
        vmbreak;
+
      }
+
    }
+
  }
+
}
+

+
/* }================================================================== */
+

added external/lua/src/lvm.h
@@ -0,0 +1,113 @@
+
/*
+
** $Id: lvm.h,v 2.41.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Lua virtual machine
+
** See Copyright Notice in lua.h
+
*/
+

+
#ifndef lvm_h
+
#define lvm_h
+

+

+
#include "ldo.h"
+
#include "lobject.h"
+
#include "ltm.h"
+

+

+
#if !defined(LUA_NOCVTN2S)
+
#define cvt2str(o)	ttisnumber(o)
+
#else
+
#define cvt2str(o)	0	/* no conversion from numbers to strings */
+
#endif
+

+

+
#if !defined(LUA_NOCVTS2N)
+
#define cvt2num(o)	ttisstring(o)
+
#else
+
#define cvt2num(o)	0	/* no conversion from strings to numbers */
+
#endif
+

+

+
/*
+
** You can define LUA_FLOORN2I if you want to convert floats to integers
+
** by flooring them (instead of raising an error if they are not
+
** integral values)
+
*/
+
#if !defined(LUA_FLOORN2I)
+
#define LUA_FLOORN2I		0
+
#endif
+

+

+
#define tonumber(o,n) \
+
	(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
+

+
#define tointeger(o,i) \
+
    (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))
+

+
#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
+

+
#define luaV_rawequalobj(t1,t2)		luaV_equalobj(NULL,t1,t2)
+

+

+
/*
+
** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
+
** return 1 with 'slot' pointing to 't[k]' (final result).  Otherwise,
+
** return 0 (meaning it will have to check metamethod) with 'slot'
+
** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
+
** 'f' is the raw get function to use.
+
*/
+
#define luaV_fastget(L,t,k,slot,f) \
+
  (!ttistable(t)  \
+
   ? (slot = NULL, 0)  /* not a table; 'slot' is NULL and result is 0 */  \
+
   : (slot = f(hvalue(t), k),  /* else, do raw access */  \
+
      !ttisnil(slot)))  /* result not nil? */
+

+
/*
+
** standard implementation for 'gettable'
+
*/
+
#define luaV_gettable(L,t,k,v) { const TValue *slot; \
+
  if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
+
  else luaV_finishget(L,t,k,v,slot); }
+

+

+
/*
+
** Fast track for set table. If 't' is a table and 't[k]' is not nil,
+
** call GC barrier, do a raw 't[k]=v', and return true; otherwise,
+
** return false with 'slot' equal to NULL (if 't' is not a table) or
+
** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro
+
** returns true, there is no need to 'invalidateTMcache', because the
+
** call is not creating a new entry.
+
*/
+
#define luaV_fastset(L,t,k,slot,f,v) \
+
  (!ttistable(t) \
+
   ? (slot = NULL, 0) \
+
   : (slot = f(hvalue(t), k), \
+
     ttisnil(slot) ? 0 \
+
     : (luaC_barrierback(L, hvalue(t), v), \
+
        setobj2t(L, cast(TValue *,slot), v), \
+
        1)))
+

+

+
#define luaV_settable(L,t,k,v) { const TValue *slot; \
+
  if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
+
    luaV_finishset(L,t,k,v,slot); }
+

+

+

+
LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
+
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
+
LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
+
LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
+
LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
+
LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
+
                               StkId val, const TValue *slot);
+
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
+
                               StkId val, const TValue *slot);
+
LUAI_FUNC void luaV_finishOp (lua_State *L);
+
LUAI_FUNC void luaV_execute (lua_State *L);
+
LUAI_FUNC void luaV_concat (lua_State *L, int total);
+
LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
+
LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
+
LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
+
LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
+

+
#endif
added external/lua/src/lzio.c
@@ -0,0 +1,68 @@
+
/*
+
** $Id: lzio.c,v 1.37.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Buffered streams
+
** See Copyright Notice in lua.h
+
*/
+

+
#define lzio_c
+
#define LUA_CORE
+

+
#include "lprefix.h"
+

+

+
#include <string.h>
+

+
#include "lua.h"
+

+
#include "llimits.h"
+
#include "lmem.h"
+
#include "lstate.h"
+
#include "lzio.h"
+

+

+
int luaZ_fill (ZIO *z) {
+
  size_t size;
+
  lua_State *L = z->L;
+
  const char *buff;
+
  lua_unlock(L);
+
  buff = z->reader(L, z->data, &size);
+
  lua_lock(L);
+
  if (buff == NULL || size == 0)
+
    return EOZ;
+
  z->n = size - 1;  /* discount char being returned */
+
  z->p = buff;
+
  return cast_uchar(*(z->p++));
+
}
+

+

+
void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
+
  z->L = L;
+
  z->reader = reader;
+
  z->data = data;
+
  z->n = 0;
+
  z->p = NULL;
+
}
+

+

+
/* --------------------------------------------------------------- read --- */
+
size_t luaZ_read (ZIO *z, void *b, size_t n) {
+
  while (n) {
+
    size_t m;
+
    if (z->n == 0) {  /* no bytes in buffer? */
+
      if (luaZ_fill(z) == EOZ)  /* try to read more */
+
        return n;  /* no more input; return number of missing bytes */
+
      else {
+
        z->n++;  /* luaZ_fill consumed first byte; put it back */
+
        z->p--;
+
      }
+
    }
+
    m = (n <= z->n) ? n : z->n;  /* min. between n and z->n */
+
    memcpy(b, z->p, m);
+
    z->n -= m;
+
    z->p += m;
+
    b = (char *)b + m;
+
    n -= m;
+
  }
+
  return 0;
+
}
+

added external/lua/src/lzio.h
@@ -0,0 +1,66 @@
+
/*
+
** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $
+
** Buffered streams
+
** See Copyright Notice in lua.h
+
*/
+

+

+
#ifndef lzio_h
+
#define lzio_h
+

+
#include "lua.h"
+

+
#include "lmem.h"
+

+

+
#define EOZ	(-1)			/* end of stream */
+

+
typedef struct Zio ZIO;
+

+
#define zgetc(z)  (((z)->n--)>0 ?  cast_uchar(*(z)->p++) : luaZ_fill(z))
+

+

+
typedef struct Mbuffer {
+
  char *buffer;
+
  size_t n;
+
  size_t buffsize;
+
} Mbuffer;
+

+
#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
+

+
#define luaZ_buffer(buff)	((buff)->buffer)
+
#define luaZ_sizebuffer(buff)	((buff)->buffsize)
+
#define luaZ_bufflen(buff)	((buff)->n)
+

+
#define luaZ_buffremove(buff,i)	((buff)->n -= (i))
+
#define luaZ_resetbuffer(buff) ((buff)->n = 0)
+

+

+
#define luaZ_resizebuffer(L, buff, size) \
+
	((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \
+
				(buff)->buffsize, size), \
+
	(buff)->buffsize = size)
+

+
#define luaZ_freebuffer(L, buff)	luaZ_resizebuffer(L, buff, 0)
+

+

+
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
+
                                        void *data);
+
LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n);	/* read next n bytes */
+

+

+

+
/* --------- Private Part ------------------ */
+

+
struct Zio {
+
  size_t n;			/* bytes still unread */
+
  const char *p;		/* current position in buffer */
+
  lua_Reader reader;		/* reader function */
+
  void *data;			/* additional data */
+
  lua_State *L;			/* Lua state (for reader) */
+
};
+

+

+
LUAI_FUNC int luaZ_fill (ZIO *z);
+

+
#endif
modified libpkg/Makefile.autosetup
@@ -50,6 +50,7 @@ LOCAL_CFLAGS= -I$(top_srcdir)/compat \
		-I$(top_srcdir)/external/libucl/include \
		-I$(top_srcdir)/external/libucl/klib \
		-I$(top_srcdir)/external/libfetch \
+
		-I$(top_srcdir)/external/lua/src \
		-I$(top_srcdir)/libpkg/repo \
		-I$(top_srcdir)/libpkg \
		-I$(top_srcdir) \
@@ -69,6 +70,7 @@ LOCAL_LDFLAGS= @waflags@ \
		-L$(top_builddir)/external/blake2 -lblake2_pic \
		-L$(top_builddir)/compat -lbsd_compat_pic \
		-L$(top_builddir)/external/libfetch -lfetch_pic \
+
		-L$(top_builddir)/external/liblua -llua_pic \
		@nowaflags@ \
		-lssl \
		-lcrypto \
@@ -81,6 +83,7 @@ STATIC_LIBS= @REPOS_STATIC_LIBS@ \
		$(top_builddir)/external/linenoise/liblinenoise.a \
		$(top_builddir)/external/expat/libexpat.a \
		$(top_builddir)/external/blake2/libblake2.a \
+
		$(top_builddir)/external/liblua/liblua.a \
		$(top_builddir)/compat/libbsd_compat.a \
		$(top_builddir)/external/libfetch/libfetch.a \
		lib$(LIB).a
modified libpkg/pkg_ports.c
@@ -110,6 +110,12 @@ keyword_open_schema(void)
		"    post-deinstall = { type = string }; "
		"    pre-upgrade = { type = string }; "
		"    post-upgrade = { type = string }; "
+
		"    pre-install-lua = { type = string }; "
+
		"    post-install-lua = { type = string }; "
+
		"    pre-deinstall-lua = { type = string }; "
+
		"    post-deinstall-lua = { type = string }; "
+
		"    pre-upgrade-lua = { type = string }; "
+
		"    post-upgrade-lua = { type = string }; "
		"    messages: {"
		"        type = array; "
		"        items = {"