Feature #1566 ยป 0068-Add-copy-of-lua-5.5-under-version-control.patch
dependencies/lua-5.5/README | ||
---|---|---|
This is Lua 5.5.0 (beta), released on 28 Jun 2025.
|
||
For installation instructions, license details, and
|
||
further information about Lua, see doc/readme.html.
|
||
dependencies/lua-5.5/Version.txt | ||
---|---|---|
Sources here are from lua-5.5.0-beta
|
||
(http://www.lua.org/ftp/lua-5.5.0-beta.tar.gz)
|
||
Upstream bug fixes from https://www.lua.org/bugs.html applied:
|
||
Not entire lua distribution directory hierarchy is included here, and
|
||
some files needed for Freeciv usage have been added.
|
||
Changes applied to included lua source files are included in freeciv_lua.patch
|
dependencies/lua-5.5/doc/readme.html | ||
---|---|---|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
<HTML>
|
||
<HEAD>
|
||
<TITLE>Lua 5.5 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="https://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
|
||
Welcome to Lua 5.5
|
||
</H1>
|
||
<DIV CLASS="menubar">
|
||
<A HREF="#about">about</A>
|
||
·
|
||
<A HREF="#install">installation</A>
|
||
·
|
||
<A HREF="#changes">changes</A>
|
||
·
|
||
<A HREF="#license">license</A>
|
||
·
|
||
<A HREF="contents.html">reference manual</A>
|
||
</DIV>
|
||
<H2><A NAME="about">About Lua</A></H2>
|
||
<P>
|
||
Lua is a powerful, efficient, lightweight, embeddable scripting language
|
||
developed by a
|
||
<A HREF="https://www.lua.org/authors.html">team</A>
|
||
at
|
||
<A HREF="https://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
|
||
<A HREF="https://www.lua.org/uses.html">many products and projects</A>
|
||
around the world.
|
||
<P>
|
||
Lua's
|
||
<A HREF="https://www.lua.org/">official website</A>
|
||
provides complete information
|
||
about Lua,
|
||
including
|
||
an
|
||
<A HREF="https://www.lua.org/about.html">executive summary</A>,
|
||
tips on
|
||
<A HREF="https://www.lua.org/start.html">getting started</A>,
|
||
and
|
||
updated
|
||
<A HREF="https://www.lua.org/docs.html">documentation</A>,
|
||
especially the
|
||
<A HREF="https://www.lua.org/manual/5.5/">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="https://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,
|
||
such as Linux and macOS.
|
||
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="https://luabinaries.sourceforge.net">LuaBinaries</A>.
|
||
<H3>Building Lua</H3>
|
||
<P>
|
||
In most common Unix-like platforms, simply do "<KBD>make</KBD>".
|
||
Here are the details.
|
||
<OL>
|
||
<LI>
|
||
Open a terminal window and move to
|
||
the top-level directory, which is named <TT>lua-5.5.0</TT>.
|
||
The <TT>Makefile</TT> there controls both the build process and the installation process.
|
||
<P>
|
||
<LI>
|
||
Do "<KBD>make</KBD>". The <TT>Makefile</TT> will guess your platform and build Lua for it.
|
||
<P>
|
||
<LI>
|
||
If the guess failed, do "<KBD>make help</KBD>" and see if your platform is listed.
|
||
The platforms currently supported are:
|
||
<P>
|
||
<P CLASS="display">
|
||
guess aix bsd c89 freebsd generic ios 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>
|
||
<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, and so may need to do "<KBD>sudo make install</KBD>".
|
||
<P>
|
||
To build and install Lua in one step, do "<KBD>make all install</KBD>",
|
||
or "<KBD>make xxx install</KBD>",
|
||
where xxx is your platform name.
|
||
<P>
|
||
To install Lua locally after building it, 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 — edit <TT>Makefile</TT>.
|
||
<LI> How to build Lua — edit <TT>src/Makefile</TT>.
|
||
<LI> Lua features — 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,
|
||
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 lcorolib.c ldblib.c liolib.c lmathlib.c loadlib.c loslib.c lstrlib.c ltablib.c lutf8lib.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 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 — 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.4</A></H2>
|
||
<P>
|
||
Here are the main changes introduced in Lua 5.5.
|
||
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> declarations for global variables
|
||
<LI> for-loop variables are read only
|
||
<LI> floats are printed in decimal with enough digits to be read back correctly.
|
||
<LI> more levels for constructors
|
||
<LI> table.create
|
||
<LI> utf8.offset returns also final position of character
|
||
<LI> external strings (that use memory not managed by Lua)
|
||
<LI> new functions luaL_openselectedlibs and luaL_makeseed
|
||
<LI> major collections done incrementally
|
||
<LI> more compact arrays (large arrays use about 60% less memory)
|
||
<LI> lua.c loads 'readline' dynamically
|
||
<LI> static (fixed) binaries (when loading a binary chunk in memory, Lua can reuse its original memory in some of the internal structures)
|
||
<LI> dump and undump reuse all strings
|
||
<LI> auxiliary buffer reuses buffer when it creates final string
|
||
</UL>
|
||
<H2><A NAME="license">License</A></H2>
|
||
<P>
|
||
<A HREF="https://opensource.org/osd">
|
||
<IMG SRC="OSIApproved_100X125.png" ALIGN="right" ALT="[Open Source Initiative Approved License]" STYLE="padding-left: 1em" WIDTH=50>
|
||
</A>
|
||
Lua is free software distributed under the terms of the
|
||
<A HREF="https://opensource.org/license/mit">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 the
|
||
<A HREF="https://www.lua.org/license.html">license page</A>.
|
||
<BLOCKQUOTE STYLE="padding-bottom: 0em">
|
||
Copyright © 1994–2025 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:
|
||
Thu Jun 26 13:06:11 UTC 2025
|
||
</P>
|
||
<!--
|
||
Last change: revised for Lua 5.5.0
|
||
-->
|
||
</BODY>
|
||
</HTML>
|
dependencies/lua-5.5/freeciv_lua.patch | ||
---|---|---|
diff -Nurd lua-5.5/src/ldo.c lua-5.5/src/ldo.c
|
||
--- lua-5.5/src/ldo.c 2025-07-05 05:37:52.108553768 +0300
|
||
+++ lua-5.5/src/ldo.c 2025-07-05 05:40:32.053318937 +0300
|
||
@@ -73,7 +73,7 @@
|
||
try { (f)(L, ud); } catch(...) { if ((c)->status == 0) (c)->status = -1; }
|
||
#define luai_jmpbuf int /* dummy field */
|
||
|
||
-#elif defined(LUA_USE_POSIX) /* }{ */
|
||
+#elif defined(LUA_USE_ULONGJMP) /* }{ */
|
||
|
||
/* in POSIX, try _longjmp/_setjmp (more efficient) */
|
||
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
|
||
@@ -133,9 +133,9 @@
|
||
lua_unlock(L);
|
||
g->panic(L); /* call panic function (last chance to jump out) */
|
||
}
|
||
- abort();
|
||
}
|
||
}
|
||
+ abort();
|
||
}
|
||
|
||
|
||
diff -Nurd lua-5.5/src/liolib.c lua-5.5/src/liolib.c
|
||
--- lua-5.5/src/liolib.c 2025-07-05 05:37:52.108553768 +0300
|
||
+++ lua-5.5/src/liolib.c 2025-07-05 05:40:32.053318937 +0300
|
||
@@ -53,7 +53,7 @@
|
||
|
||
#if !defined(l_popen) /* { */
|
||
|
||
-#if defined(LUA_USE_POSIX) /* { */
|
||
+#if defined(LUA_USE_POPEN) /* { */
|
||
|
||
#define l_popen(L,c,m) (fflush(NULL), popen(c,m))
|
||
#define l_pclose(L,file) (pclose(file))
|
||
@@ -114,7 +114,7 @@
|
||
|
||
#if !defined(l_fseek) /* { */
|
||
|
||
-#if defined(LUA_USE_POSIX) /* { */
|
||
+#if defined(LUA_USE_FSEEKO) /* { */
|
||
|
||
#include <sys/types.h>
|
||
|
||
diff -Nurd lua-5.5/src/loslib.c lua-5.5/src/loslib.c
|
||
--- lua-5.5/src/loslib.c 2025-07-05 05:37:52.108553768 +0300
|
||
+++ lua-5.5/src/loslib.c 2025-07-05 05:40:32.053318937 +0300
|
||
@@ -75,7 +75,7 @@
|
||
** where it uses gmtime_r/localtime_r
|
||
*/
|
||
|
||
-#if defined(LUA_USE_POSIX) /* { */
|
||
+#if defined(LUA_USE_GMTIME_R) /* { */
|
||
|
||
#define l_gmtime(t,r) gmtime_r(t,r)
|
||
#define l_localtime(t,r) localtime_r(t,r)
|
||
@@ -102,7 +102,7 @@
|
||
*/
|
||
#if !defined(lua_tmpnam) /* { */
|
||
|
||
-#if defined(LUA_USE_POSIX) /* { */
|
||
+#if defined(LUA_USE_MKSTEMP) /* { */
|
||
|
||
#include <unistd.h>
|
||
|
||
diff -Nurd lua-5.5/src/luaconf.h lua-5.5/src/luaconf.h
|
||
--- lua-5.5/src/luaconf.h 2025-07-05 05:37:52.108553768 +0300
|
||
+++ lua-5.5/src/luaconf.h 2025-07-05 05:40:32.053318937 +0300
|
||
@@ -11,6 +11,7 @@
|
||
#include <limits.h>
|
||
#include <stddef.h>
|
||
|
||
+#include "localluaconf.h"
|
||
|
||
/*
|
||
** ===================================================================
|
dependencies/lua-5.5/src/lapi.c | ||
---|---|---|
/*
|
||
** $Id: lapi.c $
|
||
** Lua API
|
||
** See Copyright Notice in lua.h
|
||
*/
|
||
#define lapi_c
|
||
#define LUA_CORE
|
||
#include "lprefix.h"
|
||
#include <limits.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 " $";
|
||
/*
|
||
** Test for a valid index (one that is not the 'nilvalue').
|
||
*/
|
||
#define isvalid(L, o) ((o) != &G(L)->nilvalue)
|
||
/* test for pseudo index */
|
||
#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
|
||
/* test for upvalue */
|
||
#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
|
||
/*
|
||
** Convert an acceptable index to a pointer to its respective value.
|
||
** Non-valid indices return the special nil value 'G(L)->nilvalue'.
|
||
*/
|
||
static TValue *index2value (lua_State *L, int idx) {
|
||
CallInfo *ci = L->ci;
|
||
if (idx > 0) {
|
||
StkId o = ci->func.p + idx;
|
||
api_check(L, idx <= ci->top.p - (ci->func.p + 1), "unacceptable index");
|
||
if (o >= L->top.p) return &G(L)->nilvalue;
|
||
else return s2v(o);
|
||
}
|
||
else if (!ispseudo(idx)) { /* negative index */
|
||
api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
|
||
"invalid index");
|
||
return s2v(L->top.p + 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 (ttisCclosure(s2v(ci->func.p))) { /* C closure? */
|
||
CClosure *func = clCvalue(s2v(ci->func.p));
|
||
return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
|
||
: &G(L)->nilvalue;
|
||
}
|
||
else { /* light C function or Lua function (through a hook)?) */
|
||
api_check(L, ttislcf(s2v(ci->func.p)), "caller not a C function");
|
||
return &G(L)->nilvalue; /* no upvalues */
|
||
}
|
||
}
|
||
}
|
||
/*
|
||
** Convert a valid actual index (not a pseudo-index) to its address.
|
||
*/
|
||
static StkId index2stack (lua_State *L, int idx) {
|
||
CallInfo *ci = L->ci;
|
||
if (idx > 0) {
|
||
StkId o = ci->func.p + idx;
|
||
api_check(L, o < L->top.p, "invalid index");
|
||
return o;
|
||
}
|
||
else { /* non-positive index */
|
||
api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
|
||
"invalid index");
|
||
api_check(L, !ispseudo(idx), "invalid index");
|
||
return L->top.p + idx;
|
||
}
|
||
}
|
||
LUA_API int lua_checkstack (lua_State *L, int n) {
|
||
int res;
|
||
CallInfo *ci;
|
||
lua_lock(L);
|
||
ci = L->ci;
|
||
api_check(L, n >= 0, "negative 'n'");
|
||
if (L->stack_last.p - L->top.p > n) /* stack large enough? */
|
||
res = 1; /* yes; check is OK */
|
||
else /* need to grow stack */
|
||
res = luaD_growstack(L, n, 0);
|
||
if (res && ci->top.p < L->top.p + n)
|
||
ci->top.p = L->top.p + 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_checkpop(from, n);
|
||
api_check(from, G(from) == G(to), "moving among independent states");
|
||
api_check(from, to->ci->top.p - to->top.p >= n, "stack overflow");
|
||
from->top.p -= n;
|
||
for (i = 0; i < n; i++) {
|
||
setobjs2s(to, to->top.p, from->top.p + i);
|
||
to->top.p++; /* 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 lua_Number lua_version (lua_State *L) {
|
||
UNUSED(L);
|
||
return LUA_VERSION_NUM;
|
||
}
|
||
/*
|
||
** 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.p - L->ci->func.p) + idx;
|
||
}
|
||
LUA_API int lua_gettop (lua_State *L) {
|
||
return cast_int(L->top.p - (L->ci->func.p + 1));
|
||
}
|
||
LUA_API void lua_settop (lua_State *L, int idx) {
|
||
CallInfo *ci;
|
||
StkId func, newtop;
|
||
ptrdiff_t diff; /* difference for new top */
|
||
lua_lock(L);
|
||
ci = L->ci;
|
||
func = ci->func.p;
|
||
if (idx >= 0) {
|
||
api_check(L, idx <= ci->top.p - (func + 1), "new top too large");
|
||
diff = ((func + 1) + idx) - L->top.p;
|
||
for (; diff > 0; diff--)
|
||
setnilvalue(s2v(L->top.p++)); /* clear new slots */
|
||
}
|
||
else {
|
||
api_check(L, -(idx+1) <= (L->top.p - (func + 1)), "invalid new top");
|
||
diff = idx + 1; /* will "subtract" index (as it is negative) */
|
||
}
|
||
newtop = L->top.p + diff;
|
||
if (diff < 0 && L->tbclist.p >= newtop) {
|
||
lua_assert(ci->callstatus & CIST_TBC);
|
||
newtop = luaF_close(L, newtop, CLOSEKTOP, 0);
|
||
}
|
||
L->top.p = newtop; /* correct top only after closing any upvalue */
|
||
lua_unlock(L);
|
||
}
|
||
LUA_API void lua_closeslot (lua_State *L, int idx) {
|
||
StkId level;
|
||
lua_lock(L);
|
||
level = index2stack(L, idx);
|
||
api_check(L, (L->ci->callstatus & CIST_TBC) && (L->tbclist.p == level),
|
||
"no variable to close at given level");
|
||
level = luaF_close(L, level, CLOSEKTOP, 0);
|
||
setnilvalue(s2v(level));
|
||
lua_unlock(L);
|
||
}
|
||
/*
|
||
** Reverse the stack segment from 'from' to 'to'
|
||
** (auxiliary to 'lua_rotate')
|
||
** Note that we move(copy) only the value inside the stack.
|
||
** (We do not move additional fields that may exist.)
|
||
*/
|
||
static void reverse (lua_State *L, StkId from, StkId to) {
|
||
for (; from < to; from++, to--) {
|
||
TValue temp;
|
||
setobj(L, &temp, s2v(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.p - 1; /* end of stack segment being rotated */
|
||
p = index2stack(L, idx); /* start of segment */
|
||
api_check(L, L->tbclist.p < p, "moving a to-be-closed slot");
|
||
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 = index2value(L, fromidx);
|
||
to = index2value(L, toidx);
|
||
api_check(L, isvalid(L, to), "invalid index");
|
||
setobj(L, to, fr);
|
||
if (isupvalue(toidx)) /* function upvalue? */
|
||
luaC_barrier(L, clCvalue(s2v(L->ci->func.p)), 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.p, index2value(L, idx));
|
||
api_incr_top(L);
|
||
lua_unlock(L);
|
||
}
|
||
/*
|
||
** access functions (stack -> C)
|
||
*/
|
||
LUA_API int lua_type (lua_State *L, int idx) {
|
||
const TValue *o = index2value(L, idx);
|
||
return (isvalid(L, o) ? ttype(o) : LUA_TNONE);
|
||
}
|
||
LUA_API const char *lua_typename (lua_State *L, int t) {
|
||
UNUSED(L);
|
||
api_check(L, LUA_TNONE <= t && t < LUA_NUMTYPES, "invalid type");
|
||
return ttypename(t);
|
||
}
|
||
LUA_API int lua_iscfunction (lua_State *L, int idx) {
|
||
const TValue *o = index2value(L, idx);
|
||
return (ttislcf(o) || (ttisCclosure(o)));
|
||
}
|
||
LUA_API int lua_isinteger (lua_State *L, int idx) {
|
||
const TValue *o = index2value(L, idx);
|
||
return ttisinteger(o);
|
||
}
|
||
LUA_API int lua_isnumber (lua_State *L, int idx) {
|
||
lua_Number n;
|
||
const TValue *o = index2value(L, idx);
|
||
return tonumber(o, &n);
|
||
}
|
||
LUA_API int lua_isstring (lua_State *L, int idx) {
|
||
const TValue *o = index2value(L, idx);
|
||
return (ttisstring(o) || cvt2str(o));
|
||
}
|
||
LUA_API int lua_isuserdata (lua_State *L, int idx) {
|
||
const TValue *o = index2value(L, idx);
|
||
return (ttisfulluserdata(o) || ttislightuserdata(o));
|
||
}
|
||
LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
|
||
const TValue *o1 = index2value(L, index1);
|
||
const TValue *o2 = index2value(L, index2);
|
||
return (isvalid(L, o1) && isvalid(L, 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_checkpop(L, 2); /* all other operations expect two operands */
|
||
else { /* for unary operations, add fake 2nd operand */
|
||
api_checkpop(L, 1);
|
||
setobjs2s(L, L->top.p, L->top.p - 1);
|
||
api_incr_top(L);
|
||
}
|
||
/* first operand at top - 2, second at top - 1; result go to top - 2 */
|
||
luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2);
|
||
L->top.p--; /* pop second operand */
|
||
lua_unlock(L);
|
||
}
|
||
LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
|
||
const TValue *o1;
|
||
const TValue *o2;
|
||
int i = 0;
|
||
lua_lock(L); /* may call tag method */
|
||
o1 = index2value(L, index1);
|
||
o2 = index2value(L, index2);
|
||
if (isvalid(L, o1) && isvalid(L, 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 unsigned (lua_numbertocstring) (lua_State *L, int idx, char *buff) {
|
||
const TValue *o = index2value(L, idx);
|
||
if (ttisnumber(o)) {
|
||
unsigned len = luaO_tostringbuff(o, buff);
|
||
buff[len++] = '\0'; /* add final zero */
|
||
return len;
|
||
}
|
||
else
|
||
return 0;
|
||
}
|
||
LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
|
||
size_t sz = luaO_str2num(s, s2v(L->top.p));
|
||
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 = 0;
|
||
const TValue *o = index2value(L, idx);
|
||
int isnum = tonumber(o, &n);
|
||
if (pisnum)
|
||
*pisnum = isnum;
|
||
return n;
|
||
}
|
||
LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
|
||
lua_Integer res = 0;
|
||
const TValue *o = index2value(L, idx);
|
||
int isnum = tointeger(o, &res);
|
||
if (pisnum)
|
||
*pisnum = isnum;
|
||
return res;
|
||
}
|
||
LUA_API int lua_toboolean (lua_State *L, int idx) {
|
||
const TValue *o = index2value(L, idx);
|
||
return !l_isfalse(o);
|
||
}
|
||
LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
|
||
TValue *o;
|
||
lua_lock(L);
|
||
o = index2value(L, idx);
|
||
if (!ttisstring(o)) {
|
||
if (!cvt2str(o)) { /* not convertible? */
|
||
if (len != NULL) *len = 0;
|
||
lua_unlock(L);
|
||
return NULL;
|
||
}
|
||
luaO_tostring(L, o);
|
||
luaC_checkGC(L);
|
||
o = index2value(L, idx); /* previous call may reallocate the stack */
|
||
}
|
||
lua_unlock(L);
|
||
if (len != NULL)
|
||
return getlstr(tsvalue(o), *len);
|
||
else
|
||
return getstr(tsvalue(o));
|
||
}
|
||
LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) {
|
||
const TValue *o = index2value(L, idx);
|
||
switch (ttypetag(o)) {
|
||
case LUA_VSHRSTR: return cast(lua_Unsigned, tsvalue(o)->shrlen);
|
||
case LUA_VLNGSTR: return cast(lua_Unsigned, tsvalue(o)->u.lnglen);
|
||
case LUA_VUSERDATA: return cast(lua_Unsigned, uvalue(o)->len);
|
||
case LUA_VTABLE: return luaH_getn(hvalue(o));
|
||
default: return 0;
|
||
}
|
||
}
|
||
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
|
||
const TValue *o = index2value(L, idx);
|
||
if (ttislcf(o)) return fvalue(o);
|
||
else if (ttisCclosure(o))
|
||
return clCvalue(o)->f;
|
||
else return NULL; /* not a C function */
|
||
}
|
||
l_sinline void *touserdata (const TValue *o) {
|
||
switch (ttype(o)) {
|
||
case LUA_TUSERDATA: return getudatamem(uvalue(o));
|
||
case LUA_TLIGHTUSERDATA: return pvalue(o);
|
||
default: return NULL;
|
||
}
|