summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--doc/contents.html20
-rw-r--r--doc/lua.css7
-rw-r--r--doc/manual.html416
-rw-r--r--doc/readme.html34
-rw-r--r--src/Makefile2
-rw-r--r--src/lapi.c214
-rw-r--r--src/lapi.h6
-rw-r--r--src/lauxlib.c50
-rw-r--r--src/lauxlib.h21
-rw-r--r--src/lbaselib.c79
-rw-r--r--src/ldebug.c17
-rw-r--r--src/ldo.c9
-rw-r--r--src/ldump.c6
-rw-r--r--src/lgc.c102
-rw-r--r--src/lgc.h26
-rw-r--r--src/liolib.c20
-rw-r--r--src/llex.c8
-rw-r--r--src/llimits.h32
-rw-r--r--src/lmathlib.c61
-rw-r--r--src/lmem.c10
-rw-r--r--src/loadlib.c149
-rw-r--r--src/lobject.c43
-rw-r--r--src/lobject.h107
-rw-r--r--src/lparser.c2
-rw-r--r--src/lstate.c12
-rw-r--r--src/lstate.h66
-rw-r--r--src/lstring.c52
-rw-r--r--src/lstring.h12
-rw-r--r--src/lstrlib.c21
-rw-r--r--src/ltable.c29
-rw-r--r--src/ltable.h9
-rw-r--r--src/ltablib.c183
-rw-r--r--src/ltm.c2
-rw-r--r--src/lua.c30
-rw-r--r--src/lua.h88
-rw-r--r--src/luac.c6
-rw-r--r--src/luaconf.h43
-rw-r--r--src/lutf8lib.c4
-rw-r--r--src/lvm.c77
-rw-r--r--src/lvm.h17
41 files changed, 1212 insertions, 882 deletions
diff --git a/README b/README
index 1e7fa3ac..6d6b584c 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
-This is Lua 5.3.0 (work3), released on 19 Jul 2014.
+This is Lua 5.3.0 (alpha), released on 31 Jul 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 af3142b5..b7a00e30 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>All details may change in the final version.</EM>
+<EM>Some details may change in the final version.</EM>
<P>
The reference manual is the official definition of the Lua language.
@@ -37,7 +37,7 @@ For a complete introduction to Lua programming, see the book
<A HREF="#index">index</A>
<HR>
<SMALL>
-Copyright &copy; 2011&ndash;2014 Lua.org, PUC-Rio.
+Copyright &copy; 2014 Lua.org, PUC-Rio.
Freely available under the terms of the
<A HREF="http://www.lua.org/license.html">Lua license</A>.
</SMALL>
@@ -229,7 +229,6 @@ Freely available under the terms of the
<TD>
<H3>&nbsp;</H3>
<P>
-<A HREF="manual.html#pdf-math">math</A><BR>
<A HREF="manual.html#pdf-math.abs">math.abs</A><BR>
<A HREF="manual.html#pdf-math.acos">math.acos</A><BR>
<A HREF="manual.html#pdf-math.asin">math.asin</A><BR>
@@ -240,7 +239,6 @@ Freely available under the terms of the
<A HREF="manual.html#pdf-math.floor">math.floor</A><BR>
<A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR>
<A HREF="manual.html#pdf-math.huge">math.huge</A><BR>
-<A HREF="manual.html#pdf-math.ifloor">math.ifloor</A><BR>
<A HREF="manual.html#pdf-math.log">math.log</A><BR>
<A HREF="manual.html#pdf-math.max">math.max</A><BR>
<A HREF="manual.html#pdf-math.maxinteger">math.maxinteger</A><BR>
@@ -254,7 +252,9 @@ Freely available under the terms of the
<A HREF="manual.html#pdf-math.sin">math.sin</A><BR>
<A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR>
<A HREF="manual.html#pdf-math.tan">math.tan</A><BR>
+<A HREF="manual.html#pdf-math.tointeger">math.tointeger</A><BR>
<A HREF="manual.html#pdf-math.type">math.type</A><BR>
+<A HREF="manual.html#pdf-math.ult">math.ult</A><BR>
<P>
<A HREF="manual.html#pdf-os.clock">os.clock</A><BR>
@@ -301,6 +301,7 @@ Freely available under the terms of the
<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.pack">table.pack</A><BR>
<A HREF="manual.html#pdf-table.remove">table.remove</A><BR>
@@ -321,6 +322,7 @@ 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>
@@ -347,6 +349,7 @@ Freely available under the terms of the
<A HREF="manual.html#lua_error">lua_error</A><BR>
<A HREF="manual.html#lua_gc">lua_gc</A><BR>
<A HREF="manual.html#lua_getallocf">lua_getallocf</A><BR>
+<A HREF="manual.html#lua_getextraspace">lua_getextraspace</A><BR>
<A HREF="manual.html#lua_getfield">lua_getfield</A><BR>
<A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR>
<A HREF="manual.html#lua_gethook">lua_gethook</A><BR>
@@ -399,7 +402,6 @@ Freely available under the terms of the
<A HREF="manual.html#lua_pushnumber">lua_pushnumber</A><BR>
<A HREF="manual.html#lua_pushstring">lua_pushstring</A><BR>
<A HREF="manual.html#lua_pushthread">lua_pushthread</A><BR>
-<A HREF="manual.html#lua_pushunsigned">lua_pushunsigned</A><BR>
<A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR>
<A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR>
<A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR>
@@ -437,8 +439,6 @@ Freely available under the terms of the
<A HREF="manual.html#lua_topointer">lua_topointer</A><BR>
<A HREF="manual.html#lua_tostring">lua_tostring</A><BR>
<A HREF="manual.html#lua_tothread">lua_tothread</A><BR>
-<A HREF="manual.html#lua_tounsigned">lua_tounsigned</A><BR>
-<A HREF="manual.html#lua_tounsignedx">lua_tounsignedx</A><BR>
<A HREF="manual.html#lua_touserdata">lua_touserdata</A><BR>
<A HREF="manual.html#lua_type">lua_type</A><BR>
<A HREF="manual.html#lua_typename">lua_typename</A><BR>
@@ -480,7 +480,6 @@ Freely available under the terms of the
<A HREF="manual.html#luaL_checkstring">luaL_checkstring</A><BR>
<A HREF="manual.html#luaL_checktype">luaL_checktype</A><BR>
<A HREF="manual.html#luaL_checkudata">luaL_checkudata</A><BR>
-<A HREF="manual.html#luaL_checkunsigned">luaL_checkunsigned</A><BR>
<A HREF="manual.html#luaL_checkversion">luaL_checkversion</A><BR>
<A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR>
<A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR>
@@ -508,7 +507,6 @@ Freely available under the terms of the
<A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR>
<A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR>
<A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR>
-<A HREF="manual.html#luaL_optunsigned">luaL_optunsigned</A><BR>
<A HREF="manual.html#luaL_prepbuffer">luaL_prepbuffer</A><BR>
<A HREF="manual.html#luaL_prepbuffsize">luaL_prepbuffsize</A><BR>
<A HREF="manual.html#luaL_pushresult">luaL_pushresult</A><BR>
@@ -531,10 +529,10 @@ Freely available under the terms of the
<HR>
<SMALL CLASS="footer">
Last update:
-Thu Jun 19 17:09:46 BRT 2014
+Thu Jul 31 14:04:18 BRT 2014
</SMALL>
<!--
-Last change: updated for Lua 5.3.0 (work3)
+Last change: updated for Lua 5.3.0 (alpha)
-->
</BODY>
diff --git a/doc/lua.css b/doc/lua.css
index 3d2443ac..98f0fcda 100644
--- a/doc/lua.css
+++ b/doc/lua.css
@@ -59,6 +59,10 @@ a:link:active, a:visited:active {
color: #FF0000 ;
}
+h1 a img {
+ vertical-align: text-bottom ;
+}
+
hr {
border: 0 ;
height: 1px ;
@@ -88,9 +92,8 @@ input[type=text] {
border-radius: 2em ;
-moz-border-radius: 2em ;
background-image: url('images/search.png') ;
- background-repeat: no-repeat;
+ background-repeat: no-repeat ;
background-position: 4px center ;
padding-left: 20px ;
height: 2em ;
}
-
diff --git a/doc/manual.html b/doc/manual.html
index de2dc5f6..186597b5 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -18,13 +18,13 @@ Lua 5.3 Reference Manual
<P>
<IMG SRC="alert.png" ALIGN="absbottom">
-<EM>All details may change in the final version.</EM>
+<EM>Some details may change in the final version.</EM>
<P>
by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
<p>
<small>
-Copyright &copy; 2011&ndash;2014 Lua.org, PUC-Rio.
+Copyright &copy; 2014 Lua.org, PUC-Rio.
Freely available under the terms of the
<a href="http://www.lua.org/license.html">Lua license</a>.
</small>
@@ -38,7 +38,7 @@ Freely available under the terms of the
<!-- ====================================================================== -->
<p>
-<!-- $Id: manual.of,v 1.121 2014/06/18 19:12:23 roberto Exp $ -->
+<!-- $Id: manual.of,v 1.125 2014/07/31 13:58:08 roberto Exp $ -->
@@ -125,7 +125,7 @@ it usually represents the absence of a useful value.
Both <b>nil</b> and <b>false</b> make a condition false;
any other value makes it true.
<em>Number</em> represents both
-integral numbers and real (floating-point) numbers.
+integer numbers and real (floating-point) numbers.
<em>String</em> represents immutable sequences of bytes.
Lua is 8-bit clean:
@@ -146,7 +146,7 @@ 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
-(what is called <em>Small Lua</em>) is particularly attractive
+(called <em>Small Lua</em>) is particularly attractive
for small machines.
@@ -159,7 +159,7 @@ functions written in C
<p>
The type <em>userdata</em> is provided to allow arbitrary C&nbsp;data to
be stored in Lua variables.
-A userdata value is a pointer to a block of raw memory.
+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.
@@ -178,7 +178,7 @@ 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 supports coroutines on all systems,
-even those that do not support threads.
+even those that do not support threads natively.
<p>
@@ -324,7 +324,9 @@ is never updated by Lua.
<p>
Because Lua is an embedded extension language,
all Lua actions start from C&nbsp;code in the host program
-calling a function from the Lua library (see <a href="#lua_pcall"><code>lua_pcall</code></a>).
+calling a function from the Lua library.
+(when you use Lua standalone,
+the <code>lua</code> application is the host program.)
Whenever an error occurs during
the compilation or execution of a Lua chunk,
control returns to the host,
@@ -1891,9 +1893,9 @@ that rounds the quotient towards minus infinite (floor).
In case of overflows in integer arithmetic,
all operations <em>wrap around</em>,
according to the usual rules of two-complement arithmetic.
-(In other words, they return the correct result modulo <em>2<sup>64</sup></em>.)
-
-
+(In other words,
+they return the unique representable integer
+that is equal modulo <em>2<sup>64</sup></em> to the mathematical result.)
@@ -1921,7 +1923,7 @@ Both right and left shifts fill the vacant bits with zeros.
Negative displacements shift to the other direction;
displacements with absolute values equal to or higher than
the number of bits in an integer
-result in zero (all bits are shifted out).
+result in zero (as all bits are shifted out).
@@ -1952,16 +1954,17 @@ In a conversion from integer to float,
if the integer value has an exact representation as a float,
that is the result.
Otherwise,
-the conversion gets the nearest higher or lower representable value.
+the conversion gets the nearest higher or
+the nearest lower representable value.
This kind of conversion never fails.
<p>
The conversion from float to integer
-first takes the floor of the float number.
-If that value can be represented as an integer
-(that is, it is in the range of integer representation),
-that is the result.
+checks whether the float has an exact representation as an integer
+(that is, the float has an integral value and
+it is in the range of integer representation).
+If it does, that representation is the result.
Otherwise, the conversion fails.
@@ -2005,7 +2008,7 @@ Otherwise, the values of the operands are compared.
Strings are compared in the obvious way.
Numbers follow the usual rule for binary operations:
if both operands are integers,
-the are compared as integers;
+they are compared as integers;
otherwise, they are converted to floats
and compared as such.
@@ -2028,7 +2031,7 @@ by using the "eq" metamethod (see <a href="#2.4">&sect;2.4</a>).
<p>
-Equality comparisons never convert strings to numbers
+Equality comparisons do not convert strings to numbers
or vice versa.
Thus, <code>"0"==0</code> evaluates to <b>false</b>,
and <code>t[0]</code> and <code>t["0"]</code> denote different
@@ -2190,7 +2193,7 @@ with key <code>exp1</code> and value <code>exp2</code>.
A field of the form <code>name = exp</code> is equivalent to
<code>["name"] = exp</code>.
Finally, fields of the form <code>exp</code> are equivalent to
-<code>[i] = exp</code>, where <code>i</code> are consecutive numerical integers,
+<code>[i] = exp</code>, where <code>i</code> are consecutive integers
starting with 1.
Fields in the other formats do not affect this counting.
For example,
@@ -2861,7 +2864,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, int ctx) {
+ int k (lua_State *L, int status, lua_Ctx ctx) {
... /* code 2 */
}
@@ -2905,6 +2908,12 @@ the status is always <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> when Lu
(For these two functions,
Lua will not call the continuation in case of errors,
because they do not handle errors.)
+Similarly, when using <a href="#lua_callk"><code>lua_callk</code></a>,
+you should call the continuation function
+with <a href="#pdf-LUA_OK"><code>LUA_OK</code></a> as the status.
+(For <a href="#lua_yieldk"><code>lua_yieldk</code></a>, there is not much point in calling
+directly the continuation function,
+because <a href="#lua_yieldk"><code>lua_yieldk</code></a> usually does not return.)
<p>
@@ -3159,7 +3168,7 @@ 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, int ctx,
+<pre>void lua_callk (lua_State *L, int nargs, int nresults, lua_Ctx ctx,
lua_KFunction k);</pre>
<p>
@@ -3307,7 +3316,7 @@ Concatenation is performed following the usual semantics of Lua
<pre>void lua_copy (lua_State *L, int fromidx, int toidx);</pre>
<p>
-Moves the element at index <code>fromidx</code>
+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).
@@ -3335,6 +3344,21 @@ 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,
@@ -3485,6 +3509,31 @@ Returns the type of the pushed value.
+<hr><h3><a name="lua_getextraspace"><code>lua_getextraspace</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void *lua_getextraspace (lua_State *L);</pre>
+
+<p>
+Returns a pointer to a raw memory area associated with the
+given Lua state.
+The application can use this area for any purpose;
+Lua does not use it for anything.
+
+
+<p>
+Each new thread has this area initialized with a copy
+of the area of the main thread.
+
+
+<p>
+By default, this area has the size of a pointer to void,
+but you can recompile Lua with a different size for this area.
+(See <code>LUA_EXTRASPACE</code> in <code>luaconf.h</code>.)
+
+
+
+
+
<hr><h3><a name="lua_getglobal"><code>lua_getglobal</code></a></h3><p>
<span class="apii">[-0, +1, <em>e</em>]</span>
<pre>int lua_getglobal (lua_State *L, const char *name);</pre>
@@ -3502,8 +3551,9 @@ Returns the type of that value.
<pre>int lua_getmetatable (lua_State *L, int index);</pre>
<p>
-Pushes onto the stack the metatable of the value at the given index.
-If the value does not have a metatable,
+If the value at the given index has a metatable,
+the function pushes that metatable onto the stack and returns&nbsp;1.
+Otherwise,
the function returns&nbsp;0 and pushes nothing on the stack.
@@ -3588,9 +3638,9 @@ The type of integers in Lua.
<p>
By default this type is <code>long long</code>
(usually a 64-bit two-complement integer),
-but that can be changed in <code>luaconf.h</code>
-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>.)
<p>
@@ -3775,7 +3825,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_KFunction"><code>lua_KFunction</code></a></h3>
-<pre>typedef int (*lua_KFunction) (lua_State *L, int status, int ctx);</pre>
+<pre>typedef int (*lua_KFunction) (lua_State *L, int status, lua_Ctx ctx);</pre>
<p>
Type for continuation functions (see <a href="#4.7">&sect;4.7</a>).
@@ -3988,7 +4038,8 @@ The type of floats in Lua.
<p>
By default this type is double,
-but that can be changed in <code>luaconf.h</code> to a single float.
+but that can be changed to a single float.
+(See <code>LUA_REAL</code> in <code>luaconf.h</code>.)
@@ -4096,7 +4147,7 @@ error while running a <code>__gc</code> metamethod.
int nargs,
int nresults,
int errfunc,
- int ctx,
+ lua_Ctx ctx,
lua_KFunction k);</pre>
<p>
@@ -4366,17 +4417,6 @@ Returns 1 if this thread is the main thread of its state.
-<hr><h3><a name="lua_pushunsigned"><code>lua_pushunsigned</code></a></h3><p>
-<span class="apii">[-0, +1, &ndash;]</span>
-<pre>void lua_pushunsigned (lua_State *L, lua_Unsigned n);</pre>
-
-<p>
-Pushes an integer with value <code>n</code> onto the stack.
-
-
-
-
-
<hr><h3><a name="lua_pushvalue"><code>lua_pushvalue</code></a></h3><p>
<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_pushvalue (lua_State *L, int index);</pre>
@@ -4916,9 +4956,12 @@ to a string inside the Lua state.
This string always has a zero ('<code>\0</code>')
after its last character (as in&nbsp;C),
but can contain other zeros in its body.
+
+
+<p>
Because Lua has garbage collection,
there is no guarantee that the pointer returned by <code>lua_tolstring</code>
-will be valid after the corresponding value is removed from the stack.
+will be valid after the corresponding Lua value is removed from the stack.
@@ -5001,48 +5044,6 @@ otherwise, the function returns <code>NULL</code>.
-<hr><h3><a name="lua_tounsigned"><code>lua_tounsigned</code></a></h3><p>
-<span class="apii">[-0, +0, &ndash;]</span>
-<pre>lua_Unsigned lua_tounsigned (lua_State *L, int index);</pre>
-
-<p>
-Equivalent to <a href="#lua_tounsignedx"><code>lua_tounsignedx</code></a> with <code>isnum</code> equal to <code>NULL</code>.
-
-
-
-
-
-<hr><h3><a name="lua_tounsignedx"><code>lua_tounsignedx</code></a></h3><p>
-<span class="apii">[-0, +0, &ndash;]</span>
-<pre>lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);</pre>
-
-<p>
-Converts the Lua value at the given index
-to the unsigned integral type <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
-The Lua value must be an integer,
-or a float,
-or a string convertible to a number
-(see <a href="#3.4.3">&sect;3.4.3</a>);
-otherwise, <code>lua_tounsignedx</code> returns&nbsp;0.
-
-
-<p>
-If the number is not an integer,
-it is rounded towards minus infinite (floor).
-If the result is outside the range of representable values,
-it is normalized to the module of its division by
-one more than the maximum representable value.
-
-
-<p>
-If <code>isnum</code> is not <code>NULL</code>,
-its referent is assigned a boolean value that
-indicates whether the operation succeeded.
-
-
-
-
-
<hr><h3><a name="lua_touserdata"><code>lua_touserdata</code></a></h3><p>
<span class="apii">[-0, +0, &ndash;]</span>
<pre>void *lua_touserdata (lua_State *L, int index);</pre>
@@ -5101,11 +5102,6 @@ which must be one the values returned by <a href="#lua_type"><code>lua_type</cod
The unsigned version of <a href="#lua_Integer"><code>lua_Integer</code></a>.
-<p>
-Lua also defines the constant <a name="pdf-LUA_MAXUNSIGNED"><code>LUA_MAXUNSIGNED</code></a>,
-with the maximum value that fits in this type.
-
-
@@ -5178,14 +5174,14 @@ and pushes them onto the stack <code>to</code>.
<hr><h3><a name="lua_yield"><code>lua_yield</code></a></h3><p>
-<span class="apii">[-?, +?, &ndash;]</span>
+<span class="apii">[-?, +?, <em>e</em>]</span>
<pre>int lua_yield (lua_State *L, int nresults);</pre>
<p>
This function is equivalent to <a href="#lua_yieldk"><code>lua_yieldk</code></a>,
but it has no continuation (see <a href="#4.7">&sect;4.7</a>).
Therefore, when the thread resumes,
-it returns to the function that called
+it continues the function that called
the function calling <code>lua_yield</code>.
@@ -5193,21 +5189,15 @@ the function calling <code>lua_yield</code>.
<hr><h3><a name="lua_yieldk"><code>lua_yieldk</code></a></h3><p>
-<span class="apii">[-?, +?, &ndash;]</span>
-<pre>int lua_yieldk (lua_State *L, int nresults, int ctx, lua_KFunction k);</pre>
+<span class="apii">[-?, +?, <em>e</em>]</span>
+<pre>int lua_yieldk (lua_State *L, int nresults, lua_Ctx ctx, lua_KFunction k);</pre>
<p>
-Yields a coroutine.
+Yields a coroutine (thread).
<p>
-This function should only be called as the
-return expression of a C&nbsp;function, as follows:
-
-<pre>
- return lua_yieldk (L, n, ctx, k);
-</pre><p>
-When a C&nbsp;function calls <a href="#lua_yieldk"><code>lua_yieldk</code></a> in that way,
+When a C&nbsp;function calls <a href="#lua_yieldk"><code>lua_yieldk</code></a>,
the running coroutine suspends its execution,
and the call to <a href="#lua_resume"><code>lua_resume</code></a> that started this coroutine returns.
The parameter <code>nresults</code> is the number of values from the stack
@@ -5227,6 +5217,29 @@ the continuation function receives the value <code>ctx</code>
that was passed to <a href="#lua_yieldk"><code>lua_yieldk</code></a>.
+<p>
+Usually, this function does not return;
+when the coroutine eventually resumes,
+it continues executing the continuation function.
+However, there is one special case,
+which is when this function is called
+from inside a line hook (see <a href="#4.9">&sect;4.9</a>).
+In that case, <code>lua_yieldk</code> should be called with no continuation
+(probably in the form of <a href="#lua_yield"><code>lua_yield</code></a>),
+and the hook should return immediately after the call.
+Lua will yield and,
+when the coroutine resumes again,
+it will continue the normal execution
+of the (Lua) function that triggered the hook.
+
+
+<p>
+This function can raise an error if it is called from a thread
+with a pending C call with no continuation function,
+or it is called from a thread that is not running inside a resume
+(e.g., the main thread).
+
+
@@ -6196,18 +6209,6 @@ returns the userdata address (see <a href="#lua_touserdata"><code>lua_touserdata
-<hr><h3><a name="luaL_checkunsigned"><code>luaL_checkunsigned</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>lua_Unsigned luaL_checkunsigned (lua_State *L, int arg);</pre>
-
-<p>
-Checks whether the function argument <code>arg</code> is a number
-and returns this number converted to a <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
-
-
-
-
-
<hr><h3><a name="luaL_checkversion"><code>luaL_checkversion</code></a></h3><p>
<span class="apii">[-0, +0, &ndash;]</span>
<pre>void luaL_checkversion (lua_State *L);</pre>
@@ -6682,23 +6683,6 @@ Otherwise, raises an error.
-<hr><h3><a name="luaL_optunsigned"><code>luaL_optunsigned</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>lua_Unsigned luaL_optunsigned (lua_State *L,
- int arg,
- lua_Unsigned u);</pre>
-
-<p>
-If the function argument <code>arg</code> is a number,
-returns this number converted to a <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
-If this argument is absent or is <b>nil</b>,
-returns <code>u</code>.
-Otherwise, raises an error.
-
-
-
-
-
<hr><h3><a name="luaL_prepbuffer"><code>luaL_prepbuffer</code></a></h3><p>
<span class="apii">[-?, +?, <em>e</em>]</span>
<pre>char *luaL_prepbuffer (luaL_Buffer *B);</pre>
@@ -6803,18 +6787,19 @@ in which both <code>name</code> and <code>func</code> are <code>NULL</code>.
lua_CFunction openf, int glb);</pre>
<p>
-Calls function <code>openf</code> with string <code>modname</code> as an argument
+If <code>modname</code> is not already present in <a href="#pdf-package.loaded"><code>package.loaded</code></a>,
+calls function <code>openf</code> with string <code>modname</code> as an argument
and sets the call result in <code>package.loaded[modname]</code>,
as if that function has been called through <a href="#pdf-require"><code>require</code></a>.
<p>
If <code>glb</code> is true,
-also stores the result into global <code>modname</code>.
+also stores the module into global <code>modname</code>.
<p>
-Leaves a copy of that result on the stack.
+Leaves a copy of the module on the stack.
@@ -7218,21 +7203,19 @@ Otherwise, returns the metatable of the given object.
<p>
-If <code>t</code> has a metamethod <code>__ipairs</code>,
-calls it with <code>t</code> as argument and returns the first three
-results from the call.
-
-
-<p>
-Otherwise,
-returns three values: an iterator function, the table <code>t</code>, and 0,
+Returns three values (an iterator function, the table <code>t</code>, and 0)
so that the construction
<pre>
for i,v in ipairs(t) do <em>body</em> end
</pre><p>
-will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), ...,
-up to the first integer key absent from the table.
+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>).
@@ -7973,9 +7956,9 @@ 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 prefix up to (and including) the first hyphen is removed.
-For instance, if the module name is <code>a.v1-b.c</code>,
-the function name will be <code>luaopen_b_c</code>.
+its sufix after (and including) the first hyphen is removed.
+For instance, if the module name is <code>a.b.c-v2.1</code>,
+the function name will be <code>luaopen_a_b_c</code>.
<p>
@@ -8138,6 +8121,8 @@ 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>,
@@ -8165,7 +8150,7 @@ that do not use a two-complement representation for integers.
<p>
Looks for the first match of
-<code>pattern</code> in the string <code>s</code>.
+<code>pattern</code> (see <a href="#6.4.1">&sect;6.4.1</a>) in the string <code>s</code>.
If it finds a match, then <code>find</code> returns the indices of&nbsp;<code>s</code>
where this occurrence starts and ends;
otherwise, it returns <b>nil</b>.
@@ -8235,7 +8220,8 @@ it is converted to one following the same rules of <a href="#pdf-tostring"><code
<hr><h3><a name="pdf-string.gmatch"><code>string.gmatch (s, pattern)</code></a></h3>
Returns an iterator function that,
each time it is called,
-returns the next captures from <code>pattern</code> over the string <code>s</code>.
+returns the next captures from <code>pattern</code> (see <a href="#6.4.1">&sect;6.4.1</a>)
+over the string <code>s</code>.
If <code>pattern</code> specifies no captures,
then the whole match is produced in each call.
@@ -8273,7 +8259,7 @@ work as an anchor, as this would prevent the iteration.
<hr><h3><a name="pdf-string.gsub"><code>string.gsub (s, pattern, repl [, n])</code></a></h3>
Returns a copy of <code>s</code>
in which all (or the first <code>n</code>, if given)
-occurrences of the <code>pattern</code> have been
+occurrences of the <code>pattern</code> (see <a href="#6.4.1">&sect;6.4.1</a>) have been
replaced by a replacement string specified by <code>repl</code>,
which can be a string, a table, or a function.
<code>gsub</code> also returns, as its second value,
@@ -8368,7 +8354,7 @@ The definition of what an uppercase letter is depends on the current locale.
<p>
<hr><h3><a name="pdf-string.match"><code>string.match (s, pattern [, init])</code></a></h3>
Looks for the first <em>match</em> of
-<code>pattern</code> in the string <code>s</code>.
+<code>pattern</code> (see <a href="#6.4.1">&sect;6.4.1</a>) in the string <code>s</code>.
If it finds one, then <code>match</code> returns
the captures from the pattern;
otherwise it returns <b>nil</b>.
@@ -8456,8 +8442,21 @@ The definition of what a lowercase letter is depends on the current locale.
+
+
<h3>6.4.1 &ndash; <a name="6.4.1">Patterns</a></h3>
+<p>
+Patterns in Lua are described by regular strings,
+which are interpreted as patterns by the pattern-matching functions
+<a href="#pdf-string.find"><code>string.find</code></a>,
+<a href="#pdf-string.gmatch"><code>string.gmatch</code></a>,
+<a href="#pdf-string.gsub"><code>string.gsub</code></a>,
+and <a href="#pdf-string.match"><code>string.match</code></a>.
+This section describes the syntax and the meaning
+(that is, what they match) of these strings.
+
+
<h4>Character Class:</h4><p>
A <em>character class</em> is used to represent a set of characters.
@@ -8649,8 +8648,6 @@ string <code>"flaaap"</code>, there will be two captures: 3&nbsp;and&nbsp;5.
-
-
<h2>6.5 &ndash; <a name="6.5">UTF-8 Support</a></h2>
<p>
@@ -8775,11 +8772,6 @@ in tables given as arguments.
<p>
-For performance reasons,
-all table accesses (get/set) performed by these functions are raw.
-
-
-<p>
<hr><h3><a name="pdf-table.concat"><code>table.concat (list [, sep [, i [, j]]])</code></a></h3>
@@ -8795,6 +8787,22 @@ 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>
+
+
+<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.
+
+
+
+
+<p>
<hr><h3><a name="pdf-table.insert"><code>table.insert (list, [pos,] value)</code></a></h3>
@@ -9015,18 +9023,6 @@ a value larger than any other numerical value.
<p>
-<hr><h3><a name="pdf-math.ifloor"><code>math.ifloor (x)</code></a></h3>
-
-
-<p>
-Returns the largest integer smaller than or equal to <code>x</code>.
-If the value does not fit in an integer,
-returns <b>nil</b>.
-
-
-
-
-<p>
<hr><h3><a name="pdf-math.log"><code>math.log (x [, base])</code></a></h3>
@@ -9172,6 +9168,18 @@ Returns the tangent of <code>x</code> (assumed to be in radians).
<p>
+<hr><h3><a name="pdf-math.tointeger"><code>math.tointeger (x)</code></a></h3>
+
+
+<p>
+If the value <code>x</code> is convertible to an integer,
+returns that integer.
+Otherwise, returns <b>nil</b>.
+
+
+
+
+<p>
<hr><h3><a name="pdf-math.type"><code>math.type (x)</code></a></h3>
@@ -9183,6 +9191,18 @@ or <b>nil</b> if <code>x</code> is not a number.
+<p>
+<hr><h3><a name="pdf-math.ult"><code>math.ult (m, n)</code></a></h3>
+
+
+<p>
+Returns a boolean,
+true if integer <code>m</code> is below integer <code>n</code> when
+they are compared as unsigned integers.
+
+
+
+
@@ -10272,8 +10292,7 @@ The options are:
<li><b><code>--</code>: </b> stops handling options;</li>
<li><b><code>-</code>: </b> executes <code>stdin</code> as a file and stops handling options.</li>
</ul><p>
-After handling its options, <code>lua</code> runs the given <em>script</em>,
-passing to it the given <em>args</em> as string arguments.
+After handling its options, <code>lua</code> runs the given <em>script</em>.
When called without arguments,
<code>lua</code> behaves as <code>lua -v -i</code>
when the standard input (<code>stdin</code>) is a terminal,
@@ -10283,7 +10302,7 @@ and as <code>lua -</code> otherwise.
<p>
When called without option <code>-E</code>,
the interpreter checks for an environment variable <a name="pdf-LUA_INIT_5_3"><code>LUA_INIT_5_3</code></a>
-(or <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a> if it is not defined)
+(or <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a> if the versioned name is not defined)
before running any argument.
If the variable content has the format <code>@<em>filename</em></code>,
then <code>lua</code> executes the file.
@@ -10343,6 +10362,11 @@ For instance, the call
$ lua -e "print(arg[1])"
</pre><p>
will print "<code>-e</code>".
+If there is a script,
+the script is called with parameters
+<code>arg[1]</code>, &middot;&middot;&middot;, <code>arg[#arg]</code>.
+(Like all chunks in Lua,
+the script is compiled as a vararg function.)
<p>
@@ -10417,7 +10441,7 @@ do not imply source-code changes in a program,
such as the numeric values for constants
or the implementation of functions as macros.
Therefore,
-you should never assume that binaries are compatible between
+you should not assume that binaries are compatible between
different Lua versions.
Always recompile clients of the Lua API when
using a new version.
@@ -10426,7 +10450,7 @@ using a new version.
<p>
Similarly, Lua versions can always change the internal representation
of precompiled chunks;
-precompiled chunks are never compatible between different Lua versions.
+precompiled chunks are not compatible between different Lua versions.
<p>
@@ -10458,12 +10482,6 @@ it is not a general guideline for good programming.
For good programming,
use floats where you need floats
and integers where you need integers.)
-
-
-<p>
-Although not formally an incompatibility,
-the proper differentiation between floats and integers
-have an impact on performance.
</li>
<li>
@@ -10503,6 +10521,16 @@ while the bitwise operators in Standard Lua operate on 64-bit integers.)
</li>
<li>
+The Table library now respects metamethods
+for setting and getting elements.
+</li>
+
+<li>
+The <a href="#pdf-ipairs"><code>ipairs</code></a> iterator now respects metamethods and
+its id{__ipairs} metamethod has been deprecated.
+</li>
+
+<li>
Option names in <a href="#pdf-io.read"><code>io.read</code></a> do not have a starting '<code>*</code>' anymore.
For compatibility, Lua will continue to ignore this character.
</li>
@@ -10513,12 +10541,23 @@ The following functions were deprecated in the mathematical library:
<code>frexp</code>, and <code>ldexp</code>.
You can replace <code>math.pow(x,y)</code> with <code>x^y</code>;
you can replace <code>math.atan2</code> with <code>math.atan</code>,
-which now accepts two parameters;
+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.
</li>
+<li>
+The searcher for C loaders used by <a href="#pdf-require"><code>require</code></a>
+changed the way it handles versioned names.
+Now, the version should come after the module name
+(as is usual in most other tools).
+For compatibility, that searcher still tries the old format
+if if cannot find an open function according to the new style.
+(Lua&nbsp;5.2 already worked that way,
+but it did not document the change.)
+</li>
+
</ul>
@@ -10541,6 +10580,13 @@ Function <a href="#lua_dump"><code>lua_dump</code></a> has an extra parameter, <
Use 0 as the value of this parameter to get the old behavior.
</li>
+<li>
+Functions to inject/project unsigned integers
+(<code>lua_pushunsigned</code>, <code>lua_tounsigned</code>, etc.)
+were deprecated.
+Use their signed equivalents with a type cast.
+</li>
+
</ul>
@@ -10550,7 +10596,7 @@ Use 0 as the value of this parameter to get the old behavior.
<p>
Here is the complete syntax of Lua in extended BNF.
-(It does not describe operator precedences.)
+(For operator precedences, see <a href="#3.4.8">&sect;3.4.8</a>.)
@@ -10635,10 +10681,10 @@ Here is the complete syntax of Lua in extended BNF.
<HR>
<SMALL CLASS="footer">
Last update:
-Thu Jun 19 17:13:19 BRT 2014
+Thu Jul 31 14:02:14 BRT 2014
</SMALL>
<!--
-Last change: updated for Lua 5.3.0 (work3)
+Last change: revised for Lua 5.3.0 (alpha)
-->
</body></html>
diff --git a/doc/readme.html b/doc/readme.html
index 6c9ec1e1..19e0c553 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 (work3)
+Welcome to Lua 5.3 (alpha)
</H1>
<P>
<IMG SRC="alert.png" ALIGN="absbottom">
-<EM>All details may change in the final version.</EM>
+<EM>Some 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-work3</TT>.
+the top-level directory, which is named <TT>lua-5.3.0-alpha</TT>.
The <TT>Makefile</TT> there controls both the build process and the installation process.
<P>
<LI>
@@ -275,36 +275,38 @@ lists the
<LI> better support for small architectures ("Small Lua" with 32-bit numbers)
<LI> bitwise operators
<LI> basic utf-8 library
+
<LI> utf-8 escapes in literal strings
-<LI> functions for packing/unpacking numbers
-<LI> userdata can have any Lua value as uservalue
<LI> strip option in <CODE>lua_dump</CODE>/<CODE>string.dump</CODE>
</UL>
Here are the other changes introduced in Lua 5.3:
<H3>Language</H3>
<UL>
-<LI>
+<LI> userdata can have any Lua value as uservalue
+<LI> integer division
+<LI> more flexible rules for some metamethods
</UL>
<H3>Libraries</H3>
<UL>
-<LI>
+<LI> functions for packing/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>
</UL>
<H3>C API</H3>
<UL>
-<LI>
-</UL>
-
-<H3>Implementation</H3>
-<UL>
-<LI>
+<LI> new functions: <CODE>lua_rotate</CODE>, <CODE>lua_isyieldable</CODE>, <CODE>lua_strtonum</CODE>
+<LI> <CODE>lua_gettable</CODE> and similar functions return type of resulted value
</UL>
<H3>Lua standalone interpreter</H3>
<UL>
-<LI> Can be used as calculator; no need to prefix with '='
+<LI> can be used as calculator; no need to prefix with '='
+<LI> <CODE>arg</CODE> table available to all code
</UL>
<H2><A NAME="license">License</A></H2>
@@ -354,10 +356,10 @@ THE SOFTWARE.
<HR>
<SMALL CLASS="footer">
Last update:
-Wed Jun 11 22:54:18 BRT 2014
+Thu Jul 31 15:23:46 BRT 2014
</SMALL>
<!--
-Last change: updated for Lua 5.3.0 (work3)
+Last change: updated for Lua 5.3.0 (alpha)
-->
</BODY>
diff --git a/src/Makefile b/src/Makefile
index 4b357ce1..a30a75ef 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -7,7 +7,7 @@
PLAT= none
CC= gcc
-CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
+CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS)
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
LIBS= -lm $(SYSLIBS) $(MYLIBS)
diff --git a/src/lapi.c b/src/lapi.c
index b726e3c5..9bd78308 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.219 2014/06/19 18:27:20 roberto Exp $
+** $Id: lapi.c,v 2.232 2014/07/30 14:00:14 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -44,32 +44,35 @@ const char lua_ident[] =
/* test for pseudo index */
#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
+/* test for upvalue */
+#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
+
/* test for valid but not pseudo index */
#define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
-#define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index")
+#define api_checkvalidindex(o) api_check(isvalid(o), "invalid index")
-#define api_checkstackindex(L, i, o) \
- api_check(L, isstackindex(i, o), "index not in the stack")
+#define api_checkstackindex(i, o) \
+ api_check(isstackindex(i, o), "index not in the stack")
static TValue *index2addr (lua_State *L, int idx) {
CallInfo *ci = L->ci;
if (idx > 0) {
TValue *o = ci->func + idx;
- api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
+ api_check(idx <= ci->top - (ci->func + 1), "unacceptable index");
if (o >= L->top) return NONVALIDVALUE;
else return o;
}
else if (!ispseudo(idx)) { /* negative index */
- api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
+ api_check(idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
return L->top + idx;
}
else if (idx == LUA_REGISTRYINDEX)
return &G(L)->l_registry;
else { /* upvalues */
idx = LUA_REGISTRYINDEX - idx;
- api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
+ api_check(idx <= MAXUPVAL + 1, "upvalue index too large");
if (ttislcf(ci->func)) /* light C function? */
return NONVALIDVALUE; /* it has no upvalues */
else {
@@ -94,7 +97,7 @@ LUA_API int lua_checkstack (lua_State *L, int size) {
int res;
CallInfo *ci = L->ci;
lua_lock(L);
- api_check(L, size >= 0, "negative 'size'");
+ api_check(size >= 0, "negative 'size'");
if (L->stack_last - L->top > size) /* stack large enough? */
res = 1; /* yes; check is OK */
else { /* no; need to grow stack */
@@ -116,8 +119,8 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
if (from == to) return;
lua_lock(to);
api_checknelems(from, n);
- api_check(from, G(from) == G(to), "moving among independent states");
- api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
+ api_check(G(from) == G(to), "moving among independent states");
+ api_check(to->ci->top - to->top >= n, "not enough elements to move");
from->top -= n;
for (i = 0; i < n; i++) {
setobj2s(to, to->top++, from->top + i);
@@ -168,13 +171,13 @@ LUA_API void lua_settop (lua_State *L, int idx) {
StkId func = L->ci->func;
lua_lock(L);
if (idx >= 0) {
- api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
+ api_check(idx <= L->stack_last - (func + 1), "new top too large");
while (L->top < (func + 1) + idx)
setnilvalue(L->top++);
L->top = (func + 1) + idx;
}
else {
- api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
+ api_check(-(idx+1) <= (L->top - (func + 1)), "invalid new top");
L->top += idx+1; /* `subtract' index (index is negative) */
}
lua_unlock(L);
@@ -183,7 +186,7 @@ LUA_API void lua_settop (lua_State *L, int idx) {
/*
** Reverse the stack segment from 'from' to 'to'
-** (auxiliar to 'lua_rotate')
+** (auxiliary to 'lua_rotate')
*/
static void reverse (lua_State *L, StkId from, StkId to) {
for (; from < to; from++, to--) {
@@ -204,8 +207,8 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) {
lua_lock(L);
t = L->top - 1; /* end of stack segment being rotated */
p = index2addr(L, idx); /* start of segment */
- api_checkstackindex(L, idx, p);
- api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
+ api_checkstackindex(idx, p);
+ api_check((n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
reverse(L, p, m); /* reverse the prefix with length 'n' */
reverse(L, m + 1, t); /* reverse the suffix */
@@ -214,31 +217,17 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) {
}
-static void moveto (lua_State *L, TValue *fr, int idx) {
- TValue *to = index2addr(L, idx);
- api_checkvalidindex(L, to);
+LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
+ TValue *fr, *to;
+ lua_lock(L);
+ fr = index2addr(L, fromidx);
+ to = index2addr(L, toidx);
+ api_checkvalidindex(to);
setobj(L, to, fr);
- if (idx < LUA_REGISTRYINDEX) /* function upvalue? */
+ if (isupvalue(toidx)) /* function upvalue? */
luaC_barrier(L, clCvalue(L->ci->func), fr);
/* LUA_REGISTRYINDEX does not need gc barrier
(collector revisits it before finishing collection) */
-}
-
-
-LUA_API void lua_replace (lua_State *L, int idx) {
- lua_lock(L);
- api_checknelems(L, 1);
- moveto(L, L->top - 1, idx);
- L->top--;
- lua_unlock(L);
-}
-
-
-LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
- TValue *fr;
- lua_lock(L);
- fr = index2addr(L, fromidx);
- moveto(L, fr, toidx);
lua_unlock(L);
}
@@ -265,6 +254,7 @@ LUA_API int lua_type (lua_State *L, int idx) {
LUA_API const char *lua_typename (lua_State *L, int t) {
UNUSED(L);
+ api_check(LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
return ttypename(t);
}
@@ -289,8 +279,8 @@ LUA_API int lua_isnumber (lua_State *L, int idx) {
LUA_API int lua_isstring (lua_State *L, int idx) {
- int t = lua_type(L, idx);
- return (t == LUA_TSTRING || t == LUA_TNUMBER);
+ const TValue *o = index2addr(L, idx);
+ return (ttisstring(o) || cvt2str(o));
}
@@ -334,7 +324,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
- default: api_check(L, 0, "invalid option");
+ default: api_check(0, "invalid option");
}
}
lua_unlock(L);
@@ -372,40 +362,6 @@ LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
}
-LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *pisnum) {
- lua_Unsigned res = 0;
- const TValue *o = index2addr(L, idx);
- int isnum = 0;
- switch (ttype(o)) {
- case LUA_TNUMINT: {
- res = l_castS2U(ivalue(o));
- isnum = 1;
- break;
- }
- case LUA_TNUMFLT: { /* compute floor(n) % 2^(numbits in an integer) */
- const lua_Number two2n = cast_num(LUA_MAXUNSIGNED) + cast_num(1);
- lua_Number n = fltvalue(o); /* get value */
- int neg = 0;
- n = l_floor(n); /* get its floor */
- if (n < 0) {
- neg = 1;
- n = -n; /* make 'n' positive, so that 'fmod' is the same as '%' */
- }
- n = l_mathop(fmod)(n, two2n); /* n = n % 2^(numbits in an integer) */
- if (luai_numisnan(n)) /* not a number? */
- break; /* not an integer, too */
- res = cast(lua_Unsigned, n); /* 'n' now must fit in an unsigned */
- if (neg) res = 0u - res; /* back to negative, if needed */
- isnum = 1;
- break;
- }
- default: break;
- }
- if (pisnum) *pisnum = isnum;
- return res;
-}
-
-
LUA_API int lua_toboolean (lua_State *L, int idx) {
const TValue *o = index2addr(L, idx);
return !l_isfalse(o);
@@ -415,14 +371,14 @@ LUA_API int lua_toboolean (lua_State *L, int idx) {
LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
StkId o = index2addr(L, idx);
if (!ttisstring(o)) {
- lua_lock(L); /* `luaV_tostring' may create a new string */
- if (!luaV_tostring(L, o)) { /* conversion failed? */
+ if (!cvt2str(o)) { /* not convertible? */
if (len != NULL) *len = 0;
- lua_unlock(L);
return NULL;
}
+ lua_lock(L); /* `luaO_tostring' may create a new string */
luaC_checkGC(L);
o = index2addr(L, idx); /* previous call may reallocate the stack */
+ luaO_tostring(L, o);
lua_unlock(L);
}
if (len != NULL) *len = tsvalue(o)->len;
@@ -453,7 +409,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
LUA_API void *lua_touserdata (lua_State *L, int idx) {
StkId o = index2addr(L, idx);
switch (ttnov(o)) {
- case LUA_TUSERDATA: return (rawuvalue(o) + 1);
+ case LUA_TUSERDATA: return getudatamem(uvalue(o));
case LUA_TLIGHTUSERDATA: return pvalue(o);
default: return NULL;
}
@@ -512,14 +468,6 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
}
-LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
- lua_lock(L);
- setivalue(L->top, l_castU2S(u));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
TString *ts;
lua_lock(L);
@@ -582,7 +530,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
else {
CClosure *cl;
api_checknelems(L, n);
- api_check(L, n <= MAXUPVAL, "upvalue index too large");
+ api_check(n <= MAXUPVAL, "upvalue index too large");
luaC_checkGC(L);
cl = luaF_newCclosure(L, n);
cl->f = fn;
@@ -667,7 +615,7 @@ LUA_API int lua_rawget (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2addr(L, idx);
- api_check(L, ttistable(t), "table expected");
+ api_check(ttistable(t), "table expected");
setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
lua_unlock(L);
return ttnov(L->top - 1);
@@ -678,7 +626,7 @@ LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
StkId t;
lua_lock(L);
t = index2addr(L, idx);
- api_check(L, ttistable(t), "table expected");
+ api_check(ttistable(t), "table expected");
setobj2s(L, L->top, luaH_getint(hvalue(t), n));
api_incr_top(L);
lua_unlock(L);
@@ -691,7 +639,7 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
TValue k;
lua_lock(L);
t = index2addr(L, idx);
- api_check(L, ttistable(t), "table expected");
+ api_check(ttistable(t), "table expected");
setpvalue(&k, cast(void *, p));
setobj2s(L, L->top, luaH_get(hvalue(t), &k));
api_incr_top(L);
@@ -746,8 +694,8 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) {
StkId o;
lua_lock(L);
o = index2addr(L, idx);
- api_check(L, ttisfulluserdata(o), "full userdata expected");
- getuservalue(L, rawuvalue(o), L->top);
+ api_check(ttisfulluserdata(o), "full userdata expected");
+ getuservalue(L, uvalue(o), L->top);
api_incr_top(L);
lua_unlock(L);
return ttnov(L->top - 1);
@@ -796,42 +744,48 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
LUA_API void lua_rawset (lua_State *L, int idx) {
- StkId t;
+ StkId o;
+ Table *t;
lua_lock(L);
api_checknelems(L, 2);
- t = index2addr(L, idx);
- api_check(L, ttistable(t), "table expected");
- setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
- invalidateTMcache(hvalue(t));
- luaC_barrierback(L, gcvalue(t), L->top-1);
+ o = index2addr(L, idx);
+ api_check(ttistable(o), "table expected");
+ t = hvalue(o);
+ setobj2t(L, luaH_set(L, t, L->top-2), L->top-1);
+ invalidateTMcache(t);
+ luaC_barrierback(L, t, L->top-1);
L->top -= 2;
lua_unlock(L);
}
LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
- StkId t;
+ StkId o;
+ Table *t;
lua_lock(L);
api_checknelems(L, 1);
- t = index2addr(L, idx);
- api_check(L, ttistable(t), "table expected");
- luaH_setint(L, hvalue(t), n, L->top - 1);
- luaC_barrierback(L, gcvalue(t), L->top-1);
+ o = index2addr(L, idx);
+ api_check(ttistable(o), "table expected");
+ t = hvalue(o);
+ luaH_setint(L, t, n, L->top - 1);
+ luaC_barrierback(L, t, L->top-1);
L->top--;
lua_unlock(L);
}
LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
- StkId t;
+ StkId o;
+ Table *t;
TValue k;
lua_lock(L);
api_checknelems(L, 1);
- t = index2addr(L, idx);
- api_check(L, ttistable(t), "table expected");
+ o = index2addr(L, idx);
+ api_check(ttistable(o), "table expected");
+ t = hvalue(o);
setpvalue(&k, cast(void *, p));
- setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
- luaC_barrierback(L, gcvalue(t), L->top - 1);
+ setobj2t(L, luaH_set(L, t, &k), L->top - 1);
+ luaC_barrierback(L, t, L->top - 1);
L->top--;
lua_unlock(L);
}
@@ -846,7 +800,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
if (ttisnil(L->top - 1))
mt = NULL;
else {
- api_check(L, ttistable(L->top - 1), "table expected");
+ api_check(ttistable(L->top - 1), "table expected");
mt = hvalue(L->top - 1);
}
switch (ttnov(obj)) {
@@ -861,7 +815,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
case LUA_TUSERDATA: {
uvalue(obj)->metatable = mt;
if (mt) {
- luaC_objbarrier(L, rawuvalue(obj), mt);
+ luaC_objbarrier(L, uvalue(obj), mt);
luaC_checkfinalizer(L, gcvalue(obj), mt);
}
break;
@@ -882,8 +836,8 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
lua_lock(L);
api_checknelems(L, 1);
o = index2addr(L, idx);
- api_check(L, ttisfulluserdata(o), "full userdata expected");
- setuservalue(L, rawuvalue(o), L->top - 1);
+ api_check(ttisfulluserdata(o), "full userdata expected");
+ setuservalue(L, uvalue(o), L->top - 1);
luaC_barrier(L, gcvalue(o), L->top - 1);
L->top--;
lua_unlock(L);
@@ -896,18 +850,18 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
#define checkresults(L,na,nr) \
- api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
+ api_check((nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
"results from function overflow current stack size")
-LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
+LUA_API void lua_callk (lua_State *L, int nargs, int nresults, lua_Ctx ctx,
lua_KFunction k) {
StkId func;
lua_lock(L);
- api_check(L, k == NULL || !isLua(L->ci),
+ api_check(k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
- api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
+ api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
func = L->top - (nargs+1);
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
@@ -940,21 +894,21 @@ static void f_call (lua_State *L, void *ud) {
LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
- int ctx, lua_KFunction k) {
+ lua_Ctx ctx, lua_KFunction k) {
struct CallS c;
int status;
ptrdiff_t func;
lua_lock(L);
- api_check(L, k == NULL || !isLua(L->ci),
+ api_check(k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
- api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
+ api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
if (errfunc == 0)
func = 0;
else {
StkId o = index2addr(L, errfunc);
- api_checkstackindex(L, errfunc, o);
+ api_checkstackindex(errfunc, o);
func = savestack(L, o);
}
c.func = L->top - (nargs+1); /* function to be called */
@@ -999,7 +953,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
setobj(L, f->upvals[0]->v, gt);
- luaC_barrier(L, f->upvals[0], gt);
+ luaC_upvalbarrier(L, f->upvals[0]);
}
}
lua_unlock(L);
@@ -1062,7 +1016,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
case LUA_GCSTEP: {
l_mem debt = 1; /* =1 to signal that it did an actual step */
int oldrunning = g->gcrunning;
- g->gcrunning = 1; /* force GC to run */
+ g->gcrunning = 1; /* allow GC to run */
if (data == 0) {
luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */
luaC_step(L);
@@ -1119,7 +1073,7 @@ LUA_API int lua_next (lua_State *L, int idx) {
int more;
lua_lock(L);
t = index2addr(L, idx);
- api_check(L, ttistable(t), "table expected");
+ api_check(ttistable(t), "table expected");
more = luaH_next(L, hvalue(t), L->top - 1);
if (more) {
api_incr_top(L);
@@ -1183,19 +1137,19 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
setuvalue(L, L->top, u);
api_incr_top(L);
lua_unlock(L);
- return u + 1;
+ return getudatamem(u);
}
static const char *aux_upvalue (StkId fi, int n, TValue **val,
- GCObject **owner, UpVal **uv) {
+ CClosure **owner, UpVal **uv) {
switch (ttype(fi)) {
case LUA_TCCL: { /* C closure */
CClosure *f = clCvalue(fi);
if (!(1 <= n && n <= f->nupvalues)) return NULL;
*val = &f->upvalue[n-1];
- if (owner) *owner = obj2gco(f);
+ if (owner) *owner = f;
return "";
}
case LUA_TLCL: { /* Lua closure */
@@ -1230,7 +1184,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
const char *name;
TValue *val = NULL; /* to avoid warnings */
- GCObject *owner = NULL;
+ CClosure *owner = NULL;
UpVal *uv = NULL;
StkId fi;
lua_lock(L);
@@ -1251,9 +1205,9 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
LClosure *f;
StkId fi = index2addr(L, fidx);
- api_check(L, ttisLclosure(fi), "Lua function expected");
+ api_check(ttisLclosure(fi), "Lua function expected");
f = clLvalue(fi);
- api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
+ api_check((1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
if (pf) *pf = f;
return &f->upvals[n - 1]; /* get its upvalue pointer */
}
@@ -1267,11 +1221,11 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
}
case LUA_TCCL: { /* C closure */
CClosure *f = clCvalue(fi);
- api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
+ api_check(1 <= n && n <= f->nupvalues, "invalid upvalue index");
return &f->upvalue[n - 1];
}
default: {
- api_check(L, 0, "closure expected");
+ api_check(0, "closure expected");
return NULL;
}
}
diff --git a/src/lapi.h b/src/lapi.h
index 0909a391..092f5e97 100644
--- a/src/lapi.h
+++ b/src/lapi.h
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.h,v 2.7 2009/11/27 15:37:59 roberto Exp $
+** $Id: lapi.h,v 2.8 2014/07/15 21:26:50 roberto Exp $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
@@ -11,13 +11,13 @@
#include "llimits.h"
#include "lstate.h"
-#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
+#define api_incr_top(L) {L->top++; api_check(L->top <= L->ci->top, \
"stack overflow");}
#define adjustresults(L,nres) \
{ if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
-#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
+#define api_checknelems(L,n) api_check((n) < (L->top - L->ci->func), \
"not enough elements in the stack")
diff --git a/src/lauxlib.c b/src/lauxlib.c
index df0e5156..abf589ae 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.263 2014/05/12 21:44:17 roberto Exp $
+** $Id: lauxlib.c,v 1.267 2014/07/19 14:37:09 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -396,8 +396,8 @@ LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) {
static void interror (lua_State *L, int arg) {
- if (lua_type(L, arg) == LUA_TNUMBER)
- luaL_argerror(L, arg, "float value out of integer range");
+ if (lua_isnumber(L, arg))
+ luaL_argerror(L, arg, "number has no integer representation");
else
tag_error(L, arg, LUA_TNUMBER);
}
@@ -413,26 +413,11 @@ LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
}
-LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int arg) {
- int isnum;
- lua_Unsigned d = lua_tounsignedx(L, arg, &isnum);
- if (!isnum)
- interror(L, arg);
- return d;
-}
-
-
LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
lua_Integer def) {
return luaL_opt(L, luaL_checkinteger, arg, def);
}
-
-LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int arg,
- lua_Unsigned def) {
- return luaL_opt(L, luaL_checkunsigned, arg, def);
-}
-
/* }====================================================== */
@@ -898,22 +883,26 @@ LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
/*
-** stripped-down 'require'. Calls 'openf' to open a module,
-** registers the result in 'package.loaded' table and, if 'glb'
-** is true, also registers the result in the global table.
+** Stripped-down 'require': After checking "loaded" table, calls 'openf'
+** to open a module, registers the result in 'package.loaded' table and,
+** if 'glb' is true, also registers the result in the global table.
** Leaves resulting module on the top.
*/
LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
lua_CFunction openf, int glb) {
- lua_pushcfunction(L, openf);
- lua_pushstring(L, modname); /* argument to open function */
- lua_call(L, 1, 1); /* open module */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_pushvalue(L, -2); /* make copy of module (call result) */
- lua_setfield(L, -2, modname); /* _LOADED[modname] = module */
- lua_pop(L, 1); /* remove _LOADED table */
+ lua_getfield(L, -1, modname); /* _LOADED[modname] */
+ if (!lua_toboolean(L, -1)) { /* package not already loaded? */
+ lua_pop(L, 1); /* remove field */
+ lua_pushcfunction(L, openf);
+ lua_pushstring(L, modname); /* argument to open function */
+ lua_call(L, 1, 1); /* call 'openf' to open module */
+ lua_pushvalue(L, -1); /* make copy of module (call result) */
+ lua_setfield(L, -3, modname); /* _LOADED[modname] = module */
+ }
+ lua_remove(L, -2); /* remove _LOADED table */
if (glb) {
- lua_pushvalue(L, -1); /* copy of 'mod' */
+ lua_pushvalue(L, -1); /* copy of module */
lua_setglobal(L, modname); /* _G[modname] = module */
}
}
@@ -963,13 +952,12 @@ LUALIB_API lua_State *luaL_newstate (void) {
LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
const lua_Number *v = lua_version(L);
+ if (sz != LUAL_NUMSIZES) /* check numeric types */
+ luaL_error(L, "core and library have incompatible numeric types");
if (v != lua_version(NULL))
luaL_error(L, "multiple Lua VMs detected");
else if (*v != ver)
luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
ver, *v);
- /* check numeric types */
- if (sz != LUAL_NUMSIZES)
- luaL_error(L, "core and library have incompatible numeric types");
}
diff --git a/src/lauxlib.h b/src/lauxlib.h
index 3ffe3561..b5560143 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.124 2014/04/15 18:25:49 roberto Exp $
+** $Id: lauxlib.h,v 1.125 2014/06/26 17:25:11 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -46,9 +46,6 @@ LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
lua_Integer def);
-LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int arg);
-LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int arg,
- lua_Unsigned def);
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
@@ -211,6 +208,22 @@ LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
#endif
+/*
+** {============================================================
+** Compatibility with deprecated unsigned conversions
+** =============================================================
+*/
+#if defined(LUA_COMPAT_APIUNSIGNED)
+
+#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)))
+
+#endif
+/* }============================================================ */
+
+
+
#endif
diff --git a/src/lbaselib.c b/src/lbaselib.c
index deefe6c6..de1a767f 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.289 2014/06/10 17:41:38 roberto Exp $
+** $Id: lbaselib.c,v 1.293 2014/07/24 19:33:29 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -200,9 +200,12 @@ static int luaB_collectgarbage (lua_State *L) {
}
+/*
+** This function has all type names as upvalues, to maximize performance.
+*/
static int luaB_type (lua_State *L) {
luaL_checkany(L, 1);
- lua_pushstring(L, luaL_typename(L, 1));
+ lua_pushvalue(L, lua_upvalueindex(lua_type(L, 1) + 1));
return 1;
}
@@ -241,17 +244,53 @@ static int luaB_pairs (lua_State *L) {
}
-static int ipairsaux (lua_State *L) {
- int i = luaL_checkint(L, 2);
+/*
+** Traversal function for 'ipairs' for raw tables
+*/
+static int ipairsaux_raw (lua_State *L) {
+ int i = luaL_checkint(L, 2) + 1;
luaL_checktype(L, 1, LUA_TTABLE);
- i++; /* next value */
lua_pushinteger(L, i);
return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2;
}
+/*
+** 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;
+ }
+}
+
+
+/*
+** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
+** traverse a table, depending on whether the table has metamethods
+** that can affect the traversal.
+*/
static int luaB_ipairs (lua_State *L) {
- return pairsmeta(L, "__ipairs", 1, ipairsaux);
+ lua_CFunction iter =
+ (luaL_getmetafield(L, 1, "__len") ||
+ luaL_getmetafield(L, 1, "__index"))
+ ? ipairsaux : ipairsaux_raw;
+#if defined(LUA_COMPAT_IPAIRS)
+ return pairsmeta(L, "__ipairs", 1, iter);
+#else
+ lua_pushcfunction(L, iter); /* iteration function */
+ lua_pushvalue(L, 1); /* state */
+ lua_pushinteger(L, 0); /* initial value */
+ return 3;
+#endif
}
@@ -341,7 +380,7 @@ static int luaB_load (lua_State *L) {
/* }====================================================== */
-static int dofilecont (lua_State *L, int d1, int d2) {
+static int dofilecont (lua_State *L, int d1, lua_Ctx d2) {
(void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */
return lua_gettop(L) - 1;
}
@@ -387,12 +426,12 @@ static int luaB_select (lua_State *L) {
/*
** Continuation function for 'pcall' and 'xpcall'. Both functions
-** already pushed a 'true' before doing the call, so in case of sucess
+** already pushed a 'true' before doing the call, so in case of success
** 'finishpcall' only has to return everything in the stack minus
** 'extra' values (where 'extra' is exactly the number of items to be
** ignored).
*/
-static int finishpcall (lua_State *L, int status, int extra) {
+static int finishpcall (lua_State *L, int status, lua_Ctx extra) {
if (status != LUA_OK && status != LUA_YIELD) { /* error? */
lua_pushboolean(L, 0); /* first result (false) */
lua_pushvalue(L, -2); /* error message */
@@ -461,21 +500,31 @@ static const luaL_Reg base_funcs[] = {
{"setmetatable", luaB_setmetatable},
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
- {"type", luaB_type},
{"xpcall", luaB_xpcall},
+ /* placeholders */
+ {"type", NULL},
+ {"_G", NULL},
+ {"_VERSION", NULL},
{NULL, NULL}
};
LUAMOD_API int luaopen_base (lua_State *L) {
- /* set global _G */
- lua_pushglobaltable(L);
- lua_pushglobaltable(L);
- lua_setfield(L, -2, "_G");
+ int i;
/* open lib into global table */
+ lua_pushglobaltable(L);
luaL_setfuncs(L, base_funcs, 0);
+ /* set global _G */
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "_G");
+ /* set global _VERSION */
lua_pushliteral(L, LUA_VERSION);
- lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */
+ lua_setfield(L, -2, "_VERSION");
+ /* set function 'type' with proper upvalues */
+ for (i = 0; i < LUA_NUMTAGS; i++) /* push all type names as upvalues */
+ lua_pushstring(L, lua_typename(L, i));
+ lua_pushcclosure(L, luaB_type, LUA_NUMTAGS);
+ lua_setfield(L, -2, "type");
return 1;
}
diff --git a/src/ldebug.c b/src/ldebug.c
index c1f8c3f2..3321d9f1 100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.97 2013/12/09 14:21:10 roberto Exp $
+** $Id: ldebug.c,v 2.100 2014/07/30 14:00:14 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -271,7 +271,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
if (*what == '>') {
ci = NULL;
func = L->top - 1;
- api_check(L, ttisfunction(func), "function expected");
+ api_check(ttisfunction(func), "function expected");
what++; /* skip the '>' */
L->top--; /* pop function */
}
@@ -526,26 +526,27 @@ l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
- if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
- lua_assert(!ttisstring(p1) && !ttisnumber(p1));
+ if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
luaG_typeerror(L, p1, "concatenate");
}
l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
lua_Number temp;
- if (!tonumber(p1, &temp))
- p2 = p1; /* first operand is wrong */
+ if (!tonumber(p1, &temp)) /* first operand is wrong? */
+ p2 = p1; /* now second is wrong */
luaG_typeerror(L, p2, "perform arithmetic on");
}
+/*
+** Error when both values are convertible to numbers, but not to integers
+*/
l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
lua_Integer temp;
if (!tointeger(p1, &temp))
p2 = p1;
- luaG_runerror(L, "attempt to convert an out of range float%s to an integer",
- varinfo(L, p2));
+ luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2));
}
diff --git a/src/ldo.c b/src/ldo.c
index a4ba3bd0..500de40d 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.123 2014/06/19 18:27:20 roberto Exp $
+** $Id: ldo.c,v 2.126 2014/07/17 13:53:37 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -516,7 +516,7 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
/*
** Do the work for 'lua_resume' in protected mode. Most of the work
** depends on the status of the coroutine: initial state, suspended
-** inside a hook, or regulary suspended (optionally with a continuation
+** inside a hook, or regularly suspended (optionally with a continuation
** function), plus erroneous cases: non-suspended coroutine or dead
** coroutine.
*/
@@ -593,7 +593,8 @@ LUA_API int lua_isyieldable (lua_State *L) {
}
-LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_KFunction k) {
+LUA_API int lua_yieldk (lua_State *L, int nresults, lua_Ctx ctx,
+ lua_KFunction k) {
CallInfo *ci = L->ci;
luai_userstateyield(L, nresults);
lua_lock(L);
@@ -607,7 +608,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_KFunction k) {
L->status = LUA_YIELD;
ci->extra = savestack(L, ci->func); /* save current 'func' */
if (isLua(ci)) { /* inside a hook? */
- api_check(L, k == NULL, "hooks cannot continue after yielding");
+ api_check(k == NULL, "hooks cannot continue after yielding");
}
else {
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
diff --git a/src/ldump.c b/src/ldump.c
index 0be56c65..4418f3be 100644
--- a/src/ldump.c
+++ b/src/ldump.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldump.c,v 2.32 2014/06/18 18:35:43 roberto Exp $
+** $Id: ldump.c,v 2.33 2014/07/18 13:36:14 roberto Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -71,7 +71,7 @@ static void DumpString (const TString *s, DumpState *D) {
if (s == NULL)
DumpByte(0, D);
else {
- size_t size = s->tsv.len + 1; /* include trailing '\0' */
+ size_t size = s->len + 1; /* include trailing '\0' */
if (size < 0xFF)
DumpByte(cast_int(size), D);
else {
@@ -112,7 +112,7 @@ static void DumpConstants (const Proto *f, DumpState *D) {
break;
case LUA_TSHRSTR:
case LUA_TLNGSTR:
- DumpString(rawtsvalue(o), D);
+ DumpString(tsvalue(o), D);
break;
default:
lua_assert(0);
diff --git a/src/lgc.c b/src/lgc.c
index 74cacdae..84e8778d 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.183 2014/05/25 19:08:32 roberto Exp $
+** $Id: lgc.c,v 2.192 2014/07/29 16:22:24 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -62,10 +62,10 @@
*/
#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS))
#define makewhite(g,x) \
- (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))
+ (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g)))
-#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS)
-#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT)
+#define white2gray(x) resetbits(x->marked, WHITEBITS)
+#define black2gray(x) resetbit(x->marked, BLACKBIT)
#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
@@ -81,7 +81,7 @@
if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
#define markobject(g,t) \
- { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); }
+ { if ((t) && iswhite(t)) reallymarkobject(g, obj2gco(t)); }
static void reallymarkobject (global_State *g, GCObject *o);
@@ -112,7 +112,7 @@ static void reallymarkobject (global_State *g, GCObject *o);
static void removeentry (Node *n) {
lua_assert(ttisnil(gval(n)));
if (valiswhite(gkey(n)))
- setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */
+ setdeadvalue(wgkey(n)); /* unused and unmarked key; remove it */
}
@@ -126,7 +126,7 @@ static void removeentry (Node *n) {
static int iscleared (global_State *g, const TValue *o) {
if (!iscollectable(o)) return 0;
else if (ttisstring(o)) {
- markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */
+ markobject(g, tsvalue(o)); /* strings are `values', so are never weak */
return 0;
}
else return iswhite(gcvalue(o));
@@ -135,13 +135,13 @@ static int iscleared (global_State *g, const TValue *o) {
/*
** barrier that moves collector forward, that is, mark the white object
-** being pointed by a black object.
+** being pointed by a black object. (If in sweep phase, clear the black
+** object to white [sweep it] to avoid other barrier calls for this
+** same object.)
*/
void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
global_State *g = G(L);
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
- lua_assert(g->gcstate != GCSpause);
- lua_assert(gch(o)->tt != LUA_TTABLE); /* tables use a back barrier */
if (keepinvariant(g)) /* must keep invariant? */
reallymarkobject(g, v); /* restore invariant */
else { /* sweep phase */
@@ -153,16 +153,14 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
/*
** barrier that moves collector backward, that is, mark the black object
-** pointing to a white object as gray again. (Current implementation
-** only works for tables; access to 'gclist' is not uniform across
-** different types.)
+** pointing to a white object as gray again.
*/
-void luaC_barrierback_ (lua_State *L, GCObject *o) {
+void luaC_barrierback_ (lua_State *L, Table *t) {
global_State *g = G(L);
- lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE);
- black2gray(o); /* make object gray (again) */
- gco2t(o)->gclist = g->grayagain;
- g->grayagain = o;
+ lua_assert(isblack(t) && !isdead(g, t));
+ black2gray(t); /* make table gray (again) */
+ t->gclist = g->grayagain;
+ g->grayagain = obj2gco(t);
}
@@ -185,8 +183,8 @@ void luaC_fix (lua_State *L, GCObject *o) {
global_State *g = G(L);
lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */
white2gray(o); /* they will be gray forever */
- g->allgc = o->gch.next; /* remove object from 'allgc' list */
- o->gch.next = g->fixedgc; /* link it to 'fixedgc' list */
+ g->allgc = o->next; /* remove object from 'allgc' list */
+ o->next = g->fixedgc; /* link it to 'fixedgc' list */
g->fixedgc = o;
}
@@ -198,9 +196,9 @@ void luaC_fix (lua_State *L, GCObject *o) {
GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
global_State *g = G(L);
GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz));
- gch(o)->marked = luaC_white(g);
- gch(o)->tt = tt;
- gch(o)->next = g->allgc;
+ o->marked = luaC_white(g);
+ o->tt = tt;
+ o->next = g->allgc;
g->allgc = o;
return o;
}
@@ -225,7 +223,7 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
static void reallymarkobject (global_State *g, GCObject *o) {
reentry:
white2gray(o);
- switch (gch(o)->tt) {
+ switch (o->tt) {
case LUA_TSHRSTR:
case LUA_TLNGSTR: {
gray2black(o);
@@ -237,7 +235,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
markobject(g, gco2u(o)->metatable); /* mark its metatable */
gray2black(o);
g->GCmemtrav += sizeudata(gco2u(o));
- getuservalue(g->mainthread, rawgco2u(o), &uvalue);
+ getuservalue(g->mainthread, gco2u(o), &uvalue);
if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */
o = gcvalue(&uvalue);
goto reentry;
@@ -288,7 +286,7 @@ static void markmt (global_State *g) {
*/
static void markbeingfnz (global_State *g) {
GCObject *o;
- for (o = g->tobefnz; o != NULL; o = gch(o)->next)
+ for (o = g->tobefnz; o != NULL; o = o->next)
markobject(g, o);
}
@@ -303,8 +301,8 @@ static void remarkupvals (global_State *g) {
lua_State *thread;
lua_State **p = &g->twups;
while ((thread = *p) != NULL) {
- lua_assert(!isblack(obj2gco(thread))); /* threads are never black */
- if (isgray(obj2gco(thread)) && thread->openupval != NULL)
+ lua_assert(!isblack(thread)); /* threads are never black */
+ if (isgray(thread) && thread->openupval != NULL)
p = &thread->twups; /* keep marked thread with upvalues in the list */
else { /* thread is not marked or without upvalues */
UpVal *uv;
@@ -429,7 +427,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
((weakkey = strchr(svalue(mode), 'k')),
(weakvalue = strchr(svalue(mode), 'v')),
(weakkey || weakvalue))) { /* is really weak? */
- black2gray(obj2gco(h)); /* keep table gray */
+ black2gray(h); /* keep table gray */
if (!weakkey) /* strong keys? */
traverseweakvalue(g, h);
else if (!weakvalue) /* strong values? */
@@ -446,7 +444,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
static int traverseproto (global_State *g, Proto *f) {
int i;
- if (f->cache && iswhite(obj2gco(f->cache)))
+ if (f->cache && iswhite(f->cache))
f->cache = NULL; /* allow cache to be collected */
markobject(g, f->source);
for (i = 0; i < f->sizek; i++) /* mark literals */
@@ -528,7 +526,7 @@ static void propagatemark (global_State *g) {
GCObject *o = g->gray;
lua_assert(isgray(o));
gray2black(o);
- switch (gch(o)->tt) {
+ switch (o->tt) {
case LUA_TTABLE: {
Table *h = gco2t(o);
g->gray = h->gclist; /* remove from 'gray' list */
@@ -685,7 +683,7 @@ static void freeLclosure (lua_State *L, LClosure *cl) {
static void freeobj (lua_State *L, GCObject *o) {
- switch (gch(o)->tt) {
+ switch (o->tt) {
case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
case LUA_TLCL: {
freeLclosure(L, gco2lcl(o));
@@ -699,7 +697,7 @@ static void freeobj (lua_State *L, GCObject *o) {
case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
case LUA_TSHRSTR:
- luaS_remove(L, rawgco2ts(o)); /* remove it from hash table */
+ luaS_remove(L, gco2ts(o)); /* remove it from hash table */
/* go through */
case LUA_TLNGSTR: {
luaM_freemem(L, o, sizestring(gco2ts(o)));
@@ -727,14 +725,14 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
int white = luaC_white(g); /* current white */
while (*p != NULL && count-- > 0) {
GCObject *curr = *p;
- int marked = gch(curr)->marked;
+ int marked = curr->marked;
if (isdeadm(ow, marked)) { /* is 'curr' dead? */
- *p = gch(curr)->next; /* remove 'curr' from list */
+ *p = curr->next; /* remove 'curr' from list */
freeobj(L, curr); /* erase 'curr' */
}
else { /* update marks */
- gch(curr)->marked = cast_byte((marked & maskcolors) | white);
- p = &gch(curr)->next; /* go to next element */
+ curr->marked = cast_byte((marked & maskcolors) | white);
+ p = &curr->next; /* go to next element */
}
}
return (*p == NULL) ? NULL : p;
@@ -781,10 +779,10 @@ static void checkSizes (lua_State *L, global_State *g) {
static GCObject *udata2finalize (global_State *g) {
GCObject *o = g->tobefnz; /* get first element */
lua_assert(tofinalize(o));
- g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */
- gch(o)->next = g->allgc; /* return it to 'allgc' list */
+ g->tobefnz = o->next; /* remove it from 'tobefnz' list */
+ o->next = g->allgc; /* return it to 'allgc' list */
g->allgc = o;
- resetbit(gch(o)->marked, FINALIZEDBIT); /* object is "normal" again */
+ resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */
if (issweepphase(g))
makewhite(g, o); /* "sweep" object */
return o;
@@ -859,7 +857,7 @@ static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
*/
static GCObject **findlast (GCObject **p) {
while (*p != NULL)
- p = &gch(*p)->next;
+ p = &(*p)->next;
return p;
}
@@ -875,12 +873,12 @@ static void separatetobefnz (global_State *g, int all) {
while ((curr = *p) != NULL) { /* traverse all finalizable objects */
lua_assert(tofinalize(curr));
if (!(iswhite(curr) || all)) /* not being collected? */
- p = &gch(curr)->next; /* don't bother with it */
+ p = &curr->next; /* don't bother with it */
else {
- *p = gch(curr)->next; /* remove 'curr' from "fin" list */
- gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */
+ *p = curr->next; /* remove 'curr' from "fin" list */
+ curr->next = *lastnext; /* link at the end of 'tobefnz' list */
*lastnext = curr;
- lastnext = &gch(curr)->next;
+ lastnext = &curr->next;
}
}
}
@@ -899,15 +897,15 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
GCObject **p;
if (issweepphase(g)) {
makewhite(g, o); /* "sweep" object 'o' */
- if (g->sweepgc == &o->gch.next) /* shoud not remove 'sweepgc' object */
+ if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */
}
/* search for pointer pointing to 'o' */
- for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }
- *p = o->gch.next; /* remove 'o' from 'allgc' list */
- o->gch.next = g->finobj; /* link it in "fin" list */
+ 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 */
g->finobj = o;
- l_setbit(o->gch.marked, FINALIZEDBIT); /* mark it as such */
+ l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */
}
}
@@ -975,7 +973,7 @@ static l_mem atomic (lua_State *L) {
l_mem work;
GCObject *origweak, *origall;
g->GCmemtrav = 0; /* start counting work */
- lua_assert(!iswhite(obj2gco(g->mainthread)));
+ lua_assert(!iswhite(g->mainthread));
g->gcstate = GCSinsideatomic;
markobject(g, L); /* mark running thread */
/* registry and global metatables may be changed by API */
@@ -1066,7 +1064,7 @@ static lu_mem singlestep (lua_State *L) {
return sweepstep(L, g, GCSswpend, NULL);
}
case GCSswpend: { /* finish sweeps */
- makewhite(g, obj2gco(g->mainthread)); /* sweep main thread */
+ makewhite(g, g->mainthread); /* sweep main thread */
checkSizes(L, g);
g->gcstate = GCScallfin;
return 0;
diff --git a/src/lgc.h b/src/lgc.h
index 5ba91082..81e6aa53 100644
--- a/src/lgc.h
+++ b/src/lgc.h
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.h,v 2.82 2014/03/19 18:51:16 roberto Exp $
+** $Id: lgc.h,v 2.85 2014/07/19 15:14:46 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -84,19 +84,19 @@
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
-#define iswhite(x) testbits((x)->gch.marked, WHITEBITS)
-#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
+#define iswhite(x) testbits((x)->marked, WHITEBITS)
+#define isblack(x) testbit((x)->marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \
- (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
+ (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
-#define tofinalize(x) testbit((x)->gch.marked, FINALIZEDBIT)
+#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
-#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked)
+#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
-#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
-#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
+#define changewhite(x) ((x)->marked ^= WHITEBITS)
+#define gray2black(x) l_setbit((x)->marked, BLACKBIT)
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
@@ -107,15 +107,15 @@
#define luaC_barrier(L,p,v) { \
- if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \
+ if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \
luaC_barrier_(L,obj2gco(p),gcvalue(v)); }
#define luaC_barrierback(L,p,v) { \
- if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \
- luaC_barrierback_(L,obj2gco(p)); }
+ if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \
+ luaC_barrierback_(L,p); }
#define luaC_objbarrier(L,p,o) { \
- if (isblack(obj2gco(p)) && iswhite(obj2gco(o))) \
+ if (isblack(p) && iswhite(o)) \
luaC_barrier_(L,obj2gco(p),obj2gco(o)); }
#define luaC_upvalbarrier(L,uv) \
@@ -129,7 +129,7 @@ LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
-LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
+LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o);
LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv);
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
diff --git a/src/liolib.c b/src/liolib.c
index 5613aa1a..96cb1a31 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c,v 2.126 2014/06/02 03:00:51 roberto Exp $
+** $Id: liolib.c,v 2.128 2014/07/29 16:01:00 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -402,11 +402,11 @@ static int test2 (RN *rn, const char *set) {
/*
-** Read a sequence of (hexa)digits
+** Read a sequence of (hex)digits
*/
-static int readdigits (RN *rn, int hexa) {
+static int readdigits (RN *rn, int hex) {
int count = 0;
- while ((hexa ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn))
+ while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn))
count++;
return count;
}
@@ -426,7 +426,7 @@ static int readdigits (RN *rn, int hexa) {
static int read_number (lua_State *L, FILE *f) {
RN rn;
int count = 0;
- int hexa = 0;
+ int hex = 0;
char decp[2] = ".";
rn.f = f; rn.n = 0;
decp[0] = getlocaledecpoint(); /* get decimal point from locale */
@@ -434,13 +434,13 @@ static int read_number (lua_State *L, FILE *f) {
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
test2(&rn, "-+"); /* optional signal */
if (test2(&rn, "0")) {
- if (test2(&rn, "xX")) hexa = 1; /* numeral is hexadecimal */
+ if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
else count = 1; /* count initial '0' as a valid digit */
}
- count += readdigits(&rn, hexa); /* integral part */
+ count += readdigits(&rn, hex); /* integral part */
if (test2(&rn, decp)) /* decimal point? */
- count += readdigits(&rn, hexa); /* fractionary part */
- if (count > 0 && test2(&rn, (hexa ? "pP" : "eE"))) { /* exponent mark? */
+ count += readdigits(&rn, hex); /* fractional part */
+ if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */
test2(&rn, "-+"); /* exponent signal */
readdigits(&rn, 0); /* exponent digits */
}
@@ -654,7 +654,7 @@ static int f_setvbuf (lua_State *L) {
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
- int res = setvbuf(f, NULL, mode[op], sz);
+ int res = setvbuf(f, NULL, mode[op], (size_t)sz);
return luaL_fileresult(L, res == 0, NULL);
}
diff --git a/src/llex.c b/src/llex.c
index e358f20f..6a052080 100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 2.78 2014/05/21 15:22:02 roberto Exp $
+** $Id: llex.c,v 2.80 2014/07/18 13:36:14 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -71,7 +71,7 @@ void luaX_init (lua_State *L) {
for (i=0; i<NUM_RESERVED; i++) {
TString *ts = luaS_new(L, luaX_tokens[i]);
luaC_fix(L, obj2gco(ts)); /* reserved words are never collected */
- ts->tsv.extra = cast_byte(i+1); /* reserved word */
+ ts->extra = cast_byte(i+1); /* reserved word */
}
}
@@ -137,7 +137,7 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
luaC_checkGC(L);
}
else { /* string already present */
- ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */
+ ts = tsvalue(keyfromval(o)); /* re-use value previously stored */
}
L->top--; /* remove string from stack */
return ts;
@@ -565,7 +565,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
luaZ_bufflen(ls->buff));
seminfo->ts = ts;
if (isreserved(ts)) /* reserved word? */
- return ts->tsv.extra - 1 + FIRST_RESERVED;
+ return ts->extra - 1 + FIRST_RESERVED;
else {
return TK_NAME;
}
diff --git a/src/llimits.h b/src/llimits.h
index b3f7774d..1f41e257 100644
--- a/src/llimits.h
+++ b/src/llimits.h
@@ -1,5 +1,5 @@
/*
-** $Id: llimits.h,v 1.116 2014/04/15 16:32:49 roberto Exp $
+** $Id: llimits.h,v 1.120 2014/07/18 18:29:12 roberto Exp $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -28,36 +28,37 @@ typedef unsigned char lu_byte;
/* maximum value for size_t */
-#define MAX_SIZET ((size_t)(~(size_t)0)-2)
+#define MAX_SIZET ((size_t)(~(size_t)0))
/* maximum size visible for Lua (must be representable in a lua_Integer */
#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \
- : (size_t)(LUA_MAXINTEGER)-2)
+ : (size_t)(LUA_MAXINTEGER))
-#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
+#define MAX_LUMEM ((lu_mem)(~(lu_mem)0))
-#define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2))
+#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1))
-#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
+#define MAX_INT INT_MAX /* maximum value of an int */
/*
-** conversion of pointer to integer
+** conversion of pointer to integer:
** this is for hashing only; there is no problem if the integer
** cannot hold the whole pointer value
*/
-#define IntPoint(p) ((unsigned int)(lu_mem)(p))
+#define point2int(p) ((unsigned int)((lu_mem)(p) & UINT_MAX))
/* type to ensure maximum alignment */
-#if !defined(LUAI_USER_ALIGNMENT_T)
-#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
+#if defined(LUAI_USER_ALIGNMENT_T)
+typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
+#else
+typedef union { double u; void *s; lua_Integer i; long l; } L_Umaxalign;
#endif
-typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
/* types of 'usual argument conversions' for lua_Number and lua_Integer */
@@ -79,18 +80,15 @@ typedef LUAI_UACINT l_uacInt;
/*
** assertion for checking API calls
*/
-#if !defined(luai_apicheck)
-
#if defined(LUA_USE_APICHECK)
#include <assert.h>
-#define luai_apicheck(L,e) assert(e)
+#define luai_apicheck(e) assert(e)
#else
-#define luai_apicheck(L,e) lua_assert(e)
+#define luai_apicheck(e) lua_assert(e)
#endif
-#endif
-#define api_check(l,e,msg) luai_apicheck(l,(e) && msg)
+#define api_check(e,msg) luai_apicheck((e) && msg)
#if !defined(UNUSED)
diff --git a/src/lmathlib.c b/src/lmathlib.c
index 145b35ab..312df517 100644
--- a/src/lmathlib.c
+++ b/src/lmathlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmathlib.c,v 1.103 2014/06/18 12:35:53 roberto Exp $
+** $Id: lmathlib.c,v 1.108 2014/07/28 17:35:47 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -76,39 +76,39 @@ static int math_atan (lua_State *L) {
}
-static int math_ifloor (lua_State *L) {
+static int math_toint (lua_State *L) {
int valid;
lua_Integer n = lua_tointegerx(L, 1, &valid);
if (valid)
- lua_pushinteger(L, n); /* floor computed by Lua */
+ lua_pushinteger(L, n);
else {
- luaL_checktype(L, 1, LUA_TNUMBER); /* argument must be a number */
- lua_pushnil(L); /* number is not convertible to integer */
+ luaL_checkany(L, 1);
+ lua_pushnil(L); /* value is not convertible to integer */
}
return 1;
}
-static int math_floor (lua_State *L) {
- int valid;
- lua_Integer n = lua_tointegerx(L, 1, &valid);
- if (valid)
- lua_pushinteger(L, n); /* floor computed by Lua */
- else
- lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-
static void pushnumint (lua_State *L, lua_Number d) {
lua_Integer n;
- if (lua_numtointeger(d, &n)) /* fits in an integer? */
+ if (lua_numtointeger(d, &n)) /* does 'd' fit in an integer? */
lua_pushinteger(L, n); /* result is integer */
else
lua_pushnumber(L, d); /* result is float */
}
+static int math_floor (lua_State *L) {
+ if (lua_isinteger(L, 1))
+ lua_settop(L, 1); /* integer is its own floor */
+ else {
+ lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1));
+ pushnumint(L, d);
+ }
+ return 1;
+}
+
+
static int math_ceil (lua_State *L) {
if (lua_isinteger(L, 1))
lua_settop(L, 1); /* integer is its own ceil */
@@ -145,14 +145,14 @@ static int math_fmod (lua_State *L) {
static int math_modf (lua_State *L) {
if (lua_isinteger(L ,1)) {
lua_settop(L, 1); /* number is its own integer part */
- lua_pushnumber(L, 0); /* no fractionary part */
+ lua_pushnumber(L, 0); /* no fractional part */
}
else {
lua_Number n = luaL_checknumber(L, 1);
/* integer part (rounds toward zero) */
lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n);
pushnumint(L, ip);
- /* fractionary part (test needed for inf/-inf) */
+ /* fractional part (test needed for inf/-inf) */
lua_pushnumber(L, (n == ip) ? 0.0 : (n - ip));
}
return 2;
@@ -164,6 +164,14 @@ static int math_sqrt (lua_State *L) {
return 1;
}
+
+static int math_ult (lua_State *L) {
+ lua_Integer a = luaL_checkinteger(L, 1);
+ lua_Integer b = luaL_checkinteger(L, 2);
+ lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b);
+ return 1;
+}
+
static int math_log (lua_State *L) {
lua_Number x = luaL_checknumber(L, 1);
lua_Number res;
@@ -257,22 +265,23 @@ static int math_random (lua_State *L) {
static int math_randomseed (lua_State *L) {
- l_srand((unsigned int)luaL_checkunsigned(L, 1));
+ l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1));
(void)rand(); /* discard first value to avoid undesirable correlations */
return 0;
}
static int math_type (lua_State *L) {
- luaL_checkany(L, 1);
if (lua_type(L, 1) == LUA_TNUMBER) {
if (lua_isinteger(L, 1))
lua_pushliteral(L, "integer");
else
lua_pushliteral(L, "float");
}
- else
+ else {
+ luaL_checkany(L, 1);
lua_pushnil(L);
+ }
return 1;
}
@@ -339,9 +348,10 @@ static const luaL_Reg mathlib[] = {
{"cos", math_cos},
{"deg", math_deg},
{"exp", math_exp},
- {"ifloor", math_ifloor},
+ {"tointeger", math_toint},
{"floor", math_floor},
{"fmod", math_fmod},
+ {"ult", math_ult},
{"log", math_log},
{"max", math_max},
{"min", math_min},
@@ -363,6 +373,11 @@ static const luaL_Reg mathlib[] = {
{"ldexp", math_ldexp},
{"log10", math_log10},
#endif
+ /* placeholders */
+ {"pi", NULL},
+ {"huge", NULL},
+ {"maxinteger", NULL},
+ {"mininteger", NULL},
{NULL, NULL}
};
diff --git a/src/lmem.c b/src/lmem.c
index 3f88496e..a0d2dbe9 100644
--- a/src/lmem.c
+++ b/src/lmem.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmem.c,v 1.84 2012/05/23 15:41:53 roberto Exp $
+** $Id: lmem.c,v 1.86 2014/07/15 21:26:50 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -83,12 +83,10 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
#endif
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
if (newblock == NULL && nsize > 0) {
- api_check(L, nsize > realosize,
+ api_check( nsize > realosize,
"realloc cannot fail when shrinking a block");
- if (g->gcrunning) {
- luaC_fullgc(L, 1); /* try to free some memory... */
- newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
- }
+ luaC_fullgc(L, 1); /* try to free some memory... */
+ newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
if (newblock == NULL)
luaD_throw(L, LUA_ERRMEM);
}
diff --git a/src/loadlib.c b/src/loadlib.c
index 5333311d..4894188a 100644
--- a/src/loadlib.c
+++ b/src/loadlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.113 2014/03/12 20:57:40 roberto Exp $
+** $Id: loadlib.c,v 1.116 2014/07/29 16:01:00 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -97,20 +97,33 @@
#define LIB_FAIL "open"
-
-/* error codes for ll_loadfunc */
-#define ERRLIB 1
-#define ERRFUNC 2
-
#define setprogdir(L) ((void)0)
/*
** system-dependent functions
*/
-static void ll_unloadlib (void *lib);
-static void *ll_load (lua_State *L, const char *path, int seeglb);
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
+
+/*
+** unload library 'lib'
+*/
+static void lsys_unloadlib (void *lib);
+
+/*
+** load C library in file 'path'. If 'seeglb', load with all names in
+** the library global.
+** Returns the library; in case of error, returns NULL plus an
+** error string in the stack.
+*/
+static void *lsys_load (lua_State *L, const char *path, int seeglb);
+
+/*
+** Try to find a function named 'sym' in library 'lib'.
+** Returns the function; in case of error, returns NULL plus an
+** error string in the stack.
+*/
+static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
+
@@ -126,19 +139,19 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
#include <dlfcn.h>
-static void ll_unloadlib (void *lib) {
+static void lsys_unloadlib (void *lib) {
dlclose(lib);
}
-static void *ll_load (lua_State *L, const char *path, int seeglb) {
+static void *lsys_load (lua_State *L, const char *path, int seeglb) {
void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
if (lib == NULL) lua_pushstring(L, dlerror());
return lib;
}
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
if (f == NULL) lua_pushstring(L, dlerror());
return f;
@@ -190,12 +203,12 @@ static void pusherror (lua_State *L) {
lua_pushfstring(L, "system error %d\n", error);
}
-static void ll_unloadlib (void *lib) {
+static void lsys_unloadlib (void *lib) {
FreeLibrary((HMODULE)lib);
}
-static void *ll_load (lua_State *L, const char *path, int seeglb) {
+static void *lsys_load (lua_State *L, const char *path, int seeglb) {
HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
(void)(seeglb); /* not used: symbols are 'global' by default */
if (lib == NULL) pusherror(L);
@@ -203,7 +216,7 @@ static void *ll_load (lua_State *L, const char *path, int seeglb) {
}
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
if (f == NULL) pusherror(L);
return f;
@@ -226,19 +239,19 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
-static void ll_unloadlib (void *lib) {
+static void lsys_unloadlib (void *lib) {
(void)(lib); /* not used */
}
-static void *ll_load (lua_State *L, const char *path, int seeglb) {
+static void *lsys_load (lua_State *L, const char *path, int seeglb) {
(void)(path); (void)(seeglb); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
(void)(lib); (void)(sym); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
@@ -248,7 +261,10 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
#endif
-static void *ll_checkclib (lua_State *L, const char *path) {
+/*
+** return registry.CLIBS[path]
+*/
+static void *checkclib (lua_State *L, const char *path) {
void *plib;
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
lua_getfield(L, -1, path);
@@ -258,7 +274,11 @@ static void *ll_checkclib (lua_State *L, const char *path) {
}
-static void ll_addtoclib (lua_State *L, const char *path, void *plib) {
+/*
+** registry.CLIBS[path] = plib -- for queries
+** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
+*/
+static void addtoclib (lua_State *L, const char *path, void *plib) {
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
lua_pushlightuserdata(L, plib);
lua_pushvalue(L, -1);
@@ -269,33 +289,49 @@ static void ll_addtoclib (lua_State *L, const char *path, void *plib) {
/*
-** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib
+** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
** handles in list CLIBS
*/
static int gctm (lua_State *L) {
- int n = luaL_len(L, 1);
+ lua_Integer n = luaL_len(L, 1);
for (; n >= 1; n--) { /* for each handle, in reverse order */
lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
- ll_unloadlib(lua_touserdata(L, -1));
+ lsys_unloadlib(lua_touserdata(L, -1));
lua_pop(L, 1); /* pop handle */
}
return 0;
}
-static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
- void *reg = ll_checkclib(L, path); /* check loaded C libraries */
+
+/* error codes for 'lookforfunc' */
+#define ERRLIB 1
+#define ERRFUNC 2
+
+/*
+** Look for a C function named 'sym' in a dynamically loaded library
+** 'path'.
+** First, check whether the library is already loaded; if not, try
+** to load it.
+** Then, if 'sym' is '*', return true (as library has been loaded).
+** Otherwise, look for symbol 'sym' in the library and push a
+** C function with that symbol.
+** Return 0 and 'true' or a function in the stack; in case of
+** errors, return an error code and an error message in the stack.
+*/
+static int lookforfunc (lua_State *L, const char *path, const char *sym) {
+ void *reg = checkclib(L, path); /* check loaded C libraries */
if (reg == NULL) { /* must load library? */
- reg = ll_load(L, path, *sym == '*');
+ reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */
if (reg == NULL) return ERRLIB; /* unable to load library */
- ll_addtoclib(L, path, reg);
+ addtoclib(L, path, reg);
}
if (*sym == '*') { /* loading only library (no function)? */
lua_pushboolean(L, 1); /* return 'true' */
return 0; /* no errors */
}
else {
- lua_CFunction f = ll_sym(L, reg, sym);
+ lua_CFunction f = lsys_sym(L, reg, sym);
if (f == NULL)
return ERRFUNC; /* unable to find function */
lua_pushcfunction(L, f); /* else create new function */
@@ -307,7 +343,7 @@ static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
static int ll_loadlib (lua_State *L) {
const char *path = luaL_checkstring(L, 1);
const char *init = luaL_checkstring(L, 2);
- int stat = ll_loadfunc(L, path, init);
+ int stat = lookforfunc(L, path, init);
if (stat == 0) /* no errors? */
return 1; /* return the loaded function */
else { /* error; error message is on stack top */
@@ -416,21 +452,29 @@ static int searcher_Lua (lua_State *L) {
}
+/*
+** Try to find a load function for module 'modname' at file 'filename'.
+** First, change '.' to '_' in 'modname'; then, if 'modname' has
+** the form X-Y (that is, it has an "ignore mark"), build a function
+** name "luaopen_X" and look for it. (For compatibility, if that
+** fails, it also tries "luaopen_Y".) If there is no ignore mark,
+** look for a function named "luaopen_modname".
+*/
static int loadfunc (lua_State *L, const char *filename, const char *modname) {
- const char *funcname;
+ const char *openfunc;
const char *mark;
modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
mark = strchr(modname, *LUA_IGMARK);
if (mark) {
int stat;
- funcname = lua_pushlstring(L, modname, mark - modname);
- funcname = lua_pushfstring(L, LUA_POF"%s", funcname);
- stat = ll_loadfunc(L, filename, funcname);
+ openfunc = lua_pushlstring(L, modname, mark - modname);
+ openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc);
+ stat = lookforfunc(L, filename, openfunc);
if (stat != ERRFUNC) return stat;
modname = mark + 1; /* else go ahead and try old-style name */
}
- funcname = lua_pushfstring(L, LUA_POF"%s", modname);
- return ll_loadfunc(L, filename, funcname);
+ openfunc = lua_pushfstring(L, LUA_POF"%s", modname);
+ return lookforfunc(L, filename, openfunc);
}
@@ -655,6 +699,12 @@ static const luaL_Reg pk_funcs[] = {
#if defined(LUA_COMPAT_MODULE)
{"seeall", ll_seeall},
#endif
+ /* placeholders */
+ {"preload", NULL},
+ {"cpath", NULL},
+ {"path", NULL},
+ {"searchers", NULL},
+ {"loaded", NULL},
{NULL, NULL}
};
@@ -680,24 +730,31 @@ static void createsearcherstable (lua_State *L) {
lua_pushcclosure(L, searchers[i], 1);
lua_rawseti(L, -2, i+1);
}
+#if defined(LUA_COMPAT_LOADERS)
+ lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
+ lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */
+#endif
+ lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
}
-LUAMOD_API int luaopen_package (lua_State *L) {
- /* create table CLIBS to keep track of loaded C libraries */
- luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);
- lua_createtable(L, 0, 1); /* metatable for CLIBS */
+/*
+** create table CLIBS to keep track of loaded C libraries,
+** setting a finalizer to close all libraries when closing state.
+*/
+static void createclibstable (lua_State *L) {
+ luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */
+ lua_createtable(L, 0, 1); /* create metatable for CLIBS */
lua_pushcfunction(L, gctm);
lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
lua_setmetatable(L, -2);
- /* create `package' table */
- luaL_newlib(L, pk_funcs);
+}
+
+
+LUAMOD_API int luaopen_package (lua_State *L) {
+ createclibstable(L);
+ luaL_newlib(L, pk_funcs); /* create `package' table */
createsearcherstable(L);
-#if defined(LUA_COMPAT_LOADERS)
- lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
- lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */
-#endif
- lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
/* set field 'path' */
setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
/* set field 'cpath' */
diff --git a/src/lobject.c b/src/lobject.c
index 0130c1c0..2bcdbfa1 100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.86 2014/05/12 21:44:17 roberto Exp $
+** $Id: lobject.c,v 2.88 2014/07/30 14:00:14 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -256,7 +256,7 @@ static const char *l_str2d (const char *s, lua_Number *result) {
char *endptr;
if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
return NULL;
- else if (strpbrk(s, "xX")) /* hexa? */
+ else if (strpbrk(s, "xX")) /* hex? */
*result = lua_strx2number(s, &endptr);
else
*result = lua_str2number(s, &endptr);
@@ -273,7 +273,7 @@ static const char *l_str2int (const char *s, lua_Integer *result) {
while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
neg = isneg(&s);
if (s[0] == '0' &&
- (s[1] == 'x' || s[1] == 'X')) { /* hexa? */
+ (s[1] == 'x' || s[1] == 'X')) { /* hex? */
s += 2; /* skip '0x' */
for (; lisxdigit(cast_uchar(*s)); s++) {
a = a * 16 + luaO_hexavalue(cast_uchar(*s));
@@ -327,6 +327,32 @@ int luaO_utf8esc (char *buff, unsigned int x) {
}
+/* maximum length of the conversion of a number to a string */
+#define MAXNUMBER2STR 50
+
+
+/*
+** Convert a number object to a string
+*/
+void luaO_tostring (lua_State *L, StkId obj) {
+ char buff[MAXNUMBER2STR];
+ size_t len;
+ lua_assert(ttisnumber(obj));
+ if (ttisinteger(obj))
+ len = lua_integer2str(buff, ivalue(obj));
+ else {
+ len = lua_number2str(buff, fltvalue(obj));
+#if !defined(LUA_COMPAT_FLOATSTRING)
+ if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
+ buff[len++] = '.';
+ buff[len++] = '0'; /* adds '.0' to result */
+ }
+#endif
+ }
+ setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
+}
+
+
static void pushstr (lua_State *L, const char *str, size_t l) {
setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
}
@@ -349,24 +375,23 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
break;
}
case 'c': {
- char buff;
- buff = cast(char, va_arg(argp, int));
+ char buff = cast(char, va_arg(argp, int));
pushstr(L, &buff, 1);
break;
}
case 'd': {
- setivalue(L->top++, cast_int(va_arg(argp, int)));
- luaV_tostring(L, L->top - 1);
+ setivalue(L->top++, va_arg(argp, int));
+ luaO_tostring(L, L->top - 1);
break;
}
case 'I': {
setivalue(L->top++, cast(lua_Integer, va_arg(argp, l_uacInt)));
- luaV_tostring(L, L->top - 1);
+ luaO_tostring(L, L->top - 1);
break;
}
case 'f': {
setfltvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
- luaV_tostring(L, L->top - 1);
+ luaO_tostring(L, L->top - 1);
break;
}
case 'p': {
diff --git a/src/lobject.h b/src/lobject.h
index 7c512422..9972e08b 100644
--- a/src/lobject.h
+++ b/src/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.94 2014/06/19 18:39:36 roberto Exp $
+** $Id: lobject.h,v 2.101 2014/07/30 14:00:14 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -69,9 +69,9 @@
/*
-** Union of all collectable objects
+** Common type for all collectable objects
*/
-typedef union GCObject GCObject;
+typedef struct GCObject GCObject;
/*
@@ -82,11 +82,11 @@ typedef union GCObject GCObject;
/*
-** Common header in struct form
+** Common type has only the common header
*/
-typedef struct GCheader {
+struct GCObject {
CommonHeader;
-} GCheader;
+};
@@ -156,10 +156,8 @@ typedef struct lua_TValue TValue;
#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
-#define rawtsvalue(o) check_exp(ttisstring(o), rawgco2ts(val_(o).gc))
-#define tsvalue(o) (&rawtsvalue(o)->tsv)
-#define rawuvalue(o) check_exp(ttisfulluserdata(o), rawgco2u(val_(o).gc))
-#define uvalue(o) (&rawuvalue(o)->uv)
+#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
+#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
@@ -177,7 +175,7 @@ typedef struct lua_TValue TValue;
/* Macros for internal tests */
-#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt)
+#define righttt(obj) (ttype(obj) == gcvalue(obj)->tt)
#define checkliveness(g,obj) \
lua_longassert(!iscollectable(obj) || \
@@ -206,11 +204,11 @@ typedef struct lua_TValue TValue;
#define setgcovalue(L,obj,x) \
{ TValue *io = (obj); GCObject *i_g=(x); \
- val_(io).gc = i_g; settt_(io, ctb(gch(i_g)->tt)); }
+ val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }
#define setsvalue(L,obj,x) \
{ TValue *io = (obj); TString *x_ = (x); \
- val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tsv.tt)); \
+ val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
checkliveness(G(L),io); }
#define setuvalue(L,obj,x) \
@@ -243,8 +241,7 @@ typedef struct lua_TValue TValue;
#define setobj(L,obj1,obj2) \
- { const TValue *io2=(obj2); TValue *io1=(obj1); \
- io1->value_ = io2->value_; io1->tt_ = io2->tt_; \
+ { TValue *io1=(obj1); *io1 = *(obj2); \
(void)L; checkliveness(G(L),io1); }
@@ -299,50 +296,76 @@ typedef TValue *StkId; /* index to stack elements */
/*
** Header for string value; string bytes follow the end of this structure
+** (aligned according to 'UTString'; see next).
*/
-typedef union TString {
- L_Umaxalign dummy; /* ensures maximum alignment for strings */
- struct {
- CommonHeader;
- lu_byte extra; /* reserved words for short strings; "has hash" for longs */
- unsigned int hash;
- size_t len; /* number of characters in string */
- union TString *hnext; /* linked list for hash table */
- } tsv;
+typedef struct TString {
+ CommonHeader;
+ lu_byte extra; /* reserved words for short strings; "has hash" for longs */
+ unsigned int hash;
+ size_t len; /* number of characters in string */
+ struct TString *hnext; /* linked list for hash table */
} TString;
-/* get the actual string (array of bytes) from a TString */
-#define getstr(ts) cast(const char *, (ts) + 1)
+/*
+** Ensures that address after this type is always fully aligned.
+*/
+typedef union UTString {
+ L_Umaxalign dummy; /* ensures maximum alignment for strings */
+ TString tsv;
+} UTString;
+
+
+/*
+** Get the actual string (array of bytes) from a 'TString'.
+** (Access to 'extra' ensures that value is really a 'TString'.)
+*/
+#define getaddrstr(ts) (cast(char *, (ts)) + sizeof(UTString))
+#define getstr(ts) \
+ check_exp(sizeof((ts)->extra), cast(const char*, getaddrstr(ts)))
/* get the actual string (array of bytes) from a Lua value */
-#define svalue(o) getstr(rawtsvalue(o))
+#define svalue(o) getstr(tsvalue(o))
/*
** Header for userdata; memory area follows the end of this structure
+** (aligned according to 'UUdata'; see next).
*/
-typedef union Udata {
- L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
- struct {
- CommonHeader;
- lu_byte ttuv_; /* user value's tag */
- struct Table *metatable;
- size_t len; /* number of bytes */
- union Value user_; /* user value */
- } uv;
+typedef struct Udata {
+ CommonHeader;
+ lu_byte ttuv_; /* user value's tag */
+ struct Table *metatable;
+ size_t len; /* number of bytes */
+ union Value user_; /* user value */
} Udata;
+/*
+** Ensures that address after this type is always fully aligned.
+*/
+typedef union UUdata {
+ L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
+ Udata uv;
+} UUdata;
+
+
+/*
+** Get the address of memory block inside 'Udata'.
+** (Access to 'ttuv_' ensures that value is really a 'Udata'.)
+*/
+#define getudatamem(u) \
+ check_exp(sizeof((u)->ttuv_), (cast(char*, (u)) + sizeof(UUdata)))
+
#define setuservalue(L,u,o) \
{ const TValue *io=(o); Udata *iu = (u); \
- iu->uv.user_ = io->value_; iu->uv.ttuv_ = io->tt_; \
+ iu->user_ = io->value_; iu->ttuv_ = io->tt_; \
checkliveness(G(L),io); }
#define getuservalue(L,u,o) \
{ TValue *io=(o); const Udata *iu = (u); \
- io->value_ = iu->uv.user_; io->tt_ = iu->uv.ttuv_; \
+ io->value_ = iu->user_; io->tt_ = iu->ttuv_; \
checkliveness(G(L),io); }
@@ -447,6 +470,13 @@ typedef union TKey {
} TKey;
+/* copy a value into a key without messing up field 'next' */
+#define setkey(L,key,obj) \
+ { TKey *k_=(key); const TValue *io_=(obj); \
+ k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \
+ (void)L; checkliveness(G(L),io_); }
+
+
typedef struct Node {
TValue i_val;
TKey i_key;
@@ -497,6 +527,7 @@ LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
const TValue *p2, TValue *res);
LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o);
LUAI_FUNC int luaO_hexavalue (int c);
+LUAI_FUNC void luaO_tostring (lua_State *L, StkId obj);
LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
va_list argp);
LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
diff --git a/src/lparser.c b/src/lparser.c
index 6c097d7f..1e7e244a 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.139 2014/06/19 18:27:20 roberto Exp $
+** $Id: lparser.c,v 2.142 2014/07/21 16:02:10 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
diff --git a/src/lstate.c b/src/lstate.c
index 1628ad91..295fc4c7 100644
--- a/src/lstate.c
+++ b/src/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.121 2014/02/18 13:46:26 roberto Exp $
+** $Id: lstate.c,v 2.125 2014/07/24 16:17:56 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -53,9 +53,7 @@
** thread state + extra space
*/
typedef struct LX {
-#if defined(LUAI_EXTRASPACE)
- char buff[LUAI_EXTRASPACE];
-#endif
+ lu_byte extra_[LUA_EXTRASPACE];
lua_State l;
} LX;
@@ -252,7 +250,7 @@ static void close_state (lua_State *L) {
LUA_API lua_State *lua_newthread (lua_State *L) {
- global_State *g = G(L);
+ global_State *g = G(L);
lua_State *L1;
lua_lock(L);
luaC_checkGC(L);
@@ -263,6 +261,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
/* link it on list 'allgc' */
L1->next = g->allgc;
g->allgc = obj2gco(L1);
+ /* anchor it on L stack */
setthvalue(L, L->top, L1);
api_incr_top(L);
preinit_thread(L1, g);
@@ -270,6 +269,9 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
L1->basehookcount = L->basehookcount;
L1->hook = L->hook;
resethookcount(L1);
+ /* initialize L1 extra space */
+ memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread),
+ LUA_EXTRASPACE);
luai_userstatethread(L, L1);
stack_init(L1, L); /* init stack */
lua_unlock(L);
diff --git a/src/lstate.h b/src/lstate.h
index add9e95b..698bea0d 100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.107 2014/06/12 19:07:30 roberto Exp $
+** $Id: lstate.h,v 2.114 2014/07/23 17:15:43 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -60,9 +60,6 @@ typedef struct CallInfo {
StkId func; /* function index in the stack */
StkId top; /* top for this function */
struct CallInfo *previous, *next; /* dynamic call link */
- ptrdiff_t extra;
- short nresults; /* expected number of results from this function */
- lu_byte callstatus;
union {
struct { /* only for Lua functions */
StkId base; /* base for this function */
@@ -71,9 +68,12 @@ typedef struct CallInfo {
struct { /* only for C functions */
lua_KFunction k; /* continuation in case of yields */
ptrdiff_t old_errfunc;
- int ctx; /* context info. in case of yields */
+ lua_Ctx ctx; /* context info. in case of yields */
} c;
} u;
+ ptrdiff_t extra;
+ short nresults; /* expected number of results from this function */
+ lu_byte callstatus;
} CallInfo;
@@ -149,20 +149,20 @@ struct lua_State {
const Instruction *oldpc; /* last pc traced */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
- int stacksize;
- unsigned short nny; /* number of non-yieldable calls in stack */
- unsigned short nCcalls; /* number of nested C calls */
- lu_byte hookmask;
- lu_byte allowhook;
- int basehookcount;
- int hookcount;
- lua_Hook hook;
UpVal *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
struct lua_State *twups; /* list of threads with open upvalues */
struct lua_longjmp *errorJmp; /* current error recover point */
- ptrdiff_t errfunc; /* current error handling function (stack index) */
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
+ lua_Hook hook;
+ ptrdiff_t errfunc; /* current error handling function (stack index) */
+ int stacksize;
+ int basehookcount;
+ int hookcount;
+ unsigned short nny; /* number of non-yieldable calls in stack */
+ unsigned short nCcalls; /* number of nested C calls */
+ lu_byte hookmask;
+ lu_byte allowhook;
};
@@ -170,12 +170,12 @@ struct lua_State {
/*
-** Union of all collectable objects
+** Union of all collectable objects (only for conversions)
*/
-union GCObject {
- GCheader gch; /* common header */
- union TString ts;
- union Udata u;
+union GCUnion {
+ GCObject gc; /* common header */
+ struct TString ts;
+ struct Udata u;
union Closure cl;
struct Table h;
struct Proto p;
@@ -183,24 +183,24 @@ union GCObject {
};
-#define gch(o) (&(o)->gch)
+#define cast_u(o) cast(union GCUnion *, (o))
/* macros to convert a GCObject into a specific value */
-#define rawgco2ts(o) \
- check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts))
-#define gco2ts(o) (&rawgco2ts(o)->tsv)
-#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
-#define gco2u(o) (&rawgco2u(o)->uv)
-#define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l))
-#define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c))
+#define gco2ts(o) \
+ check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))
+#define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u))
+#define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l))
+#define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c))
#define gco2cl(o) \
- check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl))
-#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
-#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
-#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
+ check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))
+#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))
+#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))
+#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))
+
-/* macro to convert any Lua object into a GCObject */
-#define obj2gco(v) (cast(GCObject *, (v)))
+/* macro to convert a Lua object into a GCObject */
+#define obj2gco(v) \
+ check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc)))
/* actual number of total bytes allocated */
diff --git a/src/lstring.c b/src/lstring.c
index c63111a8..df28a7f2 100644
--- a/src/lstring.c
+++ b/src/lstring.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.c,v 2.40 2014/06/18 22:59:29 roberto Exp $
+** $Id: lstring.c,v 2.44 2014/07/21 16:02:10 roberto Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -34,10 +34,10 @@
** equality for long strings
*/
int luaS_eqlngstr (TString *a, TString *b) {
- size_t len = a->tsv.len;
- lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR);
+ size_t len = a->len;
+ lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
return (a == b) || /* same instance or... */
- ((len == b->tsv.len) && /* equal length and ... */
+ ((len == b->len) && /* equal length and ... */
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
}
@@ -67,9 +67,9 @@ void luaS_resize (lua_State *L, int newsize) {
TString *p = tb->hash[i];
tb->hash[i] = NULL;
while (p) { /* for each node in the list */
- TString *hnext = p->tsv.hnext; /* save next */
- unsigned int h = lmod(p->tsv.hash, newsize); /* new position */
- p->tsv.hnext = tb->hash[h]; /* chain it */
+ TString *hnext = p->hnext; /* save next */
+ unsigned int h = lmod(p->hash, newsize); /* new position */
+ p->hnext = tb->hash[h]; /* chain it */
tb->hash[h] = p;
p = hnext;
}
@@ -92,24 +92,24 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
TString *ts;
GCObject *o;
size_t totalsize; /* total size of TString object */
- totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
+ totalsize = sizelstring(l);
o = luaC_newobj(L, tag, totalsize);
- ts = rawgco2ts(o);
- ts->tsv.len = l;
- ts->tsv.hash = h;
- ts->tsv.extra = 0;
- memcpy(ts+1, str, l*sizeof(char));
- ((char *)(ts+1))[l] = '\0'; /* ending 0 */
+ ts = gco2ts(o);
+ ts->len = l;
+ ts->hash = h;
+ ts->extra = 0;
+ memcpy(getaddrstr(ts), str, l * sizeof(char));
+ getaddrstr(ts)[l] = '\0'; /* ending 0 */
return ts;
}
void luaS_remove (lua_State *L, TString *ts) {
stringtable *tb = &G(L)->strt;
- TString **p = &tb->hash[lmod(ts->tsv.hash, tb->size)];
+ TString **p = &tb->hash[lmod(ts->hash, tb->size)];
while (*p != ts) /* find previous element */
- p = &(*p)->tsv.hnext;
- *p = (*p)->tsv.hnext; /* remove element from its list */
+ p = &(*p)->hnext;
+ *p = (*p)->hnext; /* remove element from its list */
tb->nuse--;
}
@@ -122,12 +122,12 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
global_State *g = G(L);
unsigned int h = luaS_hash(str, l, g->seed);
TString **list = &g->strt.hash[lmod(h, g->strt.size)];
- for (ts = *list; ts != NULL; ts = ts->tsv.hnext) {
- if (l == ts->tsv.len &&
+ for (ts = *list; ts != NULL; ts = ts->hnext) {
+ if (l == ts->len &&
(memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
/* found! */
- if (isdead(g, obj2gco(ts))) /* dead (but not collected yet)? */
- changewhite(obj2gco(ts)); /* resurrect it */
+ if (isdead(g, ts)) /* dead (but not collected yet)? */
+ changewhite(ts); /* resurrect it */
return ts;
}
}
@@ -136,7 +136,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
}
ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
- ts->tsv.hnext = *list;
+ ts->hnext = *list;
*list = ts;
g->strt.nuse++;
return ts;
@@ -170,10 +170,10 @@ Udata *luaS_newudata (lua_State *L, size_t s) {
GCObject *o;
if (s > MAX_SIZE - sizeof(Udata))
luaM_toobig(L);
- o = luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s);
- u = rawgco2u(o);
- u->uv.len = s;
- u->uv.metatable = NULL;
+ o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s));
+ u = gco2u(o);
+ u->len = s;
+ u->metatable = NULL;
setuservalue(L, u, luaO_nilobject);
return u;
}
diff --git a/src/lstring.h b/src/lstring.h
index d5f5b249..d3f04caf 100644
--- a/src/lstring.h
+++ b/src/lstring.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.h,v 1.54 2014/03/19 18:51:42 roberto Exp $
+** $Id: lstring.h,v 1.56 2014/07/18 14:46:47 roberto Exp $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -12,9 +12,11 @@
#include "lstate.h"
-#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
+#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
+#define sizestring(s) sizelstring((s)->len)
-#define sizeudata(u) (sizeof(union Udata)+(u)->len)
+#define sizeludata(l) (sizeof(union UUdata) + (l))
+#define sizeudata(u) sizeludata((u)->len)
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
@@ -23,13 +25,13 @@
/*
** test whether a string is a reserved word
*/
-#define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0)
+#define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0)
/*
** equality for short strings, which are always internalized
*/
-#define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b))
+#define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b))
LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
diff --git a/src/lstrlib.c b/src/lstrlib.c
index 3cbd91b2..05330c80 100644
--- a/src/lstrlib.c
+++ b/src/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.198 2014/04/27 14:42:26 roberto Exp $
+** $Id: lstrlib.c,v 1.200 2014/07/30 13:59:24 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -59,7 +59,7 @@ static int str_sub (lua_State *L) {
if (start < 1) start = 1;
if (end > (lua_Integer)l) end = l;
if (start <= end)
- lua_pushlstring(L, s + start - 1, end - start + 1);
+ lua_pushlstring(L, s + start - 1, (size_t)(end - start + 1));
else lua_pushliteral(L, "");
return 1;
}
@@ -119,7 +119,7 @@ static int str_rep (lua_State *L) {
else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */
return luaL_error(L, "resulting string too large");
else {
- size_t totallen = n * l + (n - 1) * lsep;
+ size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep;
luaL_Buffer b;
char *p = luaL_buffinitsize(L, &b, totallen);
while (n-- > 1) { /* first n-1 copies (followed by separator) */
@@ -594,7 +594,7 @@ static int str_find_aux (lua_State *L, int find) {
/* explicit request or no special characters? */
if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
/* do a plain search */
- const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp);
+ const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp);
if (s2) {
lua_pushinteger(L, s2 - s + 1);
lua_pushinteger(L, s2 - s + lp);
@@ -685,7 +685,8 @@ static int gmatch (lua_State *L) {
static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
const char *e) {
size_t l, i;
- const char *news = lua_tolstring(ms->L, 3, &l);
+ lua_State *L = ms->L;
+ const char *news = lua_tolstring(L, 3, &l);
for (i = 0; i < l; i++) {
if (news[i] != L_ESC)
luaL_addchar(b, news[i]);
@@ -693,14 +694,16 @@ 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(ms->L, "invalid use of " LUA_QL("%c")
- " in replacement string", L_ESC);
+ luaL_error(L, "invalid use of " LUA_QL("%c")
+ " in replacement string", L_ESC);
luaL_addchar(b, news[i]);
}
else if (news[i] == '0')
luaL_addlstring(b, s, e - s);
else {
push_onecapture(ms, news[i] - '1', s, e);
+ luaL_tolstring(L, -1, NULL); /* if number, convert it to string */
+ lua_remove(L, -2); /* remove original value */
luaL_addvalue(b); /* add capture to accumulated result */
}
}
@@ -744,9 +747,9 @@ static int str_gsub (lua_State *L) {
const char *src = luaL_checklstring(L, 1, &srcl);
const char *p = luaL_checklstring(L, 2, &lp);
int tr = lua_type(L, 3);
- size_t max_s = luaL_optinteger(L, 4, srcl+1);
+ lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1);
int anchor = (*p == '^');
- size_t n = 0;
+ lua_Integer n = 0;
MatchState ms;
luaL_Buffer b;
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
diff --git a/src/ltable.c b/src/ltable.c
index a7675a57..6ba80e3b 100644
--- a/src/ltable.c
+++ b/src/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.90 2014/06/18 22:59:29 roberto Exp $
+** $Id: ltable.c,v 2.93 2014/07/29 16:22:24 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -52,7 +52,7 @@
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
-#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
+#define hashstr(t,str) hashpow2(t, (str)->hash)
#define hashboolean(t,p) hashpow2(t, p)
#define hashint(t,i) hashpow2(t, i)
@@ -64,7 +64,7 @@
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
-#define hashpointer(t,p) hashmod(t, IntPoint(p))
+#define hashpointer(t,p) hashmod(t, point2int(p))
#define dummynode (&dummynode_)
@@ -116,14 +116,14 @@ static Node *mainposition (const Table *t, const TValue *key) {
case LUA_TNUMFLT:
return hashfloat(t, fltvalue(key));
case LUA_TSHRSTR:
- return hashstr(t, rawtsvalue(key));
+ return hashstr(t, tsvalue(key));
case LUA_TLNGSTR: {
- TString *s = rawtsvalue(key);
- if (s->tsv.extra == 0) { /* no hash? */
- s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash);
- s->tsv.extra = 1; /* now it has its hash */
+ TString *s = tsvalue(key);
+ if (s->extra == 0) { /* no hash? */
+ s->hash = luaS_hash(getstr(s), s->len, s->hash);
+ s->extra = 1; /* now it has its hash */
}
- return hashstr(t, rawtsvalue(key));
+ return hashstr(t, tsvalue(key));
}
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
@@ -309,7 +309,7 @@ static void setnodevector (lua_State *L, Table *t, int size) {
for (i=0; i<size; i++) {
Node *n = gnode(t, i);
gnext(n) = 0;
- setnilvalue(gkey(n));
+ setnilvalue(wgkey(n));
setnilvalue(gval(n));
}
}
@@ -466,7 +466,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
mp = f;
}
}
- setobj2t(L, gkey(mp), key);
+ setkey(L, &mp->i_key, key);
luaC_barrierback(L, t, key);
lua_assert(ttisnil(gval(mp)));
return gval(mp);
@@ -501,9 +501,10 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
*/
const TValue *luaH_getstr (Table *t, TString *key) {
Node *n = hashstr(t, key);
- lua_assert(key->tsv.tt == LUA_TSHRSTR);
+ lua_assert(key->tt == LUA_TSHRSTR);
for (;;) { /* check whether `key' is somewhere in the chain */
- if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key))
+ const TValue *k = gkey(n);
+ if (ttisshrstring(k) && eqshrstr(tsvalue(k), key))
return gval(n); /* that's it */
else {
int nx = gnext(n);
@@ -520,7 +521,7 @@ const TValue *luaH_getstr (Table *t, TString *key) {
*/
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
- case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
+ case LUA_TSHRSTR: return luaH_getstr(t, tsvalue(key));
case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
case LUA_TNIL: return luaO_nilobject;
case LUA_TNUMFLT: {
diff --git a/src/ltable.h b/src/ltable.h
index 12366d4b..45ff45f2 100644
--- a/src/ltable.h
+++ b/src/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 2.18 2013/08/30 16:01:37 roberto Exp $
+** $Id: ltable.h,v 2.19 2014/07/29 16:22:24 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -11,10 +11,15 @@
#define gnode(t,i) (&(t)->node[i])
-#define gkey(n) (&(n)->i_key.tvk)
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->i_key.nk.next)
+
+/* 'const' to avoid wrong writings that can mess up field 'next' */
+#define gkey(n) cast(const TValue*, (&(n)->i_key.tvk))
+
+#define wgkey(n) (&(n)->i_key.nk)
+
#define invalidateTMcache(t) ((t)->flags = 0)
diff --git a/src/ltablib.c b/src/ltablib.c
index ab0d21e7..bc353866 100644
--- a/src/ltablib.c
+++ b/src/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.70 2014/05/16 18:53:25 roberto Exp $
+** $Id: ltablib.c,v 1.73 2014/07/29 16:01:00 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -17,8 +17,56 @@
#include "lualib.h"
-#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n))
+/*
+** Structure with table-access functions
+*/
+typedef struct {
+ int (*geti) (lua_State *L, int idx, lua_Integer n);
+ void (*seti) (lua_State *L, int idx, lua_Integer n);
+} TabA;
+
+
+/*
+** 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 {
+ lua_pushliteral(L, "__index"); /* 'index' metamethod */
+ ta->geti = (lua_rawget(L, -2) == LUA_TNIL) ? lua_rawgeti : geti;
+ lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */
+ ta->seti = (lua_rawget(L, -3) == LUA_TNIL) ? lua_rawseti : seti;
+ lua_pop(L, 3); /* pop metatable plus both metamethods */
+ }
+}
+
+
+#define aux_getn(L,n,ta) (checktab(L, n, ta), luaL_len(L, n))
#if defined(LUA_COMPAT_MAXN)
@@ -40,7 +88,8 @@ static int maxn (lua_State *L) {
static int tinsert (lua_State *L) {
- lua_Integer e = aux_getn(L, 1) + 1; /* first empty element */
+ TabA ta;
+ lua_Integer e = aux_getn(L, 1, &ta) + 1; /* first empty element */
lua_Integer pos; /* where to insert new element */
switch (lua_gettop(L)) {
case 2: { /* called with only 2 arguments */
@@ -52,8 +101,8 @@ static int tinsert (lua_State *L) {
pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */
luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds");
for (i = e; i > pos; i--) { /* move up elements */
- lua_rawgeti(L, 1, i-1);
- lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
+ (*ta.geti)(L, 1, i - 1);
+ (*ta.seti)(L, 1, i); /* t[i] = t[i - 1] */
}
break;
}
@@ -61,29 +110,67 @@ static int tinsert (lua_State *L) {
return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
}
}
- lua_rawseti(L, 1, pos); /* t[pos] = v */
+ (*ta.seti)(L, 1, pos); /* t[pos] = v */
return 0;
}
static int tremove (lua_State *L) {
- lua_Integer size = aux_getn(L, 1);
+ TabA ta;
+ lua_Integer size = aux_getn(L, 1, &ta);
lua_Integer pos = luaL_optinteger(L, 2, size);
if (pos != size) /* validate 'pos' if given */
luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds");
- lua_rawgeti(L, 1, pos); /* result = t[pos] */
+ (*ta.geti)(L, 1, pos); /* result = t[pos] */
for ( ; pos < size; pos++) {
- lua_rawgeti(L, 1, pos+1);
- lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
+ (*ta.geti)(L, 1, pos + 1);
+ (*ta.seti)(L, 1, pos); /* t[pos] = t[pos + 1] */
}
lua_pushnil(L);
- lua_rawseti(L, 1, pos); /* t[pos] = nil */
+ (*ta.seti)(L, 1, pos); /* t[pos] = nil */
+ return 1;
+}
+
+
+static int tcopy (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 */
+ /* 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;
+ n = e - f + 1; /* number of elements to move */
+ if (t > f) {
+ for (i = n - 1; i >= 0; i--) {
+ (*ta.geti)(L, 1, f + i);
+ (*ta.seti)(L, tt, t + i);
+ }
+ }
+ else {
+ for (i = 0; i < n; i++) {
+ (*ta.geti)(L, 1, f + i);
+ (*ta.seti)(L, tt, t + i);
+ }
+ }
+ }
+ lua_pushvalue(L, tt); /* return "to table" */
return 1;
}
-static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) {
- lua_rawgeti(L, 1, i);
+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);
@@ -92,20 +179,21 @@ static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) {
static int tconcat (lua_State *L) {
+ TabA ta;
luaL_Buffer b;
size_t lsep;
lua_Integer i, last;
const char *sep = luaL_optlstring(L, 2, "", &lsep);
- luaL_checktype(L, 1, LUA_TTABLE);
+ checktab(L, 1, &ta);
i = luaL_optinteger(L, 3, 1);
last = luaL_opt(L, luaL_checkinteger, 4, luaL_len(L, 1));
luaL_buffinit(L, &b);
for (; i < last; i++) {
- addfield(L, &b, i);
+ addfield(L, &b, &ta, i);
luaL_addlstring(&b, sep, lsep);
}
if (i == last) /* add last value (if interval was not empty) */
- addfield(L, &b, i);
+ addfield(L, &b, &ta, i);
luaL_pushresult(&b);
return 1;
}
@@ -131,20 +219,21 @@ static int pack (lua_State *L) {
static int unpack (lua_State *L) {
+ TabA ta;
lua_Integer i, e;
lua_Unsigned n;
- luaL_checktype(L, 1, LUA_TTABLE);
+ checktab(L, 1, &ta);
i = luaL_optinteger(L, 2, 1);
e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1));
if (i > e) return 0; /* empty range */
n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */
- if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, ++n))
+ if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n)))
return luaL_error(L, "too many results to unpack");
do { /* must have at least one element */
- lua_rawgeti(L, 1, i); /* push arg[i..e] */
+ (*ta.geti)(L, 1, i); /* push arg[i..e] */
} while (i++ < e);
- return n;
+ return (int)n;
}
/* }====================================================== */
@@ -160,9 +249,9 @@ static int unpack (lua_State *L) {
*/
-static void set2 (lua_State *L, int i, int j) {
- lua_rawseti(L, 1, i);
- lua_rawseti(L, 1, j);
+static void set2 (lua_State *L, TabA *ta, int i, int j) {
+ (*ta->seti)(L, 1, i);
+ (*ta->seti)(L, 1, j);
}
static int sort_comp (lua_State *L, int a, int b) {
@@ -180,45 +269,45 @@ static int sort_comp (lua_State *L, int a, int b) {
return lua_compare(L, a, b, LUA_OPLT);
}
-static void auxsort (lua_State *L, int l, int u) {
+static void auxsort (lua_State *L, TabA *ta, int l, int u) {
while (l < u) { /* for tail recursion */
int i, j;
/* sort elements a[l], a[(l+u)/2] and a[u] */
- lua_rawgeti(L, 1, l);
- lua_rawgeti(L, 1, u);
+ (*ta->geti)(L, 1, l);
+ (*ta->geti)(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
- set2(L, l, u); /* swap a[l] - a[u] */
+ set2(L, ta, l, u); /* swap a[l] - a[u] */
else
lua_pop(L, 2);
if (u-l == 1) break; /* only 2 elements */
i = (l+u)/2;
- lua_rawgeti(L, 1, i);
- lua_rawgeti(L, 1, l);
+ (*ta->geti)(L, 1, i);
+ (*ta->geti)(L, 1, l);
if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
- set2(L, i, l);
+ set2(L, ta, i, l);
else {
lua_pop(L, 1); /* remove a[l] */
- lua_rawgeti(L, 1, u);
+ (*ta->geti)(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
- set2(L, i, u);
+ set2(L, ta, i, u);
else
lua_pop(L, 2);
}
if (u-l == 2) break; /* only 3 elements */
- lua_rawgeti(L, 1, i); /* Pivot */
+ (*ta->geti)(L, 1, i); /* Pivot */
lua_pushvalue(L, -1);
- lua_rawgeti(L, 1, u-1);
- set2(L, i, u-1);
+ (*ta->geti)(L, 1, u-1);
+ set2(L, ta, i, u-1);
/* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
i = l; j = u-1;
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
/* repeat ++i until a[i] >= P */
- while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
+ while ((*ta->geti)(L, 1, ++i), sort_comp(L, -1, -2)) {
if (i>=u) luaL_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[i] */
}
/* repeat --j until a[j] <= P */
- while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
+ while ((*ta->geti)(L, 1, --j), sort_comp(L, -3, -1)) {
if (j<=l) luaL_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[j] */
}
@@ -226,11 +315,11 @@ static void auxsort (lua_State *L, int l, int u) {
lua_pop(L, 3); /* pop pivot, a[i], a[j] */
break;
}
- set2(L, i, j);
+ set2(L, ta, i, j);
}
- lua_rawgeti(L, 1, u-1);
- lua_rawgeti(L, 1, i);
- set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
+ (*ta->geti)(L, 1, u-1);
+ (*ta->geti)(L, 1, i);
+ set2(L, ta, u-1, i); /* swap pivot (a[u-1]) with a[i] */
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
/* adjust so that smaller half is in [j..i] and larger one in [l..u] */
if (i-l < u-i) {
@@ -239,17 +328,18 @@ static void auxsort (lua_State *L, int l, int u) {
else {
j=i+1; i=u; u=j-2;
}
- auxsort(L, j, i); /* call recursively the smaller one */
+ auxsort(L, ta, j, i); /* call recursively the smaller one */
} /* repeat the routine for the larger one */
}
static int sort (lua_State *L) {
- int n = aux_getn(L, 1);
- luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
+ TabA ta;
+ int n = (int)aux_getn(L, 1, &ta);
+ luaL_checkstack(L, 50, ""); /* assume array is smaller than 2^50 */
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION);
- lua_settop(L, 2); /* make sure there is two arguments */
- auxsort(L, 1, n);
+ lua_settop(L, 2); /* make sure there are two arguments */
+ auxsort(L, &ta, 1, n);
return 0;
}
@@ -265,6 +355,7 @@ static const luaL_Reg tab_funcs[] = {
{"pack", pack},
{"unpack", unpack},
{"remove", tremove},
+ {"copy", tcopy},
{"sort", sort},
{NULL, NULL}
};
diff --git a/src/ltm.c b/src/ltm.c
index 996a73e8..825f82d4 100644
--- a/src/ltm.c
+++ b/src/ltm.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.c,v 2.27 2014/06/10 18:53:18 roberto Exp $
+** $Id: ltm.c,v 2.29 2014/07/18 13:36:14 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
diff --git a/src/lua.c b/src/lua.c
index 0657b220..f46f9fb3 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -1,5 +1,5 @@
/*
-** $Id: lua.c,v 1.211 2014/06/05 20:42:06 roberto Exp $
+** $Id: lua.c,v 1.213 2014/06/30 19:48:08 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -115,7 +115,7 @@ static void lstop (lua_State *L, lua_Debug *ar) {
/*
** Function to be called at a C signal. Because a C signal cannot
-** just change a Lua state (as there is no proper syncronization),
+** just change a Lua state (as there is no proper synchronization),
** this function only sets a hook that, when called, will stop the
** interpreter.
*/
@@ -284,7 +284,7 @@ static const char *get_prompt (lua_State *L, int firstline) {
/*
** Check whether 'status' signals a syntax error and the error
** message at the top of the stack ends with the above mark for
-** incoplete statements.
+** incomplete statements.
*/
static int incomplete (lua_State *L, int status) {
if (status == LUA_ERRSYNTAX) {
@@ -417,25 +417,31 @@ static void doREPL (lua_State *L) {
/*
-** Push on the stack 'n' strings from 'argv'
+** Push on the stack the contents of table 'arg' from 1 to #arg
*/
-static void pushargs (lua_State *L, char **argv, int n) {
- int i;
+static int pushargs (lua_State *L) {
+ int i, n;
+ lua_getglobal(L, "arg");
+ if (!lua_istable(L, -1))
+ luaL_error(L, "'arg' is not a table");
+ n = (int)luaL_len(L, -1);
luaL_checkstack(L, n + 3, "too many arguments to script");
- for (i = 1; i < n; i++) /* skip 0 (the script name) */
- lua_pushstring(L, argv[i]);
+ for (i = 1; i <= n; i++)
+ lua_rawgeti(L, -i, i);
+ lua_remove(L, -i); /* remove table from the stack */
+ return n;
}
-static int handle_script (lua_State *L, char **argv, int n) {
+static int handle_script (lua_State *L, char **argv) {
int status;
const char *fname = argv[0];
if (strcmp(fname, "-") == 0 && strcmp(argv[-1], "--") != 0)
fname = NULL; /* stdin */
status = luaL_loadfile(L, fname);
if (status == LUA_OK) {
- pushargs(L, argv, n); /* push arguments to script */
- status = docall(L, n - 1, LUA_MULTRET);
+ int n = pushargs(L); /* push arguments to script */
+ status = docall(L, n, LUA_MULTRET);
}
return report(L, status);
}
@@ -570,7 +576,7 @@ static int pmain (lua_State *L) {
if (!runargs(L, argv, script)) /* execute arguments -e and -l */
return 0; /* something failed */
if (script < argc && /* execute main script (if there is one) */
- handle_script(L, argv + script, argc - script) != LUA_OK)
+ handle_script(L, argv + script) != LUA_OK)
return 0;
if (args & has_i) /* -i option? */
doREPL(L); /* do read-eval-print loop */
diff --git a/src/lua.h b/src/lua.h
index 0b76dbd1..81aaaebf 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.307 2014/06/10 17:41:38 roberto Exp $
+** $Id: lua.h,v 1.312 2014/07/31 13:44:30 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 (work3)"
+#define LUA_VERSION_RELEASE "0 (alpha)"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
@@ -53,30 +53,6 @@
typedef struct lua_State lua_State;
-/*
-** Type for C functions registered with Lua
-*/
-typedef int (*lua_CFunction) (lua_State *L);
-
-/*
-** Type for continuation functions
-*/
-typedef int (*lua_KFunction) (lua_State *L, int status, int ctx);
-
-
-/*
-** functions that read/write blocks when loading/dumping Lua chunks
-*/
-typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
-
-typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
-
-
-/*
-** prototype for memory-allocation functions
-*/
-typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
-
/*
** basic types
@@ -117,6 +93,34 @@ typedef LUA_INTEGER lua_Integer;
/* unsigned integer type */
typedef LUA_UNSIGNED lua_Unsigned;
+/* type for continuation-function contexts */
+typedef LUA_CTXT lua_Ctx;
+
+
+/*
+** Type for C functions registered with Lua
+*/
+typedef int (*lua_CFunction) (lua_State *L);
+
+/*
+** Type for continuation functions
+*/
+typedef int (*lua_KFunction) (lua_State *L, int status, lua_Ctx ctx);
+
+
+/*
+** Type for functions that read/write blocks when loading/dumping Lua chunks
+*/
+typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
+
+typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
+
+
+/*
+** Type for memory-allocation functions
+*/
+typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
+
/*
@@ -154,7 +158,6 @@ LUA_API int (lua_gettop) (lua_State *L);
LUA_API void (lua_settop) (lua_State *L, int idx);
LUA_API void (lua_pushvalue) (lua_State *L, int idx);
LUA_API void (lua_rotate) (lua_State *L, int idx, int n);
-LUA_API void (lua_replace) (lua_State *L, int idx);
LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx);
LUA_API int (lua_checkstack) (lua_State *L, int sz);
@@ -175,7 +178,6 @@ LUA_API const char *(lua_typename) (lua_State *L, int tp);
LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
-LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum);
LUA_API int (lua_toboolean) (lua_State *L, int idx);
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
LUA_API size_t (lua_rawlen) (lua_State *L, int idx);
@@ -220,7 +222,6 @@ LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
LUA_API void (lua_pushnil) (lua_State *L);
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
-LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n);
LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l);
LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
@@ -264,12 +265,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, int ctx,
+LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, lua_Ctx 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,
- int ctx, lua_KFunction k);
+ lua_Ctx 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,
@@ -282,7 +283,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, int ctx,
+LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_Ctx 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);
@@ -326,14 +327,15 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
/*
-** ===============================================================
+** {==============================================================
** some useful macros
** ===============================================================
*/
+#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
+
#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL)
#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL)
-#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL)
#define lua_pop(L,n) lua_settop(L, -(n)-1)
@@ -365,6 +367,24 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
+#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
+
+/* }============================================================== */
+
+
+/*
+** {==============================================================
+** compatibility macros for unsigned conversions
+** ===============================================================
+*/
+#if defined(LUA_COMPAT_APIUNSIGNED)
+
+#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
+#define lua_tounsignedx(L,i,is) ((lua_Integer)lua_tointegerx(L,i,is))
+#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL)
+
+#endif
+/* }============================================================== */
/*
** {======================================================================
diff --git a/src/luac.c b/src/luac.c
index 0764b369..68d545f1 100644
--- a/src/luac.c
+++ b/src/luac.c
@@ -203,7 +203,7 @@ int main(int argc, char* argv[])
}
/*
-** $Id: print.c,v 1.73 2014/06/12 02:41:25 lhf Exp $
+** $Id: print.c,v 1.74 2014/07/21 01:41:45 lhf Exp $
** print bytecodes
** See Copyright Notice in lua.h
*/
@@ -223,7 +223,7 @@ int main(int argc, char* argv[])
static void PrintString(const TString* ts)
{
const char* s=getstr(ts);
- size_t i,n=ts->tsv.len;
+ size_t i,n=ts->len;
printf("%c",'"');
for (i=0; i<n; i++)
{
@@ -266,7 +266,7 @@ static void PrintConstant(const Proto* f, int i)
printf(LUA_INTEGER_FMT,ivalue(o));
break;
case LUA_TSHRSTR: case LUA_TLNGSTR:
- PrintString(rawtsvalue(o));
+ PrintString(tsvalue(o));
break;
default: /* cannot happen */
printf("? type=%d",ttype(o));
diff --git a/src/luaconf.h b/src/luaconf.h
index 2bceab1c..d3db9267 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.207 2014/06/10 19:21:20 roberto Exp $
+** $Id: luaconf.h,v 1.212 2014/07/24 19:33:29 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -211,6 +211,14 @@
/*
+@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
+** a Lua state with very fast access.
+** CHANGE it if you need a different size.
+*/
+#define LUA_EXTRASPACE (sizeof(void *))
+
+
+/*
@@ LUA_QL describes how error messages quote program elements.
** CHANGE it if you want a different appearance.
*/
@@ -254,6 +262,22 @@
#define LUAI_MAXSHORTLEN 40
+/*
+@@ 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.
+*/
+#if defined (LUA_USE_C99)
+#include <stdint.h>
+#if defined (INTPTR_MAX) /* even in C99 this type is optional */
+#define LUA_CTXT intptr_t
+#endif
+#endif
+
+#if !defined(LUA_CTXT)
+/* default definition (the nearest thing to 'intptr_t' in C89) */
+#define LUA_CTXT ptrdiff_t
+#endif
+
/*
** {==================================================================
@@ -280,6 +304,17 @@
*/
#define LUA_COMPAT_BITLIB
+/*
+@@ LUA_COMPAT_IPAIRS controls the effectivness 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.)
+*/
+#define LUA_COMPAT_APIUNSIGNED
+
/*
@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
@@ -569,7 +604,6 @@
@@ LUA_INTEGER_FMT is the format for writing integers.
@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
-@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED.
@@ lua_integer2str converts an integer to a string.
*/
@@ -595,7 +629,6 @@
#define LUA_INTEGER int
#define LUA_INTEGER_FRMLEN ""
-#define LUA_MAXUNSIGNED UINT_MAX
#define LUA_MAXINTEGER INT_MAX
#define LUA_MININTEGER INT_MIN
@@ -604,7 +637,6 @@
#define LUA_INTEGER long
#define LUA_INTEGER_FRMLEN "l"
-#define LUA_MAXUNSIGNED ULONG_MAX
#define LUA_MAXINTEGER LONG_MAX
#define LUA_MININTEGER LONG_MIN
@@ -615,7 +647,6 @@
#define LUA_INTEGER __int64
#define LUA_INTEGER_FRMLEN "I64"
-#define LUA_MAXUNSIGNED _UI64_MAX
#define LUA_MAXINTEGER _I64_MAX
#define LUA_MININTEGER _I64_MIN
@@ -624,7 +655,6 @@
#define LUA_INTEGER long long
#define LUA_INTEGER_FRMLEN "ll"
-#define LUA_MAXUNSIGNED ULLONG_MAX
#define LUA_MAXINTEGER LLONG_MAX
#define LUA_MININTEGER LLONG_MIN
@@ -639,7 +669,6 @@
#define LUA_INTEGER short int
#define LUA_INTEGER_FRMLEN ""
-#define LUA_MAXUNSIGNED ((LUA_UNSIGNED)USHRT_MAX)
#define LUA_MAXINTEGER SHRT_MAX
#define LUA_MININTEGER SHRT_MIN
diff --git a/src/lutf8lib.c b/src/lutf8lib.c
index 747c018d..1e848def 100644
--- a/src/lutf8lib.c
+++ b/src/lutf8lib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lutf8lib.c,v 1.9 2014/05/14 18:33:37 roberto Exp $
+** $Id: lutf8lib.c,v 1.10 2014/07/16 13:56:14 roberto Exp $
** Standard library for UTF-8 manipulation
** See Copyright Notice in lua.h
*/
@@ -238,6 +238,8 @@ static struct luaL_Reg funcs[] = {
{"char", utfchar},
{"len", utflen},
{"codes", iter_codes},
+ /* placeholders */
+ {"charpatt", NULL},
{NULL, NULL}
};
diff --git a/src/lvm.c b/src/lvm.c
index 125be1ef..51f14292 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.216 2014/06/19 18:27:20 roberto Exp $
+** $Id: lvm.c,v 2.222 2014/07/30 14:42:44 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -33,10 +33,6 @@
#define MAXTAGLOOP 2000
-/* maximum length of the conversion of a number to a string */
-#define MAXNUMBER2STR 50
-
-
/*
** Similar to 'tonumber', but does not attempt to convert strings and
** ensure correct precision (no extra bits). Used in comparisons.
@@ -70,7 +66,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
*n = fltvalue(obj);
return 1;
}
- else if (ttisstring(obj) && /* string convertible to number? */
+ else if (cvt2num(obj) && /* string convertible to number? */
luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
obj = &v;
goto again; /* convert result from 'luaO_str2num' to a float */
@@ -80,21 +76,29 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
/*
-** try to convert a value to an integer, rounding up if 'up' is true
+** try to convert a value to an integer, rounding according to 'mode':
+** mode == 0: accepts only integral values
+** mode < 0: takes the floor of the number
+** mode > 0: takes the ceil of the number
*/
-static int tointeger_aux (const TValue *obj, lua_Integer *p, int up) {
+static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
TValue v;
again:
if (ttisfloat(obj)) {
lua_Number n = fltvalue(obj);
- n = (up ? -l_floor(-n) : l_floor(n));
- return lua_numtointeger(n, p);
+ lua_Number f = l_floor(n);
+ if (n != f) { /* not an integral value? */
+ if (mode == 0) return 0; /* fails if mode demands integral value */
+ else if (mode > 0) /* needs ceil? */
+ f += 1; /* convert floor to ceil (remember: n != f) */
+ }
+ return lua_numtointeger(f, p);
}
else if (ttisinteger(obj)) {
*p = ivalue(obj);
return 1;
}
- else if (ttisstring(obj) &&
+ else if (cvt2num(obj) &&
luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
obj = &v;
goto again; /* convert result from 'luaO_str2num' to an integer */
@@ -104,7 +108,7 @@ static int tointeger_aux (const TValue *obj, lua_Integer *p, int up) {
/*
-** try to convert a non-integer value to an integer, rounding down
+** try to convert a value to an integer
*/
int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
return tointeger_aux(obj, p, 0);
@@ -112,32 +116,6 @@ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
/*
-** Convert a number object to a string
-*/
-int luaV_tostring (lua_State *L, StkId obj) {
- if (!ttisnumber(obj))
- return 0;
- else {
- char buff[MAXNUMBER2STR];
- size_t len;
- if (ttisinteger(obj))
- len = lua_integer2str(buff, ivalue(obj));
- else {
- len = lua_number2str(buff, fltvalue(obj));
-#if !defined(LUA_COMPAT_FLOATSTRING)
- if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
- buff[len++] = '.';
- buff[len++] = '0'; /* adds '.0' to result */
- }
-#endif
- }
- setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
- return 1;
- }
-}
-
-
-/*
** Try to convert a 'for' limit to an integer, preserving the
** semantics of the loop.
** (The following explanation assumes a non-negative step; it is valid
@@ -155,7 +133,7 @@ int luaV_tostring (lua_State *L, StkId obj) {
static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
int *stopnow) {
*stopnow = 0; /* usually, let loops run */
- if (!tointeger_aux(obj, p, (step < 0))) { /* does not fit in integer? */
+ if (!tointeger_aux(obj, p, (step < 0 ? 1 : -1))) { /* not fit in integer? */
lua_Number n; /* try to convert to float */
if (!tonumber(obj, &n)) /* cannot convert to float? */
return 0; /* not a number */
@@ -239,7 +217,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
luaT_callTM(L, tm, t, key, val, 0);
return;
}
- t = tm; /* else repeat assginment over 'tm' */
+ t = tm; /* else repeat assignment over 'tm' */
}
luaG_runerror(L, "settable chain too long; possible loop");
}
@@ -254,9 +232,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
*/
static int l_strcmp (const TString *ls, const TString *rs) {
const char *l = getstr(ls);
- size_t ll = ls->tsv.len;
+ size_t ll = ls->len;
const char *r = getstr(rs);
- size_t lr = rs->tsv.len;
+ size_t lr = rs->len;
for (;;) { /* for each segment */
int temp = strcoll(l, r);
if (temp != 0) /* not equal? */
@@ -286,7 +264,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
return luai_numlt(nl, nr);
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
+ return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */
luaG_ordererror(L, l, r); /* error */
return res;
@@ -304,7 +282,7 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
return luai_numle(nl, nr);
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
+ return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
return res;
else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */
@@ -337,8 +315,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
case LUA_TLCF: return fvalue(t1) == fvalue(t2);
- case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
- case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
+ case LUA_TSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2));
+ case LUA_TLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2));
case LUA_TUSERDATA: {
if (uvalue(t1) == uvalue(t2)) return 1;
else if (L == NULL) return 0;
@@ -366,7 +344,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
/* macro used by 'luaV_concat' to ensure that element at 'o' is a string */
-#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o)))
+#define tostring(L,o) \
+ (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
/*
** Main operation for concatenation: concat 'total' values in the stack,
@@ -377,7 +356,7 @@ void luaV_concat (lua_State *L, int total) {
do {
StkId top = L->top;
int n = 2; /* number of elements handled in this pass (at least 2) */
- if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1))
+ if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
cast_void(tostring(L, top - 2)); /* result is first operand */
@@ -541,7 +520,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
ncl->upvals[i]->refcount++;
/* new closure is white, so we do not need a barrier here */
}
- if (!isblack(obj2gco(p))) /* cache will not break GC invariant? */
+ if (!isblack(p)) /* cache will not break GC invariant? */
p->cache = ncl; /* save it on cache for reuse */
}
diff --git a/src/lvm.h b/src/lvm.h
index 36e78e68..0f4667af 100644
--- a/src/lvm.h
+++ b/src/lvm.h
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.h,v 2.31 2014/05/26 17:10:22 roberto Exp $
+** $Id: lvm.h,v 2.33 2014/07/30 14:42:44 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -13,6 +13,20 @@
#include "ltm.h"
+#if !defined(LUA_NOCVTN2S)
+#define cvt2str(o) ttisnumber(o)
+#else
+#define cvt2str(o) 0 /* no convertion 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 */
+#endif
+
+
#define tonumber(o,n) \
(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
@@ -29,7 +43,6 @@ LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
LUAI_FUNC int luaV_tointeger_ (const TValue *obj, lua_Integer *p);
-LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,