summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLua Team <team@lua.org>2014-10-23 12:00:00 +0000
committerrepogen <>2014-10-23 12:00:00 +0000
commit92fdb95364ed274752b8634c8ba3dca1f1dc5fb3 (patch)
treed1747f7ed2d0ed06b83ee3073fe4256aefd4a928
parentd7648e85b78d53a2248de909868192598ad0eb69 (diff)
downloadlua-github-92fdb95364ed274752b8634c8ba3dca1f1dc5fb3.tar.gz
Lua 5.3.0-beta5.3.0-beta
-rw-r--r--README2
-rw-r--r--doc/contents.html30
-rw-r--r--doc/lua.css8
-rw-r--r--doc/manual.html732
-rw-r--r--doc/readme.html37
-rw-r--r--src/Makefile6
-rw-r--r--src/lapi.c40
-rw-r--r--src/lauxlib.c53
-rw-r--r--src/lauxlib.h18
-rw-r--r--src/lbaselib.c51
-rw-r--r--src/lbitlib.c26
-rw-r--r--src/lcorolib.c4
-rw-r--r--src/ldblib.c50
-rw-r--r--src/ldebug.c4
-rw-r--r--src/ldo.c17
-rw-r--r--src/lgc.c126
-rw-r--r--src/liolib.c30
-rw-r--r--src/llex.c21
-rw-r--r--src/lmathlib.c14
-rw-r--r--src/lmem.h24
-rw-r--r--src/loadlib.c19
-rw-r--r--src/lobject.c23
-rw-r--r--src/lobject.h6
-rw-r--r--src/lopcodes.h4
-rw-r--r--src/loslib.c9
-rw-r--r--src/lparser.c14
-rw-r--r--src/lstate.h12
-rw-r--r--src/lstrlib.c517
-rw-r--r--src/ltable.c138
-rw-r--r--src/ltable.h9
-rw-r--r--src/ltablib.c68
-rw-r--r--src/lua.c43
-rw-r--r--src/lua.h22
-rw-r--r--src/luaconf.h89
-rw-r--r--src/lutf8lib.c12
-rw-r--r--src/lvm.c10
-rw-r--r--src/lvm.h6
37 files changed, 1277 insertions, 1017 deletions
diff --git a/README b/README
index 6d6b584c..035f31b8 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
-This is Lua 5.3.0 (alpha), released on 31 Jul 2014.
+This is Lua 5.3.0 (beta), released on 23 Oct 2014.
For installation instructions, license details, and
further information about Lua, see doc/readme.html.
diff --git a/doc/contents.html b/doc/contents.html
index b7a00e30..82714f28 100644
--- a/doc/contents.html
+++ b/doc/contents.html
@@ -22,7 +22,7 @@ Lua 5.3 Reference Manual
<P>
<IMG SRC="alert.png" ALIGN="absbottom">
-<EM>Some details may change in the final version.</EM>
+<EM>A few details may change in the final version.</EM>
<P>
The reference manual is the official definition of the Lua language.
@@ -117,6 +117,7 @@ Freely available under the terms of the
<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>
@@ -183,7 +184,6 @@ Freely available under the terms of the
<P>
<A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR>
-<A HREF="manual.html#pdf-debug.Csize">debug.Csize</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>
@@ -196,6 +196,7 @@ Freely available under the terms of the
<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.sizeof">debug.sizeof</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>
@@ -236,6 +237,7 @@ Freely available under the terms of the
<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>
@@ -283,8 +285,6 @@ Freely available under the terms of the
<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.dumpfloat">string.dumpfloat</A><BR>
-<A HREF="manual.html#pdf-string.dumpint">string.dumpint</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>
@@ -292,17 +292,17 @@ Freely available under the terms of the
<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.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.undumpfloat">string.undumpfloat</A><BR>
-<A HREF="manual.html#pdf-string.undumpint">string.undumpint</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#pdf-table.concat">table.concat</A><BR>
-<A HREF="manual.html#pdf-table.copy">table.copy</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>
@@ -310,7 +310,7 @@ Freely available under the terms of the
<P>
<A HREF="manual.html#pdf-utf8.char">utf8.char</A><BR>
-<A HREF="manual.html#pdf-utf8.charpatt">utf8.charpatt</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>
@@ -322,10 +322,10 @@ Freely available under the terms of the
<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_Ctx">lua_Ctx</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>
@@ -355,6 +355,7 @@ Freely available under the terms of the
<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>
@@ -421,6 +422,7 @@ Freely available under the terms of the
<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>
@@ -428,7 +430,7 @@ Freely available under the terms of the
<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_strtonum">lua_strtonum</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>
@@ -470,9 +472,7 @@ Freely available under the terms of the
<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_checkint">luaL_checkint</A><BR>
<A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR>
-<A HREF="manual.html#luaL_checklong">luaL_checklong</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>
@@ -501,9 +501,7 @@ Freely available under the terms of the
<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_optint">luaL_optint</A><BR>
<A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR>
-<A HREF="manual.html#luaL_optlong">luaL_optlong</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>
@@ -529,10 +527,10 @@ Freely available under the terms of the
<HR>
<SMALL CLASS="footer">
Last update:
-Thu Jul 31 14:04:18 BRT 2014
+Wed Oct 22 21:16:56 BRST 2014
</SMALL>
<!--
-Last change: updated for Lua 5.3.0 (alpha)
+Last change: updated for Lua 5.3.0 (beta)
-->
</BODY>
diff --git a/doc/lua.css b/doc/lua.css
index 98f0fcda..3199a2b6 100644
--- a/doc/lua.css
+++ b/doc/lua.css
@@ -53,6 +53,7 @@ a:visited {
a:link:hover, a:visited:hover {
color: #000080 ;
background-color: #D0D0FF ;
+ border-radius: 4px;
}
a:link:active, a:visited:active {
@@ -90,10 +91,15 @@ table hr {
input[type=text] {
border: solid #a0a0a0 2px ;
border-radius: 2em ;
- -moz-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 ;
+}
diff --git a/doc/manual.html b/doc/manual.html
index 186597b5..70773501 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -18,7 +18,7 @@ Lua 5.3 Reference Manual
<P>
<IMG SRC="alert.png" ALIGN="absbottom">
-<EM>Some details may change in the final version.</EM>
+<EM>A few details may change in the final version.</EM>
<P>
by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
@@ -38,7 +38,7 @@ Freely available under the terms of the
<!-- ====================================================================== -->
<p>
-<!-- $Id: manual.of,v 1.125 2014/07/31 13:58:08 roberto Exp $ -->
+<!-- $Id: manual.of,v 1.136 2014/10/22 16:16:43 roberto Exp $ -->
@@ -49,7 +49,7 @@ Freely available under the terms of the
Lua is an extension programming language designed to support
general procedural programming with data description
facilities.
-It also offers good support for object-oriented programming,
+Lua also offers good support for object-oriented programming,
functional programming, and data-driven programming.
Lua is intended to be used as a powerful, lightweight,
embeddable scripting language for any program that needs one.
@@ -58,7 +58,7 @@ the common subset of Standard&nbsp;C and C++.
<p>
-Being an extension language, Lua has no notion of a "main" program:
+As an extension language, Lua has no notion of a "main" program:
it only works <em>embedded</em> in a host client,
called the <em>embedding program</em> or simply the <em>host</em>.
The host program can invoke functions to execute a piece of Lua code,
@@ -131,6 +131,8 @@ integer numbers and real (floating-point) numbers.
Lua is 8-bit clean:
strings can contain any 8-bit value,
including embedded zeros ('<code>\0</code>').
+Lua is also enconding-agnostic;
+it makes no assumptions about the contents of a string.
<p>
@@ -139,21 +141,21 @@ 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 has the option of mostly ignoring the difference
+the programmer may choose to mostly ignore the difference
between integers and floats
-or assuming complete control over the representation of each value.
+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 both for integers and floats
+The option with 32 bits for both integers and floats
(called <em>Small Lua</em>) is particularly attractive
-for small machines.
+for small machines and embedded systems.
<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>).
+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>
@@ -161,8 +163,10 @@ 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:
-full userdata, where the block of memory is managed by Lua,
-and light userdata, where the block of memory is managed by the host.
+<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>,
@@ -176,7 +180,7 @@ 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>).
-Do not confuse Lua threads with operating-system threads.
+Lua threads are not related to operating-system threads.
Lua supports coroutines on all systems,
even those that do not support threads natively.
@@ -184,9 +188,9 @@ even those that do not support threads natively.
<p>
The type <em>table</em> implements associative arrays,
that is, arrays that can be indexed not only with numbers,
-but with any Lua value except <b>nil</b> and NaN
-(<em>Not a Number</em>, a special numeric value used to represent
-undefined or unrepresentable results, such as <code>0/0</code>).
+but with any Lua value except <b>nil</b> and NaN.
+(<em>Not a Number</em> is a special numeric value used to represent
+undefined or unrepresentable 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.
@@ -195,7 +199,7 @@ an associated value <b>nil</b>.
<p>
-Tables are the sole data structuring mechanism in Lua;
+Tables are the sole data-structuring mechanism in Lua;
they can be used to represent ordinary arrays, sequences,
symbol tables, sets, records, graphs, trees, etc.
To represent records, Lua uses the field name as an index.
@@ -207,8 +211,8 @@ There are several convenient ways to create tables in Lua
<p>
We use the term <em>sequence</em> to denote a table where
-the set of all positive numeric keys is equal to <em>{1..n}</em>
-for some integer <em>n</em>,
+the set of all positive numeric keys is equal to {1..<em>n</em>}
+for some non-negative integer <em>n</em>,
which is called the length of the sequence (see <a href="#3.4.7">&sect;3.4.7</a>).
@@ -228,9 +232,6 @@ 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).
-
-
-<p>
In particular, floats with integral values
are equal to their respective integers
(e.g., <code>1.0 == 1</code>).
@@ -240,6 +241,9 @@ 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>
@@ -263,20 +267,21 @@ of a given value (see <a href="#6.1">&sect;6.1</a>).
<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 global name <code>var</code> is syntactically translated
-to <code>_ENV.var</code>.
+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 called <code>_ENV</code> (see <a href="#3.3.2">&sect;3.3.2</a>),
-so <code>_ENV</code> itself is never a global name in a chunk.
+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 global names,
+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 global name uses the <code>_ENV</code> that is
+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>).
@@ -288,34 +293,25 @@ Any table used as the value of <code>_ENV</code> is called an <em>environment</e
<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 variable <a href="#pdf-_G"><code>_G</code></a> is initialized with this same value.
+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 compiles a chunk,
-it initializes the value of its <code>_ENV</code> upvalue
-with the global environment (see <a href="#pdf-load"><code>load</code></a>).
+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,
-global variables in Lua code refer to entries in the global environment.
+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 several functions there operate on that 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.)
-<p>
-If you change the global environment in the registry
-(through C code or the debug library),
-all chunks loaded after the change will get the new environment.
-Previously loaded chunks are not affected, however,
-as each has its own reference to the environment in its <code>_ENV</code> variable.
-Moreover, the variable <a href="#pdf-_G"><code>_G</code></a>
-(which is stored in the original global environment)
-is never updated by Lua.
-
-
@@ -325,7 +321,7 @@ is never updated by Lua.
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,
+(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,
@@ -346,9 +342,10 @@ to call a given function in <em>protected mode</em>.
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 where the error object is a string,
+Lua itself only generates errors whose error object is a string,
but programs may generate errors with
-any value for the error object.
+any value as the error object.
+It is up to the Lua program or its host to handle such error objects.
<p>
@@ -363,7 +360,8 @@ 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, Lua breaks it and returns an appropriate message.
+If this loop goes on for too long,
+Lua breaks it and returns an appropriate message.
@@ -400,7 +398,7 @@ using the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function.
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
-(except by using the debug library);
+(except by using the debug library (<a href="#6.10">&sect;6.10</a>));
you must use the C&nbsp;API for that.
@@ -416,10 +414,10 @@ but the string library sets a metatable for the string type (see <a href="#6.4">
<p>
A metatable controls how an object behaves in
-arithmetic and bitwise operations,
+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.
+when a userdata or a table is garbage collected (<a href="#2.5">&sect;2.5</a>).
<p>
@@ -460,13 +458,13 @@ 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 the "<code>__add</code>" event,
then Lua will check the second operand.
-If Lua cannot find a metamethod,
-it raises an error.
-Otherwise,
+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>"sub": </b>
@@ -647,7 +645,7 @@ and therefore can trigger another metamethod.)
<p>
-Whenever there is a metamethod,
+Whenever there is a "newindex" metamethod,
Lua does not perform the primitive assignment.
(If necessary,
the metamethod itself can call <a href="#pdf-rawset"><code>rawset</code></a>
@@ -675,8 +673,8 @@ followed by the arguments of the original call (<code>args</code>).
<p>
Lua performs automatic memory management.
This means that
-you have to worry neither about allocating memory for new objects
-nor about freeing it when the objects are no longer needed.
+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).
@@ -710,7 +708,7 @@ 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,
-as they make the collector too slow and
+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"
@@ -758,7 +756,7 @@ 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.
-However, after an object is marked,
+However, after an object has been marked,
you can freely change the <code>__gc</code> field of its metatable.
@@ -768,18 +766,18 @@ 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,
+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.)
+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 they were marked for finalization,
+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.
@@ -789,13 +787,13 @@ the execution of the regular code.
<p>
Because the object being collected must still be used by the finalizer,
-it (and other objects accessible only through it)
+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 there is a permanent resurrection.
+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.
@@ -866,7 +864,7 @@ are removed from weak tables.
Values, such as numbers and light C functions,
are not subject to garbage collection,
and therefore are not removed from weak tables
-(unless its associated value is collected).
+(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.
@@ -921,8 +919,8 @@ passing as its first argument
a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
the coroutine starts its execution,
at the first line of its main function.
-Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on
-to the coroutine main function.
+Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed
+as arguments to the coroutine's main function.
After the coroutine starts running,
it runs until it terminates or <em>yields</em>.
@@ -932,7 +930,8 @@ 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 the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>,
+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 message.
@@ -1113,15 +1112,17 @@ into the string contents.
<p>
-A byte in a literal string can also be specified by its numerical value.
-This can be done with the escape sequence <code>\x<em>XX</em></code>,
+Strings in Lua can contain any 8-bit value, including embedded zeros,
+which can be specified as '<code>\0</code>'.
+More generally,
+we can specify any byte in a literal string by its numerical value.
+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 is to be followed by a digit,
+(Note that if a decimal escape sequence is to be followed by a digit,
it must be expressed using exactly three digits.)
-Strings in Lua can contain any 8-bit value, including embedded zeros,
-which can be specified as '<code>\0</code>'.
<p>
@@ -1147,7 +1148,7 @@ 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 proper 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.
@@ -1189,7 +1190,8 @@ the five literal strings below denote the same string:
</pre>
<p>
-A <em>numerical constant</em> can be written with an optional fractional part
+A <em>numerical 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,
@@ -1390,8 +1392,9 @@ 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 precompiles the chunk into instructions for a virtual machine,
-and then it executes the compiled code
+Lua first \emph{loads} 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.
@@ -1438,7 +1441,7 @@ before the adjustment
<p>
The assignment statement first evaluates all its expressions
-and only then are the assignments performed.
+and only then the assignments are performed.
Thus the code
<pre>
@@ -1474,7 +1477,7 @@ We use it here only for explanatory purposes.)
<p>
-An assignment to a global variable <code>x = val</code>
+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>).
@@ -1555,7 +1558,8 @@ 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 a function in disguise).
+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
@@ -1760,8 +1764,8 @@ The basic expressions in Lua are the following:
<pre>
exp ::= prefixexp
exp ::= <b>nil</b> | <b>false</b> | <b>true</b>
- exp ::= Number
- exp ::= String
+ exp ::= Numeral
+ exp ::= LiteralString
exp ::= functiondef
exp ::= tableconstructor
exp ::= &lsquo;<b>...</b>&rsquo;
@@ -1771,7 +1775,7 @@ The basic expressions in Lua are the following:
</pre>
<p>
-Numbers and literal strings are explained in <a href="#3.1">&sect;3.1</a>;
+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>;
@@ -1789,7 +1793,7 @@ relational operators (see <a href="#3.4.4">&sect;3.4.4</a>), logical operators (
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 logic <b>not</b> (see <a href="#3.4.5">&sect;3.4.5</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>).
@@ -1881,12 +1885,13 @@ so that it works for non-integer exponents too.
Integer division (<code>//</code>) converts its operands to integers
(see <a href="#3.4.3">&sect;3.4.3</a>)
and its result is always an integer.
-The result is always rounded towards minus infinite (floor).
+The result is always rounded towards minus infinite
+(floor division).
<p>
Modulo is defined as the remainder of a division
-that rounds the quotient towards minus infinite (floor).
+that rounds the quotient towards minus infinite (floor division).
<p>
@@ -1935,7 +1940,7 @@ types and representations at run time.
Most arithmetic operations applied to mixed numbers
(integers and floats) convert the integer operand to a float;
this is called the <em>usual rule</em>.
-Float division always convert integer operands to floats;
+Float division always converts integer operands to floats;
integer division and bitwise operators
always convert float operands to integers.
The C API also converts both integers to floats and
@@ -1978,8 +1983,8 @@ Then, the resulting number is converted to the required type
<p>
-The conversion from numbers to strings uses a human-readable,
-non-specified format.
+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>).
@@ -2267,7 +2272,7 @@ Arguments have the following syntax:
<pre>
args ::= &lsquo;<b>(</b>&rsquo; [explist] &lsquo;<b>)</b>&rsquo;
args ::= tableconstructor
- args ::= String
+ args ::= LiteralString
</pre><p>
All argument expressions are evaluated before the call.
A call of the form <code>f{<em>fields</em>}</code> is
@@ -2598,12 +2603,13 @@ 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 extra slots when pushing new elements.
+to ensure that the stack has enough space for pushing new elements.
<p>
Whenever Lua calls C,
-it ensures that the stack has at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra slots.
+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.
@@ -2612,7 +2618,7 @@ 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 size for all results,
+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>.
@@ -2722,14 +2728,14 @@ 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 global names,
+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,
-implemented by the auxiliary library,
+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.
@@ -2759,8 +2765,8 @@ the global environment.
<p>
Internally, Lua uses the C <code>longjmp</code> facility to handle errors.
-(You can also choose to use exceptions if you compile Lua as C++;
-search for <code>LUAI_THROW</code> in the source code.)
+(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, type errors, syntax errors,
and runtime errors)
@@ -2820,7 +2826,7 @@ 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 called <code>k</code>) to continue execution after a yield.
+(as a parameter named <code>k</code>) to continue execution after a yield.
<p>
@@ -2864,7 +2870,7 @@ the Lua code being ran by <a href="#lua_pcall"><code>lua_pcall</code></a> to yie
First, we can rewrite our function like here:
<pre>
- int k (lua_State *L, int status, lua_Ctx ctx) {
+ int k (lua_State *L, int status, lua_KContext ctx) {
... /* code 2 */
}
@@ -2990,7 +2996,7 @@ Its arguments are
<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;
-<code>nsize</code>, the new size of the block.
+and <code>nsize</code>, the new size of the block.
<p>
@@ -3047,7 +3053,7 @@ It is used in the auxiliary library by <a href="#luaL_newstate"><code>luaL_newst
</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>.
+<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.)
@@ -3150,7 +3156,7 @@ Here it is in&nbsp;C:
<pre>
lua_getglobal(L, "f"); /* function to be called */
- lua_pushstring(L, "how"); /* 1st argument */
+ 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 */
@@ -3158,7 +3164,7 @@ Here it is in&nbsp;C:
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 "balanced":
+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.
@@ -3168,7 +3174,10 @@ 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_Ctx ctx,
+<pre>void lua_callk (lua_State *L,
+ int nargs,
+ int nresults,
+ lua_KContext ctx,
lua_KFunction k);</pre>
<p>
@@ -3207,16 +3216,16 @@ many results.
<p>
As an example, the following function receives a variable number
-of numerical arguments and returns their average and sum:
+of numerical 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;
+ lua_Number sum = 0.0;
int i;
for (i = 1; i &lt;= n; i++) {
if (!lua_isnumber(L, i)) {
- lua_pushstring(L, "incorrect argument");
+ lua_pushliteral(L, "incorrect argument");
lua_error(L);
}
sum += lua_tonumber(L, i);
@@ -3232,14 +3241,15 @@ of numerical arguments and returns their average and sum:
<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 extra);</pre>
+<pre>int lua_checkstack (lua_State *L, int n);</pre>
<p>
-Ensures that there are at least <code>extra</code> free stack slots in the stack.
+Ensures that the stack has space for at least <code>n</code> extra slots.
It returns false if it cannot fulfill the request,
-because it would cause the stack to be larger than a fixed maximum size
-(typically at least a few thousand elements) or
-because it cannot allocate memory for the new stack size.
+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 is already larger than the new size,
it is left unchanged.
@@ -3260,7 +3270,7 @@ On 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,
-might need to close states as soon as they are not needed.
+will probably need to close states as soon as they are not needed.
@@ -3277,7 +3287,7 @@ 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 non valid.
+Also returns&nbsp;0 if any of the indices is not valid.
<p>
@@ -3317,9 +3327,9 @@ Concatenation is performed following the usual semantics of Lua
<p>
Copies the element at index <code>fromidx</code>
-into the valid index <code>toidx</code>
-without shifting any element
-(therefore replacing the value at that position).
+into the valid index <code>toidx</code>,
+replacing the value at that position.
+Values at other positions are not affected.
@@ -3344,21 +3354,6 @@ Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</c
-<hr><h3><a name="lua_Ctx"><code>lua_Ctx</code></a></h3>
-<pre>typedef ... lua_Ctx;</pre>
-
-<p>
-The type for continuation-function contexts.
-It must be a numerical 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_dump"><code>lua_dump</code></a></h3><p>
<span class="apii">[-0, +0, <em>e</em>]</span>
<pre>int lua_dump (lua_State *L,
@@ -3402,8 +3397,8 @@ This function does not pop the Lua function from the stack.
<pre>int lua_error (lua_State *L);</pre>
<p>
-Generates a Lua error.
-The error object must be on the stack top.
+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>).
@@ -3485,7 +3480,7 @@ see <a href="#pdf-collectgarbage"><code>collectgarbage</code></a>.
<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 passed to <a href="#lua_newstate"><code>lua_newstate</code></a>.
+opaque pointer given when the memory-allocator function was set.
@@ -3546,6 +3541,24 @@ 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>
@@ -3571,8 +3584,8 @@ and <code>k</code> is the value at the top of the stack.
<p>
-This function pops the key from the stack
-(putting the resulting value in its place).
+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>).
@@ -3591,8 +3604,8 @@ Returns the type of the pushed value.
<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
-(and so 0&nbsp;means an empty stack).
+this result is equal to the number of elements in the stack;
+in particular, 0&nbsp;means an empty stack.
@@ -3636,10 +3649,10 @@ The type of integers in Lua.
<p>
-By default this type is <code>long long</code>
+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.
+but that can be changed to <code>long</code> or <code>int</code>
+(usually a 32-bit two-complement integer).
(See <code>LUA_INT</code> in <code>luaconf.h</code>.)
@@ -3824,8 +3837,23 @@ 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 numerical 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_Ctx ctx);</pre>
+<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>).
@@ -3839,8 +3867,9 @@ Type for continuation functions (see <a href="#4.7">&sect;4.7</a>).
<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>).
+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.
@@ -3856,7 +3885,7 @@ The result is pushed on the stack.
const char *mode);</pre>
<p>
-Loads a Lua chunk (without running it).
+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.
@@ -4147,7 +4176,7 @@ error while running a <code>__gc</code> metamethod.
int nargs,
int nresults,
int errfunc,
- lua_Ctx ctx,
+ lua_KContext ctx,
lua_KFunction k);</pre>
<p>
@@ -4275,7 +4304,7 @@ The conversion specifiers can only be
'<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 an <code>int</code> as a UTF-8 byte sequence).
+'<code>%U</code>' (inserts a <code>long int</code> as a UTF-8 byte sequence).
</li>
</ul>
@@ -4452,7 +4481,7 @@ Returns 1 if the two values in indices <code>index1</code> and
<code>index2</code> are primitively equal
(that is, without calling metamethods).
Otherwise returns&nbsp;0.
-Also returns&nbsp;0 if any of the indices are non valid.
+Also returns&nbsp;0 if any of the indices are not valid.
@@ -4538,10 +4567,10 @@ Similar to <a href="#lua_settable"><code>lua_settable</code></a>, but does a raw
<hr><h3><a name="lua_rawseti"><code>lua_rawseti</code></a></h3><p>
<span class="apii">[-1, +0, <em>e</em>]</span>
-<pre>void lua_rawseti (lua_State *L, int index, lua_Integer n);</pre>
+<pre>void lua_rawseti (lua_State *L, int index, lua_Integer i);</pre>
<p>
-Does the equivalent of <code>t[n] = v</code>,
+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.
@@ -4747,6 +4776,25 @@ 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>
@@ -4851,20 +4899,22 @@ You can resume threads with status <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>
-<hr><h3><a name="lua_strtonum"><code>lua_strtonum</code></a></h3><p>
+<hr><h3><a name="lua_stringtonumber"><code>lua_stringtonumber</code></a></h3><p>
<span class="apii">[-0, +1, &ndash;]</span>
-<pre>size_t lua_strtonum (lua_State *L, const char *s);</pre>
+<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).
+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.)
@@ -5190,7 +5240,10 @@ 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_Ctx ctx, lua_KFunction k);</pre>
+<pre>int lua_yieldk (lua_State *L,
+ int nresults,
+ lua_KContext ctx,
+ lua_KFunction k);</pre>
<p>
Yields a coroutine (thread).
@@ -6052,19 +6105,6 @@ of any type (including <b>nil</b>) at position <code>arg</code>.
-<hr><h3><a name="luaL_checkint"><code>luaL_checkint</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>int luaL_checkint (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 an <code>int</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>
@@ -6078,19 +6118,6 @@ and returns this integer cast to a <a href="#lua_Integer"><code>lua_Integer</cod
-<hr><h3><a name="luaL_checklong"><code>luaL_checklong</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>long luaL_checklong (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 <code>long</code>.
-
-
-
-
-
<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>
@@ -6316,10 +6343,10 @@ file-related functions in the standard library
<p>
Pushes onto the stack the field <code>e</code> from the metatable
-of the object at index <code>obj</code>.
+of the object at index <code>obj</code> and returns the type of pushed value.
If the object does not have a metatable,
or if the metatable does not have this field,
-returns false and pushes nothing.
+pushes nothing and returns <code>LUA_TNIL</code>.
@@ -6490,16 +6517,22 @@ it does not run it.
<hr><h3><a name="luaL_newlib"><code>luaL_newlib</code></a></h3><p>
<span class="apii">[-0, +1, <em>e</em>]</span>
-<pre>void luaL_newlib (lua_State *L, const luaL_Reg *l);</pre>
+<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>
+</pre><p>
+The array <code>l</code> must be the actual array,
+not a pointer to it.
+
@@ -6579,21 +6612,6 @@ Opens all standard Lua libraries into the given state.
-<hr><h3><a name="luaL_optint"><code>luaL_optint</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>int luaL_optint (lua_State *L, int arg, int d);</pre>
-
-<p>
-If the function argument <code>arg</code> is a number,
-returns this number cast to an <code>int</code>.
-If this argument is absent or is <b>nil</b>,
-returns <code>d</code>.
-Otherwise, raises an error.
-
-
-
-
-
<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,
@@ -6612,22 +6630,6 @@ Otherwise, raises an error.
-<hr><h3><a name="luaL_optlong"><code>luaL_optlong</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>long luaL_optlong (lua_State *L, int arg, long d);</pre>
-
-<p>
-If the function argument <code>arg</code> is an integer
-(or convertible to an integer),
-returns this integer cast to a <code>long</code>.
-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,
@@ -6870,7 +6872,8 @@ 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,
-the field value is changed to <b>nil</b> to signal that the handle is closed.
+the field value is changed to <code>NULL</code>
+to signal that the handle is closed.
@@ -7210,12 +7213,8 @@ so that the construction
for i,v in ipairs(t) do <em>body</em> end
</pre><p>
will iterate over the pairs
-(<code>1,t[1]</code>), (<code>2,t[2]</code>), ..., (<code>#t,t[#t]</code>).
-
-
-<p>
-The table should be a proper sequence
-or have a <code>__len</code> metamethod (see <a href="#3.4.7">&sect;3.4.7</a>).
+(<code>1,t[1]</code>), (<code>2,t[2]</code>), ...,
+up to the first integer key absent from the table.
@@ -7251,7 +7250,8 @@ or to the value of the global environment.
(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>).
-When you load a binary chunk created from a function (see <a href="#pdf-string.dump"><code>string.dump</code></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 arbitrary upvalues.)
@@ -7774,7 +7774,7 @@ Default is '<code>?</code>'.</li>
is replaced by the executable's directory.
Default is '<code>!</code>'.</li>
-<li>The fifth line is a mark to ignore all text before it
+<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>
@@ -7956,7 +7956,7 @@ 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 sufix after (and including) the first hyphen is removed.
+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>.
@@ -8104,47 +8104,6 @@ about the function
<p>
-<hr><h3><a name="pdf-string.dumpfloat"><code>string.dumpfloat (n [, size [, endianness]])</code></a></h3>
-Returns a string with the machine representation of float <code>n</code>,
-with given size and endianness.
-The <code>size</code> is the string "<code>f</code>" (single precision),
-"<code>d</code>" (double precision), or "<code>n</code>",
-which means the size of a <a href="#lua_Number"><code>lua_Number</code></a>;
-its default is "<code>n</code>".
-The endianness is the string "<code>l</code>" (little endian), "<code>b</code>" (big endian),
-or "<code>n</code>" (native);
-the default is the native endianness.
-
-
-<p>
-This function may not work correctly in architectures
-with mixed endian.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.dumpint"><code>string.dumpint (n [, size [, endianness]])</code></a></h3>
-Returns a string with the two-complement representation of integer <code>n</code>,
-with <code>size</code> bytes and given endianness.
-The <code>size</code> can be any value from 1 to 12,
-or 0, which means the size of a <a href="#lua_Integer"><code>lua_Integer</code></a>
-(8 bytes in standard Lua);
-its default is zero.
-The endianness is the string "<code>l</code>" (little endian), "<code>b</code>" (big endian),
-or "<code>n</code>" (native);
-the default is the native endianness.
-
-
-<p>
-This function may not work correctly in architectures
-with mixed endian or
-that do not use a two-complement representation for integers.
-
-
-
-
-<p>
<hr><h3><a name="pdf-string.find"><code>string.find (s, pattern [, init [, plain]])</code></a></h3>
@@ -8368,6 +8327,18 @@ its default value is&nbsp;1 and can be negative.
<p>
+<hr><h3><a name="pdf-string.pack"><code>string.pack (fmt, v1, v2, ...)</code></a></h3>
+
+
+<p>
+Returns a binary string containing the values v1, v2, etc.
+packed (that is, serialized in binary form)
+according to the format string fmt (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>.
@@ -8412,23 +8383,16 @@ the function returns the empty string.
<p>
-<hr><h3><a name="pdf-string.undumpfloat"><code>string.undumpfloat (s [, pos [, size [, endianness]]])</code></a></h3>
-Reads the machine representation of a float starting at position
-<code>pos</code> in string <code>s</code> and returns that number.
-See <a href="#pdf-string.dumpfloat"><code>string.dumpfloat</code></a> for details about <code>size</code> and <code>endianness</code>.
-
-
+<hr><h3><a name="pdf-string.unpack"><code>string.unpack (fmt, s [, pos])</code></a></h3>
<p>
-<hr><h3><a name="pdf-string.undumpint"><code>string.undumpint (s [, pos [, size [, endianness]]])</code></a></h3>
-Reads the machine representation of an integer starting at position
-<code>pos</code> in string <code>s</code> and returns that integer.
-See <a href="#pdf-string.dumpint"><code>string.dumpint</code></a> for details about <code>size</code> and <code>endianness</code>.
-
-
-<p>
-Integers are always read as signed.
+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>.
@@ -8495,7 +8459,8 @@ represents the character <em>x</em> itself.
<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 punctuation character (even the non magic)
+Any non-alphanumeric character
+(including all punctuations, even the non-magical)
can be preceded by a '<code>%</code>'
when used to represent itself in a pattern.
</li>
@@ -8646,6 +8611,85 @@ 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 both <a href="#pdf-string.pack"><code>string.pack</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:
+<table border="1">
+<tr><td><code>&lt;</code></td><td>sets little endian</td></tr>
+<tr><td><code>&gt;</code></td><td>sets big endian</td></tr>
+<tr><td><code>![<em>n</em>]</code></td><td>sets maximum alignment to <code>n</code>
+(default is native alignment)</td></tr>
+<tr><td><code>b</code></td><td>a signed byte (<code>char</code>)</td></tr>
+<tr><td><code>B</code></td><td>an unsigned byte (<code>char</code>)</td></tr>
+<tr><td><code>h</code></td><td>a signed <code>short</code> (native size)</td></tr>
+<tr><td><code>H</code></td><td>an unsigned <code>short</code> (native size)</td></tr>
+<tr><td><code>l</code></td><td>a signed <code>long</code> (native size)</td></tr>
+<tr><td><code>L</code></td><td>an unsigned <code>long</code> (native size)</td></tr>
+<tr><td><code>j</code></td><td>a <code>lua_Integer</code></td></tr>
+<tr><td><code>J</code></td><td>a <code>lua_Unsigned</code></td></tr>
+<tr><td><code>T</code></td><td>a <code>size_t</code> (native size)</td></tr>
+<tr><td><code>i[<em>n</em>]</code></td><td>a signed <code>int</code> with <code>n</code> bytes
+(default is native size)</td></tr>
+<tr><td><code>I[<em>n</em>]</code></td><td>an unsigned <code>int</code> with <code>n</code> bytes
+(default is native size)</td></tr>
+<tr><td><code>f</code></td><td>a <code>float</code> (native size)</td></tr>
+<tr><td><code>d</code></td><td>a <code>double</code> (native size)</td></tr>
+<tr><td><code>n</code></td><td>a <code>lua_Number</code></td></tr>
+<tr><td><code>c[<em>n</em>]</code></td><td>a fixed-sized string with <code>n</code> bytes
+(default is 1)</td></tr>
+<tr><td><code>z</code></td><td>a zero-terminated string</td></tr>
+<tr><td><code>s[<em>n</em>]</code></td><td>a string preceded by its length
+coded as an unsigned integer with <code>n</code> bytes
+(default is a <code>size_t</code>)</td></tr>
+<tr><td><code>x</code></td><td>one byte of padding</td></tr>
+<tr><td><code>X<em>op</em></code></td><td>an empty item that aligns
+according to option <code>op</code>
+(which is otherwise ignored)</td></tr>
+<tr><td>'<code> </code>'</td><td>(empty space) ignored</td></tr>
+</table>
+(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>
+Before any configuration option,
+the default alignment is 1 (that is, no alignment)
+and the default endianness is the 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 (1, 2, 4, 8, or 16).
+Options "<code>c</code>" and "<code>z</code>" are not aligned.
+Option "<code>s</code>" is aligned according to the size of its starting length.
+
+
+
+
+
<h2>6.5 &ndash; <a name="6.5">UTF-8 Support</a></h2>
@@ -8678,7 +8722,7 @@ and returns a string with the concatenation of all these sequences.
<p>
-<hr><h3><a name="pdf-utf8.charpatt"><code>utf8.charpatt</code></a></h3>
+<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,
@@ -8721,7 +8765,7 @@ Returns the number of UTF-8 characters in string <code>s</code>
that start between positions <code>i</code> and @{j} (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 <b>nil</b> plus the position of the first invalid byte.
+returns a false value plus the position of the first invalid byte.
@@ -8787,32 +8831,32 @@ If <code>i</code> is greater than <code>j</code>, returns the empty string.
<p>
-<hr><h3><a name="pdf-table.copy"><code>table.copy (a1, f, e, [a2,] t)</code></a></h3>
+<hr><h3><a name="pdf-table.insert"><code>table.insert (list, [pos,] value)</code></a></h3>
<p>
-Copies elements from table <code>a1</code> to table <code>a2</code>.
-This function performs 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.
-Index <code>f</code> must be positive.
+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.insert"><code>table.insert (list, [pos,] value)</code></a></h3>
+<hr><h3><a name="pdf-table.move"><code>table.move (a1, f, e, t [,a2])</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>.
+Moves elements from table <code>a1</code> to table <code>a2</code>.
+This function performs 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.
+Index <code>f</code> must be positive.
@@ -8991,6 +9035,17 @@ 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>
@@ -9482,6 +9537,8 @@ 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).
@@ -9919,32 +9976,6 @@ The default is always the current thread.
<p>
-<hr><h3><a name="pdf-debug.Csize"><code>debug.Csize (t)</code></a></h3>
-
-
-<p>
-Returns the size of the underlying representation of a given C type,
-according to the following table:
-<table border="1">
-<tr><td>'<code>I</code>'</td><td><code>lua_Integer</code></td></tr>
-<tr><td>'<code>F</code>'</td><td><code>lua_Number</code></td></tr>
-<tr><td>'<code>b</code>'</td><td><code>byte</code></td></tr>
-<tr><td>'<code>d</code>'</td><td><code>double</code></td></tr>
-<tr><td>'<code>f</code>'</td><td><code>float</code></td></tr>
-<tr><td>'<code>h</code>'</td><td><code>short int</code></td></tr>
-<tr><td>'<code>i</code>'</td><td><code>int</code></td></tr>
-<tr><td>'<code>l</code>'</td><td><code>long int</code></td></tr>
-<tr><td>'<code>z</code>'</td><td><code>size_t</code></td></tr>
-</table>
-For all options except '<code>b</code>',
-the size is given in number of bytes;
-for option '<code>b</code>',
-the size is its number of bits.
-
-
-
-
-<p>
<hr><h3><a name="pdf-debug.debug"><code>debug.debug ()</code></a></h3>
@@ -10222,7 +10253,7 @@ 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.
-An optional <code>message</code> string is appended
+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
@@ -10384,12 +10415,11 @@ by issuing a different prompt.
<p>
In case of unprotected errors in the script,
the interpreter reports the error to the standard error stream.
-If the error object is a string,
-the interpreter adds a stack traceback to it.
-Otherwise, if the error object has a metamethod <code>__tostring</code>,
+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.
-Finally, if the error object is <b>nil</b>,
-the interpreter does not report the error.
+Otherwise, the interpreter converts the error object to a string
+and adds a stack traceback to it.
<p>
@@ -10527,7 +10557,7 @@ for setting and getting elements.
<li>
The <a href="#pdf-ipairs"><code>ipairs</code></a> iterator now respects metamethods and
-its id{__ipairs} metamethod has been deprecated.
+its <code>__ipairs</code> metamethod has been deprecated.
</li>
<li>
@@ -10544,7 +10574,8 @@ you can replace <code>math.atan2</code> with <code>math.atan</code>,
which now accepts one or two parameters;
you can replace <code>math.ldexp(x,exp)</code> with <code>x * 2.0^exp</code>.
For the other operations,
-the best choice is to use an external library.
+you can either use an external library or
+implement them in Lua.
</li>
<li>
@@ -10582,11 +10613,20 @@ Use 0 as the value of this parameter to get the old behavior.
<li>
Functions to inject/project unsigned integers
-(<code>lua_pushunsigned</code>, <code>lua_tounsigned</code>, etc.)
+(<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>
@@ -10596,7 +10636,13 @@ Use their signed equivalents with a type cast.
<p>
Here is the complete syntax of Lua in extended BNF.
-(For operator precedences, see <a href="#3.4.8">&sect;3.4.8</a>.)
+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>.)
@@ -10637,14 +10683,14 @@ Here is the complete syntax of Lua in extended BNF.
explist ::= exp {&lsquo;<b>,</b>&rsquo; exp}
- exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | &lsquo;<b>...</b>&rsquo; | functiondef |
+ 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 | String
+ args ::= &lsquo;<b>(</b>&rsquo; [explist] &lsquo;<b>)</b>&rsquo; | tableconstructor | LiteralString
functiondef ::= <b>function</b> funcbody
@@ -10681,10 +10727,10 @@ Here is the complete syntax of Lua in extended BNF.
<HR>
<SMALL CLASS="footer">
Last update:
-Thu Jul 31 14:02:14 BRT 2014
+Thu Oct 23 09:03:14 BRST 2014
</SMALL>
<!--
-Last change: revised for Lua 5.3.0 (alpha)
+Last change: revised for Lua 5.3.0 (beta)
-->
</body></html>
diff --git a/doc/readme.html b/doc/readme.html
index 19e0c553..1cba776e 100644
--- a/doc/readme.html
+++ b/doc/readme.html
@@ -31,12 +31,12 @@ tt, kbd, code {
<HR>
<H1>
<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A>
-Welcome to Lua 5.3 (alpha)
+Welcome to Lua 5.3 (beta)
</H1>
<P>
<IMG SRC="alert.png" ALIGN="absbottom">
-<EM>Some details may change in the final version.</EM>
+<EM>A few details may change in the final version.</EM>
<P>
<A HREF="#about">about</A>
@@ -114,7 +114,7 @@ Here are the details.
<OL>
<LI>
Open a terminal window and move to
-the top-level directory, which is named <TT>lua-5.3.0-alpha</TT>.
+the top-level directory, which is named <TT>lua-5.3.0-beta</TT>.
The <TT>Makefile</TT> there controls both the build process and the installation process.
<P>
<LI>
@@ -271,13 +271,11 @@ lists the
<H3>Main changes</H3>
<UL>
-<LI> support for integers (64-bit by default)
-<LI> better support for small architectures ("Small Lua" with 32-bit numbers)
+<LI> integers (64-bit by default)
+<LI> official support for small architectures ("Small Lua" with 32-bit numbers)
<LI> bitwise operators
-<LI> basic utf-8 library
+<LI> basic utf-8 support
-<LI> utf-8 escapes in literal strings
-<LI> strip option in <CODE>lua_dump</CODE>/<CODE>string.dump</CODE>
</UL>
Here are the other changes introduced in Lua 5.3:
@@ -286,20 +284,33 @@ Here are the other changes introduced in Lua 5.3:
<LI> userdata can have any Lua value as uservalue
<LI> integer division
<LI> more flexible rules for some metamethods
+<LI> utf-8 escapes in literal strings
</UL>
<H3>Libraries</H3>
<UL>
-<LI> functions for packing/unpacking numbers
+<LI> basic utf-8 library
+<LI> <CODE>ipairs</CODE> and the table library respect metamethods
+<LI> functions for packing and unpacking numbers
<LI> strip option in <CODE>string.dump</CODE>
<LI> table library respects metamethods
<LI> new function <CODE>table.copy</CODE>
-<LI> new function <CODE>debug.Csize</CODE>
+<LI> new function <CODE>debug.sizeof</CODE>
+<LI> strip option in
+<CODE>string.dump</CODE>
+and
+<CODE>lua_dump</CODE>
</UL>
<H3>C API</H3>
<UL>
-<LI> new functions: <CODE>lua_rotate</CODE>, <CODE>lua_isyieldable</CODE>, <CODE>lua_strtonum</CODE>
+<LI> simpler API for continuation functions in C
+<LI> new functions:
+<CODE>lua_rotate</CODE>,
+<CODE>lua_isyieldable</CODE>,
+<CODE>lua_strtonum</CODE>,
+<CODE>lua_geti</CODE>,
+<CODE>lua_seti</CODE>
<LI> <CODE>lua_gettable</CODE> and similar functions return type of resulted value
</UL>
@@ -356,10 +367,10 @@ THE SOFTWARE.
<HR>
<SMALL CLASS="footer">
Last update:
-Thu Jul 31 15:23:46 BRT 2014
+Tue Oct 7 18:16:28 BRT 2014
</SMALL>
<!--
-Last change: updated for Lua 5.3.0 (alpha)
+Last change: updated for Lua 5.3.0 (beta)
-->
</BODY>
diff --git a/src/Makefile b/src/Makefile
index a30a75ef..7be16dc3 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -92,7 +92,11 @@ aix:
$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
ansi:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI -DLUA_32BITS"
+ @echo ""
+ @echo "Note: in ANSI mode, Lua is built with 32-bit numbers"
+ @echo " because ANSI C89 does not support 'long long'"
+ @echo ""
bsd:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
diff --git a/src/lapi.c b/src/lapi.c
index 9bd78308..24c943d1 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.232 2014/07/30 14:00:14 roberto Exp $
+** $Id: lapi.c,v 2.238 2014/10/17 19:17:55 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -332,7 +332,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
}
-LUA_API size_t lua_strtonum (lua_State *L, const char *s) {
+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);
@@ -611,6 +611,18 @@ 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) {
+ StkId t;
+ lua_lock(L);
+ t = index2addr(L, idx);
+ setivalue(L->top, n);
+ api_incr_top(L);
+ luaV_gettable(L, t, L->top - 1, L->top - 1);
+ lua_unlock(L);
+ return ttnov(L->top - 1);
+}
+
+
LUA_API int lua_rawget (lua_State *L, int idx) {
StkId t;
lua_lock(L);
@@ -664,7 +676,7 @@ LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
LUA_API int lua_getmetatable (lua_State *L, int objindex) {
const TValue *obj;
Table *mt = NULL;
- int res;
+ int res = 0;
lua_lock(L);
obj = index2addr(L, objindex);
switch (ttnov(obj)) {
@@ -678,9 +690,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
mt = G(L)->mt[ttnov(obj)];
break;
}
- if (mt == NULL)
- res = 0;
- else {
+ if (mt != NULL) {
sethvalue(L, L->top, mt);
api_incr_top(L);
res = 1;
@@ -743,6 +753,18 @@ 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) {
+ StkId t;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ t = index2addr(L, idx);
+ setivalue(L->top++, n);
+ luaV_settable(L, t, L->top - 1, L->top - 2);
+ L->top -= 2; /* pop value and key */
+ lua_unlock(L);
+}
+
+
LUA_API void lua_rawset (lua_State *L, int idx) {
StkId o;
Table *t;
@@ -854,8 +876,8 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
"results from function overflow current stack size")
-LUA_API void lua_callk (lua_State *L, int nargs, int nresults, lua_Ctx ctx,
- lua_KFunction k) {
+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(k == NULL || !isLua(L->ci),
@@ -894,7 +916,7 @@ static void f_call (lua_State *L, void *ud) {
LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
- lua_Ctx ctx, lua_KFunction k) {
+ lua_KContext ctx, lua_KFunction k) {
struct CallS c;
int status;
ptrdiff_t func;
diff --git a/src/lauxlib.c b/src/lauxlib.c
index abf589ae..0a6cea0a 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.267 2014/07/19 14:37:09 roberto Exp $
+** $Id: lauxlib.c,v 1.270 2014/10/22 11:44:20 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -82,12 +82,12 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
static void pushfuncname (lua_State *L, lua_Debug *ar) {
if (*ar->namewhat != '\0') /* is there a name? */
- lua_pushfstring(L, "function " LUA_QS, ar->name);
+ lua_pushfstring(L, "function '%s'", ar->name);
else if (*ar->what == 'm') /* main? */
lua_pushliteral(L, "main chunk");
else if (*ar->what == 'C') {
if (pushglobalfuncname(L, ar)) {
- lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
+ lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
lua_remove(L, -2); /* remove name */
}
else
@@ -158,25 +158,25 @@ LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
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 " LUA_QS " on bad self (%s)",
+ 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 " LUA_QS " (%s)",
+ 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 = luaL_typename(L, arg);
- if (lua_getmetatable(L, arg)) {
- if (lua_getfield(L, -1, "__name") == LUA_TSTRING)
- typearg = lua_tostring(L, -1);
- }
+ 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";
+ 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);
}
@@ -229,7 +229,7 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
}
-#if !defined(inspectstat) /* { */
+#if !defined(l_inspectstat) /* { */
#if defined(LUA_USE_POSIX)
@@ -238,13 +238,13 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
/*
** use appropriate macros to interpret 'pclose' return status
*/
-#define inspectstat(stat,what) \
+#define l_inspectstat(stat,what) \
if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
#else
-#define inspectstat(stat,what) /* no op */
+#define l_inspectstat(stat,what) /* no op */
#endif
@@ -256,7 +256,7 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) {
if (stat == -1) /* error? */
return luaL_fileresult(L, 0, NULL);
else {
- inspectstat(stat, what); /* interpret result */
+ l_inspectstat(stat, what); /* interpret result */
if (*what == 'e' && stat == 0) /* successful termination? */
lua_pushboolean(L, 1);
else
@@ -335,7 +335,7 @@ LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
if (strcmp(lst[i], name) == 0)
return i;
return luaL_argerror(L, arg,
- lua_pushfstring(L, "invalid option " LUA_QS, name));
+ lua_pushfstring(L, "invalid option '%s'", name));
}
@@ -701,22 +701,23 @@ LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
if (!lua_getmetatable(L, obj)) /* no metatable? */
- return 0;
- lua_pushstring(L, event);
- if (lua_rawget(L, -2) == LUA_TNIL) { /* is metafield nil? */
- lua_pop(L, 2); /* remove metatable and metafield */
- return 0;
- }
+ return LUA_TNIL;
else {
- lua_remove(L, -2); /* remove only metatable */
- return 1;
+ 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)) /* no metafield? */
+ if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */
return 0;
lua_pushvalue(L, obj);
lua_call(L, 1, 1);
@@ -822,7 +823,7 @@ LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
/* 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 " LUA_QS, modname);
+ luaL_error(L, "name conflict for module '%s'", modname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */
}
diff --git a/src/lauxlib.h b/src/lauxlib.h
index b5560143..cecceb3f 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.125 2014/06/26 17:25:11 roberto Exp $
+** $Id: lauxlib.h,v 1.126 2014/10/01 11:54:56 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -115,10 +115,6 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
((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_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)))
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
@@ -210,15 +206,21 @@ LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
/*
** {============================================================
-** Compatibility with deprecated unsigned conversions
+** Compatibility with deprecated conversions
** =============================================================
*/
-#if defined(LUA_COMPAT_APIUNSIGNED)
+#if defined(LUA_COMPAT_APIINTCASTS)
-#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
+#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
/* }============================================================ */
diff --git a/src/lbaselib.c b/src/lbaselib.c
index de1a767f..af04db0d 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.293 2014/07/24 19:33:29 roberto Exp $
+** $Id: lbaselib.c,v 1.303 2014/10/17 19:17:55 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -32,8 +32,7 @@ static int luaB_print (lua_State *L) {
lua_call(L, 1, 1);
s = lua_tolstring(L, -1, &l); /* get result */
if (s == NULL)
- return luaL_error(L,
- LUA_QL("tostring") " must return a string to " LUA_QL("print"));
+ return luaL_error(L, "'tostring' must return a string to 'print'");
if (i>1) luai_writestring("\t", 1);
luai_writestring(s, l);
lua_pop(L, 1); /* pop result */
@@ -78,7 +77,7 @@ static int luaB_tonumber (lua_State *L) {
else {
size_t l;
const char *s = lua_tolstring(L, 1, &l);
- if (s != NULL && lua_strtonum(L, s) == l + 1)
+ if (s != NULL && lua_stringtonumber(L, s) == l + 1)
return 1; /* successful conversion to number */
/* else not a number */
}
@@ -87,11 +86,11 @@ static int luaB_tonumber (lua_State *L) {
size_t l;
const char *s;
lua_Integer n = 0; /* to avoid warnings */
- int base = luaL_checkint(L, 2);
+ lua_Integer base = luaL_checkinteger(L, 2);
luaL_checktype(L, 1, LUA_TSTRING); /* before 'luaL_checklstring'! */
s = luaL_checklstring(L, 1, &l);
luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
- if (b_str2int(s, base, &n) == s + l) {
+ if (b_str2int(s, (int)base, &n) == s + l) {
lua_pushinteger(L, n);
return 1;
} /* else not a number */
@@ -102,7 +101,7 @@ static int luaB_tonumber (lua_State *L) {
static int luaB_error (lua_State *L) {
- int level = luaL_optint(L, 2, 1);
+ int level = (int)luaL_optinteger(L, 2, 1);
lua_settop(L, 1);
if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
luaL_where(L, level);
@@ -129,7 +128,7 @@ static int luaB_setmetatable (lua_State *L) {
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"))
+ 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);
@@ -180,7 +179,7 @@ static int luaB_collectgarbage (lua_State *L) {
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
LUA_GCISRUNNING};
int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
- int ex = luaL_optint(L, 2, 0);
+ int ex = (int)luaL_optinteger(L, 2, 0);
int res = lua_gc(L, o, ex);
switch (o) {
case LUA_GCCOUNT: {
@@ -212,7 +211,7 @@ static int luaB_type (lua_State *L) {
static int pairsmeta (lua_State *L, const char *method, int iszero,
lua_CFunction iter) {
- if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */
+ if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */
luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */
lua_pushcfunction(L, iter); /* will return generator, */
lua_pushvalue(L, 1); /* state, */
@@ -248,7 +247,7 @@ static int luaB_pairs (lua_State *L) {
** Traversal function for 'ipairs' for raw tables
*/
static int ipairsaux_raw (lua_State *L) {
- int i = luaL_checkint(L, 2) + 1;
+ lua_Integer i = luaL_checkinteger(L, 2) + 1;
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushinteger(L, i);
return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2;
@@ -259,17 +258,9 @@ static int ipairsaux_raw (lua_State *L) {
** Traversal function for 'ipairs' for tables with metamethods
*/
static int ipairsaux (lua_State *L) {
- int i = luaL_checkint(L, 2) + 1;
- if (i > luaL_len(L, 1)) { /* larger than length? */
- lua_pushnil(L); /* end traversal */
- return 1;
- }
- else {
- lua_pushinteger(L, i);
- lua_pushinteger(L, i); /* key for indexing table */
- lua_gettable(L, 1);
- return 2;
- }
+ lua_Integer i = luaL_checkinteger(L, 2) + 1;
+ lua_pushinteger(L, i);
+ return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
}
@@ -279,10 +270,8 @@ static int ipairsaux (lua_State *L) {
** that can affect the traversal.
*/
static int luaB_ipairs (lua_State *L) {
- lua_CFunction iter =
- (luaL_getmetafield(L, 1, "__len") ||
- luaL_getmetafield(L, 1, "__index"))
- ? ipairsaux : ipairsaux_raw;
+ lua_CFunction iter = (luaL_getmetafield(L, 1, "__index") != LUA_TNIL)
+ ? ipairsaux : ipairsaux_raw;
#if defined(LUA_COMPAT_IPAIRS)
return pairsmeta(L, "__ipairs", 1, iter);
#else
@@ -380,7 +369,7 @@ static int luaB_load (lua_State *L) {
/* }====================================================== */
-static int dofilecont (lua_State *L, int d1, lua_Ctx d2) {
+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;
}
@@ -415,11 +404,11 @@ static int luaB_select (lua_State *L) {
return 1;
}
else {
- int i = luaL_checkint(L, 1);
+ 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 - i;
+ return n - (int)i;
}
}
@@ -431,14 +420,14 @@ static int luaB_select (lua_State *L) {
** 'extra' values (where 'extra' is exactly the number of items to be
** ignored).
*/
-static int finishpcall (lua_State *L, int status, lua_Ctx extra) {
+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) - extra; /* return all results */
+ return lua_gettop(L) - (int)extra; /* return all results */
}
diff --git a/src/lbitlib.c b/src/lbitlib.c
index dfec1d31..cca6f402 100644
--- a/src/lbitlib.c
+++ b/src/lbitlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbitlib.c,v 1.26 2014/05/15 19:28:34 roberto Exp $
+** $Id: lbitlib.c,v 1.27 2014/10/01 11:54:56 roberto Exp $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/
@@ -89,7 +89,7 @@ static int b_not (lua_State *L) {
}
-static int b_shift (lua_State *L, lua_Unsigned r, int i) {
+static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) {
if (i < 0) { /* shift right? */
i = -i;
r = trim(r);
@@ -107,18 +107,18 @@ static int b_shift (lua_State *L, lua_Unsigned r, int i) {
static int b_lshift (lua_State *L) {
- return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
+ return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkinteger(L, 2));
}
static int b_rshift (lua_State *L) {
- return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
+ return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkinteger(L, 2));
}
static int b_arshift (lua_State *L) {
lua_Unsigned r = luaL_checkunsigned(L, 1);
- int i = luaL_checkint(L, 2);
+ 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 */
@@ -131,9 +131,9 @@ static int b_arshift (lua_State *L) {
}
-static int b_rot (lua_State *L, int i) {
+static int b_rot (lua_State *L, lua_Integer d) {
lua_Unsigned r = luaL_checkunsigned(L, 1);
- i &= (LUA_NBITS - 1); /* i = i % NBITS */
+ 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));
@@ -143,12 +143,12 @@ static int b_rot (lua_State *L, int i) {
static int b_lrot (lua_State *L) {
- return b_rot(L, luaL_checkint(L, 2));
+ return b_rot(L, luaL_checkinteger(L, 2));
}
static int b_rrot (lua_State *L) {
- return b_rot(L, -luaL_checkint(L, 2));
+ return b_rot(L, -luaL_checkinteger(L, 2));
}
@@ -159,14 +159,14 @@ static int b_rrot (lua_State *L) {
** 'width' being used uninitialized.)
*/
static int fieldargs (lua_State *L, int farg, int *width) {
- int f = luaL_checkint(L, farg);
- int w = luaL_optint(L, farg + 1, 1);
+ 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 = w;
- return f;
+ *width = (int)w;
+ return (int)f;
}
diff --git a/src/lcorolib.c b/src/lcorolib.c
index fae85b95..cb6cfe5a 100644
--- a/src/lcorolib.c
+++ b/src/lcorolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcorolib.c,v 1.6 2014/05/08 13:52:20 roberto Exp $
+** $Id: lcorolib.c,v 1.7 2014/09/01 18:00:04 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
@@ -19,7 +19,7 @@
static lua_State *getco (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
- luaL_argcheck(L, co, 1, "coroutine expected");
+ luaL_argcheck(L, co, 1, "thread expected");
return co;
}
diff --git a/src/ldblib.c b/src/ldblib.c
index db79de38..3be75b55 100644
--- a/src/ldblib.c
+++ b/src/ldblib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldblib.c,v 1.139 2014/05/15 19:27:33 roberto Exp $
+** $Id: ldblib.c,v 1.143 2014/10/17 11:07:26 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -21,33 +21,6 @@
#define HOOKKEY "_HKEY"
-static int db_Csize (lua_State *L) {
- static struct {
- char c;
- unsigned char sz;
- } sizes[] = {
- {'I', sizeof(lua_Integer)},
- {'F', sizeof(lua_Number)},
- {'b', CHAR_BIT}, /* here is number of bits (not bytes) */
- {'h', sizeof(short)},
- {'i', sizeof(int)},
- {'l', sizeof(long)},
- {'z', sizeof(size_t)},
- {'f', sizeof(float)},
- {'d', sizeof(double)}
- };
- const char *s = luaL_checkstring(L, 1);
- int i;
- for (i = 0; i < (int)(sizeof(sizes)/sizeof(sizes[0])); i++) {
- if (*s == sizes[i].c) {
- lua_pushinteger(L, sizes[i].sz);
- return 1;
- }
- }
- return luaL_argerror(L, 1, lua_pushfstring(L, "invalid option '%c'", *s));
-}
-
-
static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
@@ -160,7 +133,7 @@ static int db_getinfo (lua_State *L) {
lua_xmove(L, L1, 1);
}
else { /* stack level */
- if (!lua_getstack(L1, luaL_checkint(L, arg + 1), &ar)) {
+ if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) {
lua_pushnil(L); /* level out of range */
return 1;
}
@@ -201,14 +174,15 @@ static int db_getlocal (lua_State *L) {
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
const char *name;
- int nvar = luaL_checkint(L, arg+2); /* local-variable index */
+ 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 */
- if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
+ 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");
name = lua_getlocal(L1, &ar, nvar);
if (name) {
@@ -229,12 +203,13 @@ static int db_setlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
- if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
+ 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");
luaL_checkany(L, arg+3);
lua_settop(L, arg+3);
lua_xmove(L, L1, 1);
- lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
+ lua_pushstring(L, lua_setlocal(L1, &ar, (int)luaL_checkinteger(L, arg+2)));
return 1;
}
@@ -244,7 +219,7 @@ static int db_setlocal (lua_State *L) {
*/
static int auxupvalue (lua_State *L, int get) {
const char *name;
- int n = luaL_checkint(L, 2); /* upvalue index */
+ 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;
@@ -270,7 +245,7 @@ static int db_setupvalue (lua_State *L) {
** returns its index
*/
static int checkupval (lua_State *L, int argf, int argnup) {
- int nup = luaL_checkint(L, argnup); /* upvalue index */
+ 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");
@@ -359,7 +334,7 @@ static int db_sethook (lua_State *L) {
else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checktype(L, arg+1, LUA_TFUNCTION);
- count = luaL_optint(L, arg+3, 0);
+ count = (int)luaL_optinteger(L, arg + 3, 0);
func = hookf; mask = makemask(smask, count);
}
if (gethooktable(L) == 0) { /* creating hook table? */
@@ -418,7 +393,7 @@ static int db_traceback (lua_State *L) {
if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */
lua_pushvalue(L, arg + 1); /* return it untouched */
else {
- int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0);
+ int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0);
luaL_traceback(L, L1, msg, level);
}
return 1;
@@ -426,7 +401,6 @@ static int db_traceback (lua_State *L) {
static const luaL_Reg dblib[] = {
- {"Csize", db_Csize},
{"debug", db_debug},
{"getuservalue", db_getuservalue},
{"gethook", db_gethook},
diff --git a/src/ldebug.c b/src/ldebug.c
index 3321d9f1..cf7d7ca6 100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.100 2014/07/30 14:00:14 roberto Exp $
+** $Id: ldebug.c,v 2.101 2014/10/17 16:28:21 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -515,7 +515,7 @@ static const char *varinfo (lua_State *L, const TValue *o) {
kind = getobjname(ci_func(ci)->p, currentpc(ci),
cast_int(o - ci->u.l.base), &name);
}
- return (kind) ? luaO_pushfstring(L, " (%s " LUA_QS ")", kind, name) : "";
+ return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
}
diff --git a/src/ldo.c b/src/ldo.c
index 500de40d..a2c64234 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.126 2014/07/17 13:53:37 roberto Exp $
+** $Id: ldo.c,v 2.130 2014/10/17 16:28:21 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -111,15 +111,16 @@ l_noret luaD_throw (lua_State *L, int errcode) {
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(L)->mainthread->errorJmp) { /* main thread has a handler? */
- setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */
- luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */
+ 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(L)->panic) { /* panic function? */
+ if (g->panic) { /* panic function? */
lua_unlock(L);
- G(L)->panic(L); /* call it (last chance to jump out) */
+ g->panic(L); /* call it (last chance to jump out) */
}
abort();
}
@@ -593,7 +594,7 @@ LUA_API int lua_isyieldable (lua_State *L) {
}
-LUA_API int lua_yieldk (lua_State *L, int nresults, lua_Ctx ctx,
+LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
lua_KFunction k) {
CallInfo *ci = L->ci;
luai_userstateyield(L, nresults);
@@ -661,7 +662,7 @@ struct SParser { /* data to `f_parser' */
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 " LUA_QS ")", x, mode);
+ "attempt to load a %s chunk (mode is '%s')", x, mode);
luaD_throw(L, LUA_ERRSYNTAX);
}
}
diff --git a/src/lgc.c b/src/lgc.c
index 84e8778d..ebeae89e 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.192 2014/07/29 16:22:24 roberto Exp $
+** $Id: lgc.c,v 2.196 2014/10/03 12:54:37 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -100,9 +100,9 @@ static void reallymarkobject (global_State *g, GCObject *o);
/*
-** link table 'h' into list pointed by 'p'
+** link collectable object 'o' into list pointed by 'p'
*/
-#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h))
+#define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o))
/*
@@ -159,8 +159,7 @@ 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) */
- t->gclist = g->grayagain;
- g->grayagain = obj2gco(t);
+ linkgclist(t, g->grayagain);
}
@@ -243,27 +242,23 @@ static void reallymarkobject (global_State *g, GCObject *o) {
break;
}
case LUA_TLCL: {
- gco2lcl(o)->gclist = g->gray;
- g->gray = o;
+ linkgclist(gco2lcl(o), g->gray);
break;
}
case LUA_TCCL: {
- gco2ccl(o)->gclist = g->gray;
- g->gray = o;
+ linkgclist(gco2ccl(o), g->gray);
break;
}
case LUA_TTABLE: {
- linktable(gco2t(o), &g->gray);
+ linkgclist(gco2t(o), g->gray);
break;
}
case LUA_TTHREAD: {
- gco2th(o)->gclist = g->gray;
- g->gray = o;
+ linkgclist(gco2th(o), g->gray);
break;
}
case LUA_TPROTO: {
- gco2p(o)->gclist = g->gray;
- g->gray = o;
+ linkgclist(gco2p(o), g->gray);
break;
}
default: lua_assert(0); break;
@@ -340,12 +335,18 @@ static void restartcollection (global_State *g) {
** =======================================================
*/
+/*
+** 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 (do not
- traverse it just to check) */
+ /* 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++) {
+ for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
checkdeadkey(n);
if (ttisnil(gval(n))) /* entry is empty? */
removeentry(n); /* remove it */
@@ -356,20 +357,30 @@ static void traverseweakvalue (global_State *g, Table *h) {
hasclears = 1; /* table will have to be cleared */
}
}
- if (hasclears)
- linktable(h, &g->weak); /* has to be cleared later */
- else /* no white values */
- linktable(h, &g->grayagain); /* no need to clean */
+ 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 prop = 0; /* true if table has entry "white-key -> white-value" */
+ int hasww = 0; /* true if table has entry "white-key -> white-value" */
Node *n, *limit = gnodelast(h);
- int i;
- /* traverse array part (numeric keys are 'strong') */
+ unsigned int i;
+ /* traverse array part */
for (i = 0; i < h->sizearray; i++) {
if (valiswhite(&h->array[i])) {
marked = 1;
@@ -384,26 +395,27 @@ static int traverseephemeron (global_State *g, Table *h) {
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? */
- prop = 1; /* must propagate again */
+ hasww = 1; /* white-white entry */
}
else if (valiswhite(gval(n))) { /* value not marked yet? */
marked = 1;
reallymarkobject(g, gcvalue(gval(n))); /* mark it now */
}
}
- if (prop)
- linktable(h, &g->ephemeron); /* have to propagate again */
- else if (hasclears) /* does table have white keys? */
- linktable(h, &g->allweak); /* may have to clean white keys */
- else /* no white keys */
- linktable(h, &g->grayagain); /* no need to clean */
+ /* 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);
- int i;
+ 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 */
@@ -433,7 +445,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
else if (!weakvalue) /* strong values? */
traverseephemeron(g, h);
else /* all weak */
- linktable(h, &g->allweak); /* nothing to traverse now */
+ linkgclist(h, g->allweak); /* nothing to traverse now */
}
else /* not weak */
traversestrongtable(g, h);
@@ -548,8 +560,7 @@ static void propagatemark (global_State *g) {
case LUA_TTHREAD: {
lua_State *th = gco2th(o);
g->gray = th->gclist; /* remove from 'gray' list */
- th->gclist = g->grayagain;
- g->grayagain = o; /* insert into 'grayagain' list */
+ linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
black2gray(o);
size = traversethread(g, th);
break;
@@ -571,35 +582,12 @@ static void propagateall (global_State *g) {
}
-static void propagatelist (global_State *g, GCObject *l) {
- lua_assert(g->gray == NULL); /* no grays left */
- g->gray = l;
- propagateall(g); /* traverse all elements from 'l' */
-}
-
-/*
-** retraverse all gray lists. Because tables may be reinserted in other
-** lists when traversed, traverse the original lists to avoid traversing
-** twice the same table (which is not wrong, but inefficient)
-*/
-static void retraversegrays (global_State *g) {
- GCObject *weak = g->weak; /* save original lists */
- GCObject *grayagain = g->grayagain;
- GCObject *ephemeron = g->ephemeron;
- g->weak = g->grayagain = g->ephemeron = NULL;
- propagateall(g); /* traverse main gray list */
- propagatelist(g, grayagain);
- propagatelist(g, weak);
- propagatelist(g, ephemeron);
-}
-
-
static void convergeephemerons (global_State *g) {
int changed;
do {
GCObject *w;
GCObject *next = g->ephemeron; /* get ephemeron list */
- g->ephemeron = NULL; /* tables will return to this list when traversed */
+ g->ephemeron = NULL; /* tables may return to this list when traversed */
changed = 0;
while ((w = next) != NULL) {
next = gco2t(w)->gclist;
@@ -647,7 +635,7 @@ 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);
- int i;
+ unsigned int i;
for (i = 0; i < h->sizearray; i++) {
TValue *o = &h->array[i];
if (iscleared(g, o)) /* value was collected? */
@@ -864,7 +852,7 @@ static GCObject **findlast (GCObject **p) {
/*
** move all unreachable objects (or 'all' objects) that need
-** finalization from list 'p' to list 'tobefnz' (to be finalized)
+** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
*/
static void separatetobefnz (global_State *g, int all) {
GCObject *curr;
@@ -875,7 +863,7 @@ static void separatetobefnz (global_State *g, int all) {
if (!(iswhite(curr) || all)) /* not being collected? */
p = &curr->next; /* don't bother with it */
else {
- *p = curr->next; /* remove 'curr' from "fin" list */
+ *p = curr->next; /* remove 'curr' from 'finobj' list */
curr->next = *lastnext; /* link at the end of 'tobefnz' list */
*lastnext = curr;
lastnext = &curr->next;
@@ -903,7 +891,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
/* 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 "fin" list */
+ o->next = g->finobj; /* link it in 'finobj' list */
g->finobj = o;
l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */
}
@@ -972,19 +960,21 @@ static l_mem atomic (lua_State *L) {
global_State *g = G(L);
l_mem work;
GCObject *origweak, *origall;
- g->GCmemtrav = 0; /* start counting work */
+ 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 basic metatables */
+ 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 (re)count grays) */
- /* traverse objects caught by write barrier and by 'remarkupvals' */
- retraversegrays(g);
+ work = g->GCmemtrav; /* stop counting (do not recount gray-agains) */
+ g->gray = grayagain;
+ propagateall(g); /* traverse 'grayagain' list */
g->GCmemtrav = 0; /* restart counting */
convergeephemerons(g);
/* at this point, all strongly accessible objects are marked. */
diff --git a/src/liolib.c b/src/liolib.c
index 96cb1a31..9101ecae 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c,v 2.128 2014/07/29 16:01:00 roberto Exp $
+** $Id: liolib.c,v 2.136 2014/10/22 16:55:57 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -70,7 +70,7 @@
/* ANSI definitions */
#define l_popen(L,c,m) \
((void)((void)c, m), \
- luaL_error(L, LUA_QL("popen") " not supported"), \
+ luaL_error(L, "'popen' not supported"), \
(FILE*)0)
#define l_pclose(L,file) ((void)L, (void)file, -1)
@@ -135,6 +135,7 @@
#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")
@@ -193,9 +194,14 @@ static LStream *newprefile (lua_State *L) {
}
+/*
+** 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);
- lua_CFunction cf = p->closef;
+ volatile lua_CFunction cf = p->closef;
p->closef = NULL; /* mark stream as closed */
return (*cf)(L); /* close it */
}
@@ -239,7 +245,7 @@ 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 " LUA_QS " (%s)", fname, strerror(errno));
+ luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno));
}
@@ -285,7 +291,7 @@ static FILE *getiofile (lua_State *L, const char *findex) {
lua_getfield(L, LUA_REGISTRYINDEX, findex);
p = (LStream *)lua_touserdata(L, -1);
if (isclosed(p))
- luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX));
+ luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN);
return p->f;
}
@@ -413,15 +419,15 @@ static int readdigits (RN *rn, int hex) {
/* access to locale "radix character" (decimal point) */
-#if !defined(getlocaledecpoint)
-#define getlocaledecpoint() (localeconv()->decimal_point[0])
+#if !defined(l_getlocaledecpoint)
+#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
/*
** Read a number: first reads a valid prefix of a numeral into a buffer.
-** Then it calls 'lua_strtonum' to check whether the format is correct
-** and to convert it to a Lua number
+** 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;
@@ -429,7 +435,7 @@ static int read_number (lua_State *L, FILE *f) {
int hex = 0;
char decp[2] = ".";
rn.f = f; rn.n = 0;
- decp[0] = getlocaledecpoint(); /* get decimal point from locale */
+ decp[0] = l_getlocaledecpoint(); /* get decimal point from locale */
l_lockfile(rn.f);
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
test2(&rn, "-+"); /* optional signal */
@@ -447,7 +453,7 @@ static int read_number (lua_State *L, FILE *f) {
ungetc(rn.c, rn.f); /* unread look-ahead char */
l_unlockfile(rn.f);
rn.buff[rn.n] = '\0'; /* finish string */
- if (lua_strtonum(L, rn.buff)) /* is this a valid number? */
+ if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */
return 1; /* ok */
else { /* invalid format */
lua_pushnil(L); /* "result" to be removed */
@@ -576,7 +582,7 @@ static int io_readline (lua_State *L) {
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_isnil(L, -n)) /* read at least one value? */
+ 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? */
diff --git a/src/llex.c b/src/llex.c
index 6a052080..af204f52 100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 2.80 2014/07/18 13:36:14 roberto Exp $
+** $Id: llex.c,v 2.84 2014/10/22 11:44:20 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -78,14 +78,13 @@ void luaX_init (lua_State *L) {
const char *luaX_token2str (LexState *ls, int token) {
if (token < FIRST_RESERVED) { /* single-byte symbols? */
- lua_assert(token == cast(unsigned char, token));
- return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
- luaO_pushfstring(ls->L, "char(%d)", token);
+ 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, LUA_QS, s);
+ return luaO_pushfstring(ls->L, "'%s'", s);
else /* names, strings, and numerals */
return s;
}
@@ -97,7 +96,7 @@ static const char *txtToken (LexState *ls, int token) {
case TK_NAME: case TK_STRING:
case TK_FLT: case TK_INT:
save(ls, '\0');
- return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
+ return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff));
default:
return luaX_token2str(ls, token);
}
@@ -219,8 +218,8 @@ static void buffreplace (LexState *ls, char from, char to) {
}
-#if !defined(getlocaledecpoint)
-#define getlocaledecpoint() (localeconv()->decimal_point[0])
+#if !defined(l_getlocaledecpoint)
+#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
@@ -232,7 +231,7 @@ static void buffreplace (LexState *ls, char from, char to) {
*/
static void trydecpoint (LexState *ls, TValue *o) {
char old = ls->decpoint;
- ls->decpoint = getlocaledecpoint();
+ ls->decpoint = l_getlocaledecpoint();
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
if (!buff2num(ls->buff, o)) {
/* format error with correct decimal point: no more options */
@@ -360,8 +359,8 @@ static int readhexaesc (LexState *ls) {
}
-static unsigned int readutf8esc (LexState *ls) {
- unsigned int 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 '{'");
diff --git a/src/lmathlib.c b/src/lmathlib.c
index 312df517..523e0b64 100644
--- a/src/lmathlib.c
+++ b/src/lmathlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmathlib.c,v 1.108 2014/07/28 17:35:47 roberto Exp $
+** $Id: lmathlib.c,v 1.110 2014/10/08 19:57:31 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -153,7 +153,7 @@ static int math_modf (lua_State *L) {
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) ? 0.0 : (n - ip));
+ lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
}
return 2;
}
@@ -192,12 +192,12 @@ static int math_exp (lua_State *L) {
}
static int math_deg (lua_State *L) {
- lua_pushnumber(L, luaL_checknumber(L, 1) * (180.0 / PI));
+ 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 / 180.0));
+ lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
return 1;
}
@@ -239,7 +239,7 @@ static int math_random (lua_State *L) {
double r = (double)l_rand() * (1.0 / ((double)RAND_MAX + 1.0));
switch (lua_gettop(L)) { /* check number of arguments */
case 0: { /* no arguments */
- lua_pushnumber(L, r); /* Number between 0 and 1 */
+ lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */
return 1;
}
case 1: { /* only upper limit */
@@ -324,7 +324,7 @@ static int math_frexp (lua_State *L) {
static int math_ldexp (lua_State *L) {
lua_Number x = luaL_checknumber(L, 1);
- int ep = luaL_checkint(L, 2);
+ int ep = (int)luaL_checkinteger(L, 2);
lua_pushnumber(L, l_mathop(ldexp)(x, ep));
return 1;
}
@@ -389,7 +389,7 @@ LUAMOD_API int luaopen_math (lua_State *L) {
luaL_newlib(L, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
- lua_pushnumber(L, HUGE_VAL);
+ lua_pushnumber(L, (lua_Number)HUGE_VAL);
lua_setfield(L, -2, "huge");
lua_pushinteger(L, LUA_MAXINTEGER);
lua_setfield(L, -2, "maxinteger");
diff --git a/src/lmem.h b/src/lmem.h
index 5f850999..f701ae0f 100644
--- a/src/lmem.h
+++ b/src/lmem.h
@@ -1,5 +1,5 @@
/*
-** $Id: lmem.h,v 1.40 2013/02/20 14:08:21 roberto Exp $
+** $Id: lmem.h,v 1.41 2014/10/08 20:25:51 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -15,20 +15,26 @@
/*
-** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is
-** always constant.
-** The macro is somewhat complex to avoid warnings:
-** +1 avoids warnings of "comparison has constant result";
-** cast to 'void' avoids warnings of "value unused".
+** 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) \
- (cast(void, \
- (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \
+ (((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)))
#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_reallocv(L, (b), n, 0, 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)))
diff --git a/src/loadlib.c b/src/loadlib.c
index 4894188a..9cf5e69d 100644
--- a/src/loadlib.c
+++ b/src/loadlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.116 2014/07/29 16:01:00 roberto Exp $
+** $Id: loadlib.c,v 1.117 2014/10/17 16:28:21 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -396,7 +396,7 @@ static const char *searchpath (lua_State *L, const char *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 " LUA_QS, filename);
+ lua_pushfstring(L, "\n\tno file '%s'", filename);
lua_remove(L, -2); /* remove file name */
luaL_addvalue(&msg); /* concatenate error msg. entry */
}
@@ -426,7 +426,7 @@ static const char *findfile (lua_State *L, const char *name,
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
- luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
+ luaL_error(L, "'package.%s' must be a string", pname);
return searchpath(L, name, path, ".", dirsep);
}
@@ -437,8 +437,7 @@ static int checkload (lua_State *L, int stat, const char *filename) {
return 2; /* return open function and file name */
}
else
- return luaL_error(L, "error loading module " LUA_QS
- " from file " LUA_QS ":\n\t%s",
+ return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s",
lua_tostring(L, 1), filename, lua_tostring(L, -1));
}
@@ -499,8 +498,7 @@ static int searcher_Croot (lua_State *L) {
if (stat != ERRFUNC)
return checkload(L, 0, filename); /* real error */
else { /* open function not found */
- lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
- name, filename);
+ lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename);
return 1;
}
}
@@ -524,14 +522,13 @@ static void findloader (lua_State *L, const char *name) {
luaL_buffinit(L, &msg);
lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
if (!lua_istable(L, 3))
- luaL_error(L, LUA_QL("package.searchers") " must be a table");
+ 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 " LUA_QS " not found:%s",
- name, lua_tostring(L, -1));
+ luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
}
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
@@ -589,7 +586,7 @@ static void set_env (lua_State *L) {
if (lua_getstack(L, 1, &ar) == 0 ||
lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
lua_iscfunction(L, -1))
- luaL_error(L, LUA_QL("module") " not called from a Lua function");
+ 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 */
diff --git a/src/lobject.c b/src/lobject.c
index 2bcdbfa1..28048dd7 100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.88 2014/07/30 14:00:14 roberto Exp $
+** $Id: lobject.c,v 2.93 2014/10/17 16:28:21 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -310,10 +310,11 @@ size_t luaO_str2num (const char *s, TValue *o) {
}
-int luaO_utf8esc (char *buff, unsigned int x) {
+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] = x;
+ buff[UTF8BUFFSZ - 1] = cast(char, x);
else { /* need continuation bytes */
unsigned int mfb = 0x3f; /* maximum that fits in first byte */
do {
@@ -321,7 +322,7 @@ int luaO_utf8esc (char *buff, unsigned int x) {
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] = (~mfb << 1) | x; /* add first byte */
+ buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */
}
return n;
}
@@ -359,7 +360,7 @@ static void pushstr (lua_State *L, const char *str, size_t l) {
/* this function handles only '%d', '%c', '%f', '%p', and '%s'
- conventional formats, plus Lua-specific '%L' and '%U' */
+ 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 (;;) {
@@ -376,7 +377,10 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
}
case 'c': {
char buff = cast(char, va_arg(argp, int));
- pushstr(L, &buff, 1);
+ 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': {
@@ -402,7 +406,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
}
case 'U': {
char buff[UTF8BUFFSZ];
- int l = luaO_utf8esc(buff, va_arg(argp, int));
+ int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
pushstr(L, buff + UTF8BUFFSZ - l, l);
break;
}
@@ -411,9 +415,8 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
break;
}
default: {
- luaG_runerror(L,
- "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
- *(e + 1));
+ luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'",
+ *(e + 1));
}
}
n += 2;
diff --git a/src/lobject.h b/src/lobject.h
index 9972e08b..054df783 100644
--- a/src/lobject.h
+++ b/src/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.101 2014/07/30 14:00:14 roberto Exp $
+** $Id: lobject.h,v 2.103 2014/10/01 11:52:33 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -487,7 +487,7 @@ typedef struct Table {
CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
- int sizearray; /* size of `array' array */
+ unsigned int sizearray; /* size of `array' array */
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
@@ -521,7 +521,7 @@ LUAI_DDEC const TValue luaO_nilobject_;
LUAI_FUNC int luaO_int2fb (unsigned int x);
LUAI_FUNC int luaO_fb2int (int x);
-LUAI_FUNC int luaO_utf8esc (char *buff, unsigned 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);
diff --git a/src/lopcodes.h b/src/lopcodes.h
index 3f5d0153..eb6c2a0d 100644
--- a/src/lopcodes.h
+++ b/src/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.146 2013/12/30 20:47:58 roberto Exp $
+** $Id: lopcodes.h,v 1.147 2014/10/20 18:29:55 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -203,7 +203,7 @@ 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_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++ */
diff --git a/src/loslib.c b/src/loslib.c
index 3be1d999..c721e711 100644
--- a/src/loslib.c
+++ b/src/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.46 2014/04/29 17:05:13 roberto Exp $
+** $Id: loslib.c,v 1.49 2014/10/17 16:28:21 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -189,7 +189,7 @@ static int getfield (lua_State *L, const char *key, int d) {
res = (int)lua_tointegerx(L, -1, &isnum);
if (!isnum) {
if (d < 0)
- return luaL_error(L, "field " LUA_QS " missing in date table", key);
+ return luaL_error(L, "field '%s' missing in date table", key);
res = d;
}
lua_pop(L, 1);
@@ -295,7 +295,8 @@ static int os_time (lua_State *L) {
static int os_difftime (lua_State *L) {
- lua_pushnumber(L, difftime((l_checktime(L, 1)), (l_checktime(L, 2))));
+ double res = difftime((l_checktime(L, 1)), (l_checktime(L, 2)));
+ lua_pushnumber(L, (lua_Number)res);
return 1;
}
@@ -319,7 +320,7 @@ static int os_exit (lua_State *L) {
if (lua_isboolean(L, 1))
status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
else
- status = luaL_optint(L, 1, EXIT_SUCCESS);
+ 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' */
diff --git a/src/lparser.c b/src/lparser.c
index 1e7e244a..2c009658 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.142 2014/07/21 16:02:10 roberto Exp $
+** $Id: lparser.c,v 2.143 2014/10/17 16:28:21 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -340,7 +340,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) {
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 " LUA_QS,
+ "<goto %s> at line %d jumps into the scope of local '%s'",
getstr(gt->name), gt->line, getstr(vname));
semerror(ls, msg);
}
@@ -457,7 +457,7 @@ static void breaklabel (LexState *ls) {
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 " LUA_QS " for <goto> at line %d";
+ : "no visible label '%s' for <goto> at line %d";
msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
semerror(ls, msg);
}
@@ -761,7 +761,7 @@ static void parlist (LexState *ls) {
f->is_vararg = 1;
break;
}
- default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
+ default: luaX_syntaxerror(ls, "<name> or '...' expected");
}
} while (!f->is_vararg && testnext(ls, ','));
}
@@ -953,7 +953,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
case TK_DOTS: { /* vararg */
FuncState *fs = ls->fs;
check_condition(ls, fs->f->is_vararg,
- "cannot use " LUA_QL("...") " outside a vararg function");
+ "cannot use '...' outside a vararg function");
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
break;
}
@@ -1200,7 +1200,7 @@ static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
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 " LUA_QS " already defined on line %d",
+ "label '%s' already defined on line %d",
getstr(label), ll->arr[i].line);
semerror(fs->ls, msg);
}
@@ -1367,7 +1367,7 @@ static void forstat (LexState *ls, int line) {
switch (ls->t.token) {
case '=': fornum(ls, varname, line); break;
case ',': case TK_IN: forlist(ls, varname); break;
- default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
+ default: luaX_syntaxerror(ls, "'=' or 'in' expected");
}
check_match(ls, TK_END, TK_FOR, line);
leaveblock(fs); /* loop scope (`break' jumps to this point) */
diff --git a/src/lstate.h b/src/lstate.h
index 698bea0d..3ecd4977 100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.114 2014/07/23 17:15:43 roberto Exp $
+** $Id: lstate.h,v 2.117 2014/10/07 18:29:13 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -54,7 +54,13 @@ typedef struct stringtable {
/*
-** information about a call
+** 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 */
@@ -68,7 +74,7 @@ typedef struct CallInfo {
struct { /* only for C functions */
lua_KFunction k; /* continuation in case of yields */
ptrdiff_t old_errfunc;
- lua_Ctx ctx; /* context info. in case of yields */
+ lua_KContext ctx; /* context info. in case of yields */
} c;
} u;
ptrdiff_t extra;
diff --git a/src/lstrlib.c b/src/lstrlib.c
index 05330c80..748e2a81 100644
--- a/src/lstrlib.c
+++ b/src/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.200 2014/07/30 13:59:24 roberto Exp $
+** $Id: lstrlib.c,v 1.205 2014/10/20 16:44:54 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -250,14 +250,14 @@ 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 " LUA_QL("%%") ")");
+ 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 " LUA_QL("]") ")");
+ luaL_error(ms->L, "malformed pattern (missing ']')");
if (*(p++) == L_ESC && p < ms->p_end)
p++; /* skip escapes (e.g. `%]') */
} while (*p != ']');
@@ -332,8 +332,7 @@ static int singlematch (MatchState *ms, const char *s, const char *p,
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 " LUA_QL("%%b") ")");
+ luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')");
if (*s != *p) return NULL;
else {
int b = *p;
@@ -450,8 +449,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
const char *ep; char previous;
p += 2;
if (*p != '[')
- luaL_error(ms->L, "missing " LUA_QL("[") " after "
- LUA_QL("%%f") " in pattern");
+ 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) &&
@@ -694,8 +692,7 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
i++; /* skip ESC */
if (!isdigit(uchar(news[i]))) {
if (news[i] != L_ESC)
- luaL_error(L, "invalid use of " LUA_QL("%c")
- " in replacement string", L_ESC);
+ luaL_error(L, "invalid use of '%c' in replacement string", L_ESC);
luaL_addchar(b, news[i]);
}
else if (news[i] == '0')
@@ -890,7 +887,7 @@ static int str_format (lua_State *L) {
strfrmt = scanformat(L, strfrmt, form);
switch (*strfrmt++) {
case 'c': {
- nb = sprintf(buff, form, luaL_checkint(L, arg));
+ nb = sprintf(buff, form, (int)luaL_checkinteger(L, arg));
break;
}
case 'd': case 'i':
@@ -929,8 +926,8 @@ static int str_format (lua_State *L) {
}
}
default: { /* also treat cases `pnLlh' */
- return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
- LUA_QL("format"), *(strfrmt - 1));
+ return luaL_error(L, "invalid option '%%%c' to 'format'",
+ *(strfrmt - 1));
}
}
luaL_addsize(&b, nb);
@@ -950,212 +947,394 @@ static int str_format (lua_State *L) {
*/
+/* 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)
-/* mask for one character without sign bit ((NB - 1) 1's) */
-#define SM (MC >> 1)
-
/* size of a lua_Integer */
#define SZINT ((int)sizeof(lua_Integer))
-/* maximum size for the binary representation of an integer */
-#define MAXINTSIZE 12
+/* mask for all ones in last byte in a lua Integer */
+#define HIGHERBYTE ((lua_Unsigned)MC << (NB * (SZINT - 1)))
-static union {
+/* dummy union to get native endianness */
+static const union {
int dummy;
char little; /* true iff machine is little endian */
-} const nativeendian = {1};
+} nativeendian = {1};
-static int getendian (lua_State *L, int arg) {
- const char *endian = luaL_optstring(L, arg,
- (nativeendian.little ? "l" : "b"));
- if (*endian == 'n') /* native? */
- return nativeendian.little;
- luaL_argcheck(L, *endian == 'l' || *endian == 'b', arg,
- "endianness must be 'l'/'b'/'n'");
- return (*endian == 'l');
-}
+/* 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))
-static int getintsize (lua_State *L, int arg) {
- int size = luaL_optint(L, arg, 0);
- if (size == 0) size = SZINT;
- luaL_argcheck(L, 1 <= size && size <= MAXINTSIZE, arg,
- "integer size out of valid range");
- return size;
-}
+/*
+** 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;
-/* mask for all ones in last byte in a lua Integer */
-#define HIGHERBYTE ((lua_Unsigned)MC << (NB * (SZINT - 1)))
+/*
+** information to pack/unpack stuff
+*/
+typedef struct Header {
+ lua_State *L;
+ int islittle;
+ int maxalign;
+} Header;
-static int dumpint (char *buff, lua_Integer m, int littleendian, int size) {
- int i;
- lua_Unsigned n = (lua_Unsigned)m;
- lua_Unsigned mask = (m >= 0) ? 0 : HIGHERBYTE; /* sign extension */
- if (littleendian) {
- for (i = 0; i < size - 1; i++) {
- buff[i] = (n & MC);
- n = (n >> NB) | mask;
- }
- }
+
+/*
+** 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) */
+ Keof /* end of format */
+} 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 {
- for (i = size - 1; i > 0; i--) {
- buff[i] = (n & MC);
- n = (n >> NB) | mask;
- }
- }
- buff[i] = (n & MC); /* last byte */
- if (size < SZINT) { /* need test for overflow? */
- /* OK if there are only zeros left in higher bytes,
- or only ones left (excluding non-signal bits in last byte) */
- return ((n & ~(lua_Unsigned)MC) == 0 ||
- (n | SM) == ~(lua_Unsigned)0);
+ int a = 0;
+ do {
+ a = a*10 + *((*fmt)++) - '0';
+ } while (digit(**fmt) && a < (INT_MAX/10 - 10));
+ return a;
}
- else return 1; /* no overflow can occur with full size */
}
-static int dumpint_l (lua_State *L) {
- char buff[MAXINTSIZE];
- lua_Integer n = luaL_checkinteger(L, 1);
- int size = getintsize(L, 2);
- int endian = getendian(L, 3);
- if (dumpint(buff, n, endian, size))
- lua_pushlstring(L, buff, size);
- else
- luaL_error(L, "integer does not fit into given size (%d)", size);
- return 1;
+/*
+** 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)
+ luaL_error(h->L, "integral size (%d) out of limits [1,%d]", sz, MAXINTSIZE);
+ return sz;
}
-/* mask to check higher-order byte + signal bit of next (lower) byte */
-#define HIGHERBYTE1 (HIGHERBYTE | (HIGHERBYTE >> 1))
+/*
+** Initialize Header
+*/
+static void initheader (lua_State *L, Header *h) {
+ h->L = L;
+ h->islittle = nativeendian.little;
+ h->maxalign = 1;
+}
-static int undumpint (const char *buff, lua_Integer *res,
- int littleendian, int size) {
- lua_Unsigned n = 0;
- int i;
- for (i = 0; i < size; i++) {
- if (i >= SZINT) { /* will throw away a byte? */
- /* check for overflow: it is OK to throw away leading zeros for a
- positive number, leading ones for a negative number, and a
- leading zero byte to allow unsigned integers with a 1 in
- its "signal bit" */
- if (!((n & HIGHERBYTE1) == 0 || /* zeros for positive number */
- (n & HIGHERBYTE1) == HIGHERBYTE1 || /* ones for negative number */
- (i == size - 1 && (n & HIGHERBYTE) == 0))) /* leading zero */
- return 0; /* overflow */
+/*
+** 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); return Kchar;
+ case 'z': return Kzstr;
+ case 'x': *size = 1; return Kpadding;
+ case 'X': return Kpaddalign;
+ case ' ': return Knop;
+ case '\0': return Keof;
+ case '<': h->islittle = 1; return Knop;
+ case '>': h->islittle = 0; return Knop;
+ case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); return Knop;
+ default: {
+ luaL_error(h->L, "invalid format option '%c'", opt);
+ return Knop;
}
- n <<= NB;
- n |= (lua_Unsigned)(unsigned char)buff[littleendian ? size - 1 - i : i];
- }
- if (size < SZINT) { /* need sign extension? */
- lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1);
- *res = (lua_Integer)((n ^ mask) - mask); /* do sign extension */
}
- else
- *res = (lua_Integer)n;
- return 1;
}
-static int undumpint_l (lua_State *L) {
- lua_Integer res;
- size_t len;
- const char *s = luaL_checklstring(L, 1, &len);
- lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len);
- int size = getintsize(L, 3);
- int endian = getendian(L, 4);
- luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1,
- "string too short");
- if(undumpint(s + pos - 1, &res, endian, size))
- lua_pushinteger(L, res);
- else
- luaL_error(L, "result does not fit into a Lua integer");
- return 1;
+/*
+** 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 aligment
+** despite its size.
+*/
+static KOption getdetails (Header *h, size_t totalsize,
+ const char **fmt, int *psize, int *ntoalign) {
+ int align;
+ KOption opt;
+ do {
+ opt = getoption(h, fmt, psize);
+ } while (opt == Knop); /* skip no-op options */
+ align = *psize; /* usually, alignment follows size */
+ if (opt == Kpaddalign) { /* 'X' gets alignment from following option */
+ if (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;
}
-static void correctendianness (lua_State *L, char *b, int size, int endianarg) {
- int endian = getendian(L, endianarg);
- if (endian != nativeendian.little) { /* not native endianness? */
- int i = 0;
- while (i < --size) {
- char temp = b[i];
- b[i++] = b[size];
- b[size] = temp;
- }
+static void packint (luaL_Buffer *b, lua_Unsigned n,
+ int islittle, int size, lua_Unsigned mask) {
+ char *buff = luaL_prepbuffsize(b, size);
+ int i;
+ for (i = 0; i < size - 1; i++) {
+ buff[islittle ? i : size - 1 - i] = (n & MC);
+ n = (n >> NB) | mask;
}
+ buff[islittle ? i : size - 1 - i] = (n & MC);
+ luaL_addsize(b, size); /* add result to buffer */
}
-static int getfloatsize (lua_State *L, int arg) {
- const char *size = luaL_optstring(L, arg, "n");
- if (*size == 'n') return sizeof(lua_Number);
- luaL_argcheck(L, *size == 'd' || *size == 'f', arg,
- "size must be 'f'/'d'/'n'");
- return (*size == 'd' ? sizeof(double) : sizeof(float));
+/*
+** 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 dumpfloat_l (lua_State *L) {
- float f; double d;
- char *pn; /* pointer to number */
- lua_Number n = luaL_checknumber(L, 1);
- int size = getfloatsize(L, 2);
- if (size == sizeof(lua_Number))
- pn = (char*)&n;
- else if (size == sizeof(float)) {
- f = (float)n;
- pn = (char*)&f;
- }
- else { /* native lua_Number may be neither float nor double */
- lua_assert(size == sizeof(double));
- d = (double)n;
- pn = (char*)&d;
+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);
+ for (;;) {
+ int size, ntoalign;
+ KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
+ totalsize += ntoalign + size;
+ while (ntoalign-- > 0) luaL_addchar(&b, '\0'); /* fill alignment */
+ arg++;
+ switch (opt) {
+ case Kint: { /* signed integers */
+ lua_Integer n = luaL_checkinteger(L, arg);
+ lua_Unsigned mask = (n < 0) ? HIGHERBYTE : 0; /* sign extension */
+ 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, mask);
+ 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, "wrong length");
+ luaL_addlstring(&b, s, size);
+ 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, '\0'); /* go through */
+ case Kpaddalign: case Knop:
+ arg--; /* undo increment */
+ break;
+ case Keof: /* end of format */
+ luaL_pushresult(&b);
+ return 1;
+ }
}
- correctendianness(L, pn, size, 3);
- lua_pushlstring(L, pn, size);
- return 1;
}
-static int undumpfloat_l (lua_State *L) {
- lua_Number res;
- size_t len;
- const char *s = luaL_checklstring(L, 1, &len);
- lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len);
- int size = getfloatsize(L, 3);
- luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1,
- "string too short");
- if (size == sizeof(lua_Number)) {
- memcpy(&res, s + pos - 1, size);
- correctendianness(L, (char*)&res, size, 4);
+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];
}
- else if (size == sizeof(float)) {
- float f;
- memcpy(&f, s + pos - 1, size);
- correctendianness(L, (char*)&f, size, 4);
- res = (lua_Number)f;
- }
- else { /* native lua_Number may be neither float nor double */
- double d;
- lua_assert(size == sizeof(double));
- memcpy(&d, s + pos - 1, size);
- correctendianness(L, (char*)&d, size, 4);
- res = (lua_Number)d;
+ 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 { /* 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-bit 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);
+ for (;;) {
+ 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;
+ /* 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;
+ break;
+ }
+ case Kzstr: {
+ size_t len = (int)strlen(data + pos);
+ lua_pushlstring(L, data + pos, len);
+ pos += len + 1; /* skip final '\0' */
+ break;
+ }
+ case Kpaddalign: case Kpadding: case Knop:
+ n--; /* undo increment */
+ break;
+ case Keof: /* end of format */
+ lua_pushinteger(L, pos + 1); /* next position */
+ return n;
+ }
+ pos += size;
}
- lua_pushnumber(L, res);
- return 1;
}
/* }====================================================== */
@@ -1176,10 +1355,8 @@ static const luaL_Reg strlib[] = {
{"reverse", str_reverse},
{"sub", str_sub},
{"upper", str_upper},
- {"dumpfloat", dumpfloat_l},
- {"dumpint", dumpint_l},
- {"undumpfloat", undumpfloat_l},
- {"undumpint", undumpint_l},
+ {"pack", str_pack},
+ {"unpack", str_unpack},
{NULL, NULL}
};
diff --git a/src/ltable.c b/src/ltable.c
index 6ba80e3b..f7b836d5 100644
--- a/src/ltable.c
+++ b/src/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.93 2014/07/29 16:22:24 roberto Exp $
+** $Id: ltable.c,v 2.96 2014/10/17 16:28:21 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -40,14 +40,19 @@
/*
-** Maximum size of array part (MAXASIZE) is 2^MAXBITS. (SIZEINT is the
-** minimum between size of int and size of LUA_INTEGER; array indices
-** are limited by both types.)
+** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is
+** the largest integer such that MAXASIZE fits in an unsigned int.
*/
-#define SIZEINT \
- (sizeof(int) < sizeof(LUA_INTEGER) ? sizeof(int) : sizeof(LUA_INTEGER))
-#define MAXBITS cast_int(SIZEINT * CHAR_BIT - 2)
-#define MAXASIZE (1 << MAXBITS)
+#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))))
@@ -139,29 +144,29 @@ static Node *mainposition (const Table *t, const TValue *key) {
/*
** returns the index for `key' if `key' is an appropriate key to live in
-** the array part of the table, -1 otherwise.
+** the array part of the table, 0 otherwise.
*/
-static int arrayindex (const TValue *key) {
+static unsigned int arrayindex (const TValue *key) {
if (ttisinteger(key)) {
lua_Integer k = ivalue(key);
- if (0 < k && k <= MAXASIZE) /* is `key' an appropriate array index? */
- return cast_int(k);
+ if (0 < k && (lua_Unsigned)k <= MAXASIZE)
+ return cast(unsigned int, k); /* 'key' is an appropriate array index */
}
- return -1; /* `key' did not match some condition */
+ 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 -1.
+** beginning of a traversal is signaled by 0.
*/
-static int findindex (lua_State *L, Table *t, StkId key) {
- int i;
- if (ttisnil(key)) return -1; /* first iteration */
+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 (0 < i && i <= t->sizearray) /* is `key' inside array part? */
- return i-1; /* yes; that's the index (corrected to C) */
+ 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);
@@ -172,11 +177,11 @@ static int findindex (lua_State *L, Table *t, StkId 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 + t->sizearray;
+ return (i + 1) + t->sizearray;
}
nx = gnext(n);
if (nx == 0)
- luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
+ luaG_runerror(L, "invalid key to 'next'"); /* key not found */
else n += nx;
}
}
@@ -184,15 +189,15 @@ static int findindex (lua_State *L, Table *t, StkId key) {
int luaH_next (lua_State *L, Table *t, StkId key) {
- int i = findindex(L, t, key); /* find original element */
- for (i++; i < t->sizearray; i++) { /* try first array part */
+ 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; i < sizenode(t); i++) { /* then hash part */
+ 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)));
@@ -209,19 +214,24 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
** ==============================================================
*/
-
-static int computesizes (int nums[], int *narray) {
+/*
+** 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. Put in '*narray' the optimal size, and
+** return the number of elements that will go to that part.
+*/
+static unsigned int computesizes (unsigned int nums[], unsigned int *narray) {
int i;
- int twotoi; /* 2^i */
- int a = 0; /* number of elements smaller than 2^i */
- int na = 0; /* number of elements to go to array part */
- int n = 0; /* optimal size for array part */
+ unsigned int twotoi; /* 2^i */
+ 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 n = 0; /* optimal size for array part */
for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
if (nums[i] > 0) {
a += nums[i];
if (a > twotoi/2) { /* more than half elements present? */
n = twotoi; /* optimal size (till now) */
- na = a; /* all elements smaller than n will go to array part */
+ na = a; /* all elements up to 'n' will go to array part */
}
}
if (a == *narray) break; /* all elements already counted */
@@ -232,9 +242,9 @@ static int computesizes (int nums[], int *narray) {
}
-static int countint (const TValue *key, int *nums) {
- int k = arrayindex(key);
- if (k > 0) { /* is `key' an appropriate array index? */
+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;
}
@@ -243,20 +253,21 @@ static int countint (const TValue *key, int *nums) {
}
-static int numusearray (const Table *t, int *nums) {
+static unsigned int numusearray (const Table *t, unsigned int *nums) {
int lg;
- int ttlg; /* 2^lg */
- int ause = 0; /* summation of `nums' */
- int i = 1; /* count to traverse all array keys */
- for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
- int lc = 0; /* counter */
- int lim = ttlg;
+ 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] */
+ /* count elements in range (2^(lg - 1), 2^lg] */
for (; i <= lim; i++) {
if (!ttisnil(&t->array[i-1]))
lc++;
@@ -268,9 +279,10 @@ static int numusearray (const Table *t, int *nums) {
}
-static int numusehash (const Table *t, int *nums, int *pnasize) {
+static int numusehash (const Table *t, unsigned int *nums,
+ unsigned int *pnasize) {
int totaluse = 0; /* total number of elements */
- int ause = 0; /* summation of `nums' */
+ int ause = 0; /* elements added to 'nums' (can go to array part) */
int i = sizenode(t);
while (i--) {
Node *n = &t->node[i];
@@ -284,8 +296,8 @@ static int numusehash (const Table *t, int *nums, int *pnasize) {
}
-static void setarrayvector (lua_State *L, Table *t, int size) {
- int i;
+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]);
@@ -293,7 +305,7 @@ static void setarrayvector (lua_State *L, Table *t, int size) {
}
-static void setnodevector (lua_State *L, Table *t, int size) {
+static void setnodevector (lua_State *L, Table *t, unsigned int size) {
int lsize;
if (size == 0) { /* no elements to hash part? */
t->node = cast(Node *, dummynode); /* use common `dummynode' */
@@ -302,11 +314,11 @@ static void setnodevector (lua_State *L, Table *t, int size) {
else {
int i;
lsize = luaO_ceillog2(size);
- if (lsize > MAXBITS)
+ if (lsize > MAXHBITS)
luaG_runerror(L, "table overflow");
size = twoto(lsize);
t->node = luaM_newvector(L, size, Node);
- for (i=0; i<size; i++) {
+ for (i = 0; i < (int)size; i++) {
Node *n = gnode(t, i);
gnext(n) = 0;
setnilvalue(wgkey(n));
@@ -318,9 +330,11 @@ static void setnodevector (lua_State *L, Table *t, int size) {
}
-void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
- int i;
- int oldasize = t->sizearray;
+void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
+ unsigned int nhsize) {
+ unsigned int i;
+ int j;
+ unsigned int oldasize = t->sizearray;
int oldhsize = t->lsizenode;
Node *nold = t->node; /* save old hash ... */
if (nasize > oldasize) /* array part must grow? */
@@ -338,8 +352,8 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
}
/* re-insert elements from hash part */
- for (i = twoto(oldhsize) - 1; i >= 0; i--) {
- Node *old = nold+i;
+ for (j = twoto(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 */
@@ -351,18 +365,20 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
}
-void luaH_resizearray (lua_State *L, Table *t, int nasize) {
+void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
int nsize = isdummy(t->node) ? 0 : sizenode(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) {
- int nasize, na;
- int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */
+ unsigned int nasize, na;
+ unsigned int nums[MAXABITS + 1];
int i;
int totaluse;
- for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
+ for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */
nasize = numusearray(t, nums); /* count keys in array part */
totaluse = nasize; /* all those keys are integer keys */
totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
@@ -440,7 +456,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
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' take care of TM cache and GC barrier */
+ /* whatever called 'newkey' takes care of TM cache and GC barrier */
return luaH_set(L, t, key); /* insert key into grown table */
}
lua_assert(!isdummy(f));
@@ -478,7 +494,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
*/
const TValue *luaH_getint (Table *t, lua_Integer key) {
/* (1 <= key && key <= t->sizearray) */
- if (l_castS2U(key - 1) < cast(unsigned int, t->sizearray))
+ if (l_castS2U(key - 1) < t->sizearray)
return &t->array[key - 1];
else {
Node *n = hashint(t, key);
diff --git a/src/ltable.h b/src/ltable.h
index 45ff45f2..53d25511 100644
--- a/src/ltable.h
+++ b/src/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 2.19 2014/07/29 16:22:24 roberto Exp $
+** $Id: ltable.h,v 2.20 2014/09/04 18:15:29 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -30,14 +30,15 @@
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);
+ TValue *value);
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, int nasize, int nhsize);
-LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
+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 int luaH_getn (Table *t);
diff --git a/src/ltablib.c b/src/ltablib.c
index bc353866..908acfbc 100644
--- a/src/ltablib.c
+++ b/src/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.73 2014/07/29 16:01:00 roberto Exp $
+** $Id: ltablib.c,v 1.77 2014/10/17 16:28:21 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -28,41 +28,25 @@ typedef struct {
/*
-** equivalent to 'lua_rawgeti', but not raw
-*/
-static int geti (lua_State *L, int idx, lua_Integer n) {
- lua_pushinteger(L, n);
- return lua_gettable(L, idx); /* assume 'idx' is not negative */
-}
-
-
-/*
-** equivalent to 'lua_rawseti', but not raw
-*/
-static void seti (lua_State *L, int idx, lua_Integer n) {
- lua_pushinteger(L, n);
- lua_rotate(L, -2, 1); /* exchange key and value */
- lua_settable(L, idx); /* assume 'idx' is not negative */
-}
-
-
-/*
** Check that 'arg' has a table and set access functions in 'ta' to raw
** or non-raw according to the presence of corresponding metamethods.
*/
static void checktab (lua_State *L, int arg, TabA *ta) {
- luaL_checktype(L, arg, LUA_TTABLE);
- if (!lua_getmetatable(L, arg)) { /* fast track */
- ta->geti = lua_rawgeti; /* with no metatable, all is raw */
- ta->seti = lua_rawseti;
- }
- else {
+ ta->geti = NULL; ta->seti = NULL;
+ if (lua_getmetatable(L, arg)) {
lua_pushliteral(L, "__index"); /* 'index' metamethod */
- ta->geti = (lua_rawget(L, -2) == LUA_TNIL) ? lua_rawgeti : geti;
+ if (lua_rawget(L, -2) != LUA_TNIL)
+ ta->geti = lua_geti;
lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */
- ta->seti = (lua_rawget(L, -3) == LUA_TNIL) ? lua_rawseti : seti;
+ if (lua_rawget(L, -3) != LUA_TNIL)
+ ta->seti = lua_seti;
lua_pop(L, 3); /* pop metatable plus both metamethods */
}
+ if (ta->geti == NULL || ta->seti == NULL) {
+ luaL_checktype(L, arg, LUA_TTABLE); /* must be table for raw methods */
+ if (ta->geti == NULL) ta->geti = lua_rawgeti;
+ if (ta->seti == NULL) ta->seti = lua_rawseti;
+ }
}
@@ -107,7 +91,7 @@ static int tinsert (lua_State *L) {
break;
}
default: {
- return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
+ return luaL_error(L, "wrong number of arguments to 'insert'");
}
}
(*ta.seti)(L, 1, pos); /* t[pos] = v */
@@ -132,24 +116,22 @@ static int tremove (lua_State *L) {
}
-static int tcopy (lua_State *L) {
+static int tmove (lua_State *L) {
TabA ta;
lua_Integer f = luaL_checkinteger(L, 2);
lua_Integer e = luaL_checkinteger(L, 3);
- lua_Integer t;
- int tt = 4; /* destination table */
+ lua_Integer t = luaL_checkinteger(L, 4);
+ int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
/* the following restriction avoids several problems with overflows */
luaL_argcheck(L, f > 0, 2, "initial position must be positive");
- if (lua_istable(L, tt))
- t = luaL_checkinteger(L, 5);
- else {
- tt = 1; /* destination table is equal to source */
- t = luaL_checkinteger(L, 4);
- }
if (e >= f) { /* otherwise, nothing to move */
lua_Integer n, i;
- ta.geti = (!luaL_getmetafield(L, 1, "__index")) ? lua_rawgeti : geti;
- ta.seti = (!luaL_getmetafield(L, tt, "__newindex")) ? lua_rawseti : seti;
+ ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL)
+ ? (luaL_checktype(L, 1, LUA_TTABLE), lua_rawgeti)
+ : lua_geti;
+ ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL)
+ ? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti)
+ : lua_seti;
n = e - f + 1; /* number of elements to move */
if (t > f) {
for (i = n - 1; i >= 0; i--) {
@@ -172,8 +154,8 @@ static int tcopy (lua_State *L) {
static void addfield (lua_State *L, luaL_Buffer *b, TabA *ta, lua_Integer i) {
(*ta->geti)(L, 1, i);
if (!lua_isstring(L, -1))
- luaL_error(L, "invalid value (%s) at index %d in table for "
- LUA_QL("concat"), luaL_typename(L, -1), i);
+ luaL_error(L, "invalid value (%s) at index %d in table for 'concat'",
+ luaL_typename(L, -1), i);
luaL_addvalue(b);
}
@@ -355,7 +337,7 @@ static const luaL_Reg tab_funcs[] = {
{"pack", pack},
{"unpack", unpack},
{"remove", tremove},
- {"copy", tcopy},
+ {"move", tmove},
{"sort", sort},
{NULL, NULL}
};
diff --git a/src/lua.c b/src/lua.c
index f46f9fb3..b23bb005 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -1,5 +1,5 @@
/*
-** $Id: lua.c,v 1.213 2014/06/30 19:48:08 roberto Exp $
+** $Id: lua.c,v 1.217 2014/10/20 22:21:05 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -134,9 +134,9 @@ static void print_usage (const char *badoption) {
luai_writestringerror(
"usage: %s [options] [script [args]]\n"
"Available options are:\n"
- " -e stat execute string " LUA_QL("stat") "\n"
- " -i enter interactive mode after executing " LUA_QL("script") "\n"
- " -l name require library " LUA_QL("name") "\n"
+ " -e stat execute string 'stat'\n"
+ " -i enter interactive mode after executing 'script'\n"
+ " -l name require library 'name'\n"
" -v show version information\n"
" -E ignore environment variables\n"
" -- stop handling options\n"
@@ -158,34 +158,34 @@ static void l_message (const char *pname, const char *msg) {
/*
** Check whether 'status' is not OK and, if so, prints the error
-** message on the top of the stack. Because this function can be called
-** unprotected, it only accepts actual strings as error messages. (A
-** coercion could raise a memory 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_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1)
- : NULL;
- if (msg == NULL) msg = "(error object is not a string)";
+ const char *msg = lua_tostring(L, -1);
l_message(progname, msg);
- lua_pop(L, 1);
+ lua_pop(L, 1); /* remove message */
}
return status;
}
/*
-** Message handler to be used to run all chunks
+** Message handler used to run all chunks
*/
static int msghandler (lua_State *L) {
const char *msg = lua_tostring(L, 1);
- if (msg) /* is error object a string? */
- luaL_traceback(L, L, msg, 1); /* use standard traceback */
- else if (!lua_isnoneornil(L, 1)) { /* non-string error object? */
- if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */
- lua_pushliteral(L, "(no error message)");
- } /* else no error object, does nothing */
- return 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 */
}
@@ -389,9 +389,8 @@ static void l_print (lua_State *L) {
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 " LUA_QL("print") " (%s)",
- lua_tostring(L, -1)));
+ l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)",
+ lua_tostring(L, -1)));
}
}
diff --git a/src/lua.h b/src/lua.h
index 81aaaebf..c1de153d 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.312 2014/07/31 13:44:30 roberto Exp $
+** $Id: lua.h,v 1.319 2014/10/17 19:17:55 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@@ -19,7 +19,7 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "3"
#define LUA_VERSION_NUM 503
-#define LUA_VERSION_RELEASE "0 (alpha)"
+#define LUA_VERSION_RELEASE "0 (beta)"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
@@ -94,7 +94,7 @@ typedef LUA_INTEGER lua_Integer;
typedef LUA_UNSIGNED lua_Unsigned;
/* type for continuation-function contexts */
-typedef LUA_CTXT lua_Ctx;
+typedef LUA_KCONTEXT lua_KContext;
/*
@@ -105,7 +105,7 @@ typedef int (*lua_CFunction) (lua_State *L);
/*
** Type for continuation functions
*/
-typedef int (*lua_KFunction) (lua_State *L, int status, lua_Ctx ctx);
+typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
/*
@@ -239,6 +239,7 @@ LUA_API int (lua_pushthread) (lua_State *L);
LUA_API int (lua_getglobal) (lua_State *L, const char *var);
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);
@@ -255,6 +256,7 @@ LUA_API int (lua_getuservalue) (lua_State *L, int idx);
LUA_API void (lua_setglobal) (lua_State *L, const char *var);
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);
@@ -265,12 +267,12 @@ 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_Ctx ctx,
- lua_KFunction k);
+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_Ctx ctx, lua_KFunction k);
+ 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,
@@ -283,7 +285,7 @@ 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_Ctx ctx,
+LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx,
lua_KFunction k);
#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg);
@@ -319,7 +321,7 @@ 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_strtonum) (lua_State *L, const char *s);
+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);
@@ -377,7 +379,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
** compatibility macros for unsigned conversions
** ===============================================================
*/
-#if defined(LUA_COMPAT_APIUNSIGNED)
+#if defined(LUA_COMPAT_APIINTCASTS)
#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
#define lua_tounsignedx(L,i,is) ((lua_Integer)lua_tointegerx(L,i,is))
diff --git a/src/luaconf.h b/src/luaconf.h
index d3db9267..ae395769 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.212 2014/07/24 19:33:29 roberto Exp $
+** $Id: luaconf.h,v 1.220 2014/10/21 14:38:46 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -8,9 +8,6 @@
#ifndef lconfig_h
#define lconfig_h
-#include <limits.h>
-#include <stddef.h>
-
/*
** ==================================================================
@@ -20,20 +17,42 @@
/*
-** ===================================================================
+** {==================================================================
@@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines type for
-@@ Lua integers;
+@@ Lua integers; you must define one of them.
@@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines
-@@ type for Lua floats.
+@@ type for Lua floats. You must define one of them.
+**
+** These definitions set the numeric types for Lua. Lua should work fine
+** with any mix of these previous options. The usual configurations
+** are 64-bit integers and floats (the default) and 32-bit integers and
+** floats (Small Lua, for restricted platforms).
**
-** These definitions set the numeric types for Lua. Lua should work
-** fine with any mix of these previous options.
-** The usual configurations are 64-bit integers and floats (the default)
-** and 32-bit integers and floats (Small Lua, for restricted hardware).
+** Note that C compilers not compliant with C99 may not have
+** support for 'long long'. In that case, you should not use option
+** 'LUA_INT_LONGLONG'; use instead option 'LUA_32BITS' for Small Lua
+** (see below), or LUA_INT_LONG plus LUA_REAL_DOUBLE for an interpreter
+** with 32-bit integers and double floating-point numbers.
** =====================================================================
*/
+
+/*
+** Just uncomment the next line for Small Lua; 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 */
+
+#if !defined(LUA_32BITS) && !defined(LUA_ANSI)
#define LUA_INT_LONGLONG
#define LUA_REAL_DOUBLE
+#else /* Lua 32 bits */
+#define LUA_INT_LONG
+#define LUA_REAL_FLOAT
+#endif
+
+/* }================================================================== */
/*
@@ -51,6 +70,7 @@
#endif
#if defined(LUA_WIN)
+#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ANSI C functions */
#define LUA_DL_DLL
#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
#endif
@@ -91,6 +111,9 @@
+#include <limits.h>
+#include <stddef.h>
+
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
@@ Lua libraries.
@@ -220,7 +243,8 @@
/*
@@ LUA_QL describes how error messages quote program elements.
-** CHANGE it if you want a different appearance.
+** Lua does not use these macros anymore; they are here for
+** compatibility only.
*/
#define LUA_QL(x) "'" x "'"
#define LUA_QS LUA_QL("%s")
@@ -236,14 +260,10 @@
/*
@@ luai_writestring/luai_writeline define how 'print' prints its results.
-** They are only used in libraries and the stand-alone program. (The #if
-** avoids including 'stdio.h' everywhere.)
+** They are only used in libraries and the stand-alone program.
*/
-#if defined(LUA_LIB) || defined(lua_c)
-#include <stdio.h>
#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout))
-#endif
/*
@@ luai_writestringerror defines how to print error messages.
@@ -263,19 +283,20 @@
/*
-@@ LUA_CTXT is the type of the context ('ctx') for continuation functions.
-@@ It must be a numerical type; Lua will use 'intptr_t' if available.
+@@ 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.
*/
#if defined (LUA_USE_C99)
#include <stdint.h>
#if defined (INTPTR_MAX) /* even in C99 this type is optional */
-#define LUA_CTXT intptr_t
+#define LUA_KCONTEXT intptr_t
#endif
#endif
-#if !defined(LUA_CTXT)
+#if !defined(LUA_KCONTEXT)
/* default definition (the nearest thing to 'intptr_t' in C89) */
-#define LUA_CTXT ptrdiff_t
+#define LUA_KCONTEXT ptrdiff_t
#endif
@@ -305,15 +326,16 @@
#define LUA_COMPAT_BITLIB
/*
-@@ LUA_COMPAT_IPAIRS controls the effectivness of the __ipairs metamethod.
+@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod.
*/
#define LUA_COMPAT_IPAIRS
/*
-@@ LUA_COMPAT_APIUNSIGNED controls the presence of macros for
-** manipulating unsigned integers (lua_pushunsigned, lua_tounsigned, etc.)
+@@ 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_APIUNSIGNED
+#define LUA_COMPAT_APIINTCASTS
/*
@@ -525,16 +547,11 @@
#endif /* } */
-#if defined(LUA_ANSI)
-/* C89 does not support 'opf' variants for math functions */
+#if !defined(LUA_USE_C99)
+/* 'strtof' and 'opf' variants for math functions are C99 */
#undef l_mathop
-#define l_mathop(op) (lua_Number)op
-#endif
-
-
-#if defined(LUA_ANSI) || defined(_WIN32)
-/* C89 and Windows do not support 'strtof'... */
#undef lua_str2number
+#define l_mathop(op) (lua_Number)op
#define lua_str2number(s,p) ((lua_Number)strtod((s), (p)))
#endif
@@ -652,6 +669,10 @@
#else
+#if !defined(LLONG_MAX)
+#error "Compiler does not support 'long long'. See file 'luaconf.h' line 24"
+#endif
+
#define LUA_INTEGER long long
#define LUA_INTEGER_FRMLEN "ll"
diff --git a/src/lutf8lib.c b/src/lutf8lib.c
index 1e848def..de139296 100644
--- a/src/lutf8lib.c
+++ b/src/lutf8lib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lutf8lib.c,v 1.10 2014/07/16 13:56:14 roberto Exp $
+** $Id: lutf8lib.c,v 1.12 2014/10/15 14:31:10 roberto Exp $
** Standard library for UTF-8 manipulation
** See Copyright Notice in lua.h
*/
@@ -123,9 +123,9 @@ static int codepoint (lua_State *L) {
static void pushutfchar (lua_State *L, int arg) {
- int code = luaL_checkint(L, arg);
+ lua_Integer code = luaL_checkinteger(L, arg);
luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range");
- lua_pushfstring(L, "%U", code);
+ lua_pushfstring(L, "%U", (long)code);
}
@@ -157,7 +157,7 @@ static int utfchar (lua_State *L) {
static int byteoffset (lua_State *L) {
size_t len;
const char *s = luaL_checklstring(L, 1, &len);
- int n = luaL_checkint(L, 2);
+ 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,
@@ -239,7 +239,7 @@ static struct luaL_Reg funcs[] = {
{"len", utflen},
{"codes", iter_codes},
/* placeholders */
- {"charpatt", NULL},
+ {"charpattern", NULL},
{NULL, NULL}
};
@@ -247,7 +247,7 @@ static struct luaL_Reg funcs[] = {
LUAMOD_API int luaopen_utf8 (lua_State *L) {
luaL_newlib(L, funcs);
lua_pushliteral(L, UTF8PATT);
- lua_setfield(L, -2, "charpatt");
+ lua_setfield(L, -2, "charpattern");
return 1;
}
diff --git a/src/lvm.c b/src/lvm.c
index 51f14292..c6c706db 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.222 2014/07/30 14:42:44 roberto Exp $
+** $Id: lvm.c,v 2.224 2014/10/17 16:28:21 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -1033,13 +1033,13 @@ void luaV_execute (lua_State *L) {
else { /* try making all values floats */
lua_Number ninit; lua_Number nlimit; lua_Number nstep;
if (!tonumber(plimit, &nlimit))
- luaG_runerror(L, LUA_QL("for") " limit must be a number");
+ luaG_runerror(L, "'for' limit must be a number");
setfltvalue(plimit, nlimit);
if (!tonumber(pstep, &nstep))
- luaG_runerror(L, LUA_QL("for") " step must be a number");
+ luaG_runerror(L, "'for' step must be a number");
setfltvalue(pstep, nstep);
if (!tonumber(init, &ninit))
- luaG_runerror(L, LUA_QL("for") " initial value must be a number");
+ luaG_runerror(L, "'for' initial value must be a number");
setfltvalue(init, luai_numsub(L, ninit, nstep));
}
ci->u.l.savedpc += GETARG_sBx(i);
@@ -1067,7 +1067,7 @@ void luaV_execute (lua_State *L) {
vmcase(OP_SETLIST,
int n = GETARG_B(i);
int c = GETARG_C(i);
- int last;
+ unsigned int last;
Table *h;
if (n == 0) n = cast_int(L->top - ra) - 1;
if (c == 0) {
diff --git a/src/lvm.h b/src/lvm.h
index 0f4667af..5c5e18c3 100644
--- a/src/lvm.h
+++ b/src/lvm.h
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.h,v 2.33 2014/07/30 14:42:44 roberto Exp $
+** $Id: lvm.h,v 2.34 2014/08/01 17:24:02 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -16,14 +16,14 @@
#if !defined(LUA_NOCVTN2S)
#define cvt2str(o) ttisnumber(o)
#else
-#define cvt2str(o) 0 /* no convertion from numbers to strings */
+#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 convertion from strings to numbers */
+#define cvt2num(o) 0 /* no conversion from strings to numbers */
#endif