-This is Lua 5.2.1, released on 08 Jun 2012.
+This is Lua 5.2.2, released on 21 Mar 2013.
For installation instructions, license details, and
further information about Lua, see doc/readme.html.
<P>
The reference manual is the official definition of the Lua language.
For a complete introduction to Lua programming, see the book
-<A HREF="http://www.lua.org/docs.html#books">Programming in Lua</A>.
+<A HREF="http://www.lua.org/pil/">Programming in Lua</A>.
<P>
<A HREF="manual.html">start</A>
<A HREF="#index">index</A>
<HR>
<SMALL>
-Copyright © 2011–2012 Lua.org, PUC-Rio.
+Copyright © 2011–2013 Lua.org, PUC-Rio.
Freely available under the terms of the
<A HREF="http://www.lua.org/license.html">Lua license</A>.
</SMALL>
<A HREF="manual.html#pdf-error">error</A><BR>
<A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR>
<A HREF="manual.html#pdf-ipairs">ipairs</A><BR>
-<A HREF="manual.html#pdf-loadfile">loadfile</A><BR>
<A HREF="manual.html#pdf-load">load</A><BR>
+<A HREF="manual.html#pdf-loadfile">loadfile</A><BR>
<A HREF="manual.html#pdf-next">next</A><BR>
<A HREF="manual.html#pdf-pairs">pairs</A><BR>
<A HREF="manual.html#pdf-pcall">pcall</A><BR>
<A HREF="manual.html#lua_pushcclosure">lua_pushcclosure</A><BR>
<A HREF="manual.html#lua_pushcfunction">lua_pushcfunction</A><BR>
<A HREF="manual.html#lua_pushfstring">lua_pushfstring</A><BR>
+<A HREF="manual.html#lua_pushglobaltable">lua_pushglobaltable</A><BR>
<A HREF="manual.html#lua_pushinteger">lua_pushinteger</A><BR>
<A HREF="manual.html#lua_pushlightuserdata">lua_pushlightuserdata</A><BR>
<A HREF="manual.html#lua_pushliteral">lua_pushliteral</A><BR>
<A HREF="manual.html#lua_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>
<A HREF="manual.html#lua_rawget">lua_rawget</A><BR>
<A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR>
+<A HREF="manual.html#lua_rawgetp">lua_rawgetp</A><BR>
<A HREF="manual.html#lua_rawlen">lua_rawlen</A><BR>
<A HREF="manual.html#lua_rawset">lua_rawset</A><BR>
<A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR>
-<A HREF="manual.html#lua_rawgetp">lua_rawgetp</A><BR>
<A HREF="manual.html#lua_rawsetp">lua_rawsetp</A><BR>
<A HREF="manual.html#lua_register">lua_register</A><BR>
<A HREF="manual.html#lua_remove">lua_remove</A><BR>
<A HREF="manual.html#luaL_buffinitsize">luaL_buffinitsize</A><BR>
<A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR>
<A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR>
-<A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR>
<A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR>
+<A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR>
<A HREF="manual.html#luaL_checklong">luaL_checklong</A><BR>
<A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR>
<A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR>
<A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR>
<A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR>
<A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR>
-<A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR>
<A HREF="manual.html#luaL_optint">luaL_optint</A><BR>
+<A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR>
<A HREF="manual.html#luaL_optlong">luaL_optlong</A><BR>
<A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR>
<A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR>
<HR>
<SMALL CLASS="footer">
Last update:
-Sat May 26 08:52:25 BRT 2012
+Tue Mar 12 11:22:18 BRT 2013
</SMALL>
<!--
-Last change: revised for Lua 5.2.1
+Last change: revised for Lua 5.2.2
-->
</BODY>
h2 {
padding-top: 0.4em ;
padding-bottom: 0.4em ;
- padding-left: 30px ;
- padding-right: 30px ;
- margin-left: -30px ;
+ padding-left: 1em ;
+ padding-right: 1em ;
background-color: #E0E0FF ;
+ border-radius: 8px ;
}
h3 {
p+h1, ul+h1 {
padding-top: 0.4em ;
padding-bottom: 0.4em ;
- padding-left: 30px ;
- margin-left: -30px ;
+ padding-left: 24px ;
+ margin-left: -24px ;
background-color: #E0E0FF ;
+ border-radius: 8px ;
}
+
by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
<p>
<small>
-Copyright © 2011–2012 Lua.org, PUC-Rio.
+Copyright © 2011–2013 Lua.org, PUC-Rio.
Freely available under the terms of the
<a href="http://www.lua.org/license.html">Lua license</a>.
</small>
<!-- ====================================================================== -->
<p>
-<!-- $Id: manual.of,v 1.99 2012/06/08 15:30:20 roberto Exp $ -->
+<!-- $Id: manual.of,v 1.103 2013/03/14 18:51:56 roberto Exp $ -->
<pre>
rawget(getmetatable(obj) or {}, event)
</pre><p>
-
This means that the access to a metamethod does not invoke other metamethods,
and access to objects with no metatables does not fail
(it simply results in <b>nil</b>).
<p>
When you close a state (see <a href="#lua_close"><code>lua_close</code></a>),
-Lua calls the finalizers of all objects marked for collection,
+Lua calls the finalizers of all objects marked for finalization,
following the reverse order that they were marked.
If any finalizer marks new objects for collection during that phase,
these new objects will not be finalized.
<p>
-When parsing a from a string source,
-any byte in a literal string not
+Any byte in a literal string not
explicitly affected by the previous rules represents itself.
However, Lua opens files for parsing in text mode,
and the system file functions may have problems with
</pre>
<p>
+Function calls and assignments
+can start with an open parenthesis.
+This possibility leads to an ambiguity in Lua's grammar.
+Consider the following fragment:
+
+<pre>
+ a = b + c
+ (print or io.write)('done')
+</pre><p>
+The grammar could see it in two ways:
+
+<pre>
+ a = b + c(print or io.write)('done')
+
+ a = b + c; (print or io.write)('done')
+</pre><p>
+The current parser always sees such constructions
+in the first way,
+interpreting the open parenthesis
+as the start of the arguments to a call.
+To avoid this ambiguity,
+it is a good practice to always precede with a semicolon
+statements that start with a parenthesis:
+
+<pre>
+ ;(print or io.write)('done')
+</pre>
+
+<p>
A block can be explicitly delimited to produce a single statement:
<pre>
<h3>3.3.2 – <a name="3.3.2">Chunks</a></h3>
<p>
-The unit of execution of Lua is called a <em>chunk</em>.
+The unit of compilation of Lua is called a <em>chunk</em>.
Syntactically,
a chunk is simply a block:
(unless the expression is enclosed in parentheses).
In all other contexts,
Lua adjusts the result list to one element,
-discarding all values except the first one.
+either discarding all values except the first one
+or adding a single <b>nil</b> if there are no values.
<p>
<p>
A <em>valid index</em> is an index that refers to a
-valid position within the stack, that is,
-it lies between 1 and the stack top
+real position within the stack, that is,
+its position lies between 1 and the stack top
(<code>1 ≤ abs(index) ≤ top</code>).
-Usually, functions that need a specific stack position
-(e.g., <a href="#lua_remove"><code>lua_remove</code></a>) require valid indices.
+Usually, functions that can modify the value at an index
+require valid indices.
+
+
+<p>
+Unless otherwise noted,
+any function that accepts valid indices also accepts <em>pseudo-indices</em>,
+which represent some Lua values that are accessible to C code
+but which are not in the stack.
+Pseudo-indices are used to access the registry
+and the upvalues of a C function (see <a href="#4.4">§4.4</a>).
<p>
Functions that do not need a specific stack position,
but only a value in the stack (e.g., query functions),
can be called with acceptable indices.
-An <em>acceptable index</em> refers to a position within
-the space allocated for the stack,
+An <em>acceptable index</em> can be any valid index,
+including the pseudo-indices,
+but it also can be any positive index after the stack top
+within the space allocated for the stack,
that is, indices up to the stack size.
-More formally, we define an acceptable index
-as follows:
-
-<pre>
- (index < 0 && abs(index) <= top) ||
- (index > 0 && index <= stack size)
-</pre><p>
(Note that 0 is never an acceptable index.)
-When a function is called,
-its stack size is <code>top + LUA_MINSTACK</code>.
-You can change its stack size through function <a href="#lua_checkstack"><code>lua_checkstack</code></a>.
+Except when noted otherwise,
+functions in the API work with acceptable indices.
<p>
<p>
For functions that can be called with acceptable indices,
any non-valid index is treated as if it
-contains a value of a virtual type <a name="pdf-LUA_TNONE"><code>LUA_TNONE</code></a>.
-
-
-<p>
-Unless otherwise noted,
-any function that accepts valid indices also accepts <em>pseudo-indices</em>,
-which represent some Lua values that are accessible to C code
-but which are not in the stack.
-Pseudo-indices are used to access the registry
-and the upvalues of a C function (see <a href="#4.4">§4.4</a>).
+contains a value of a virtual type <a name="pdf-LUA_TNONE"><code>LUA_TNONE</code></a>,
+which behaves like a nil value.
Whenever a C function is called,
its upvalues are located at specific pseudo-indices.
These pseudo-indices are produced by the macro
-<a name="lua_upvalueindex"><code>lua_upvalueindex</code></a>.
+<a href="#lua_upvalueindex"><code>lua_upvalueindex</code></a>.
The first value associated with a function is at position
<code>lua_upvalueindex(1)</code>, and so on.
Any access to <code>lua_upvalueindex(<em>n</em>)</code>,
where <em>n</em> is greater than the number of upvalues of the
current function (but not greater than 256),
-produces an acceptable (but invalid) index.
+produces an acceptable but invalid index.
a predefined table that can be used by any C code to
store whatever Lua values it needs to store.
The registry table is always located at pseudo-index
-<a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>.
+<a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>,
+which is a valid index.
Any C library can store data into this table,
but it should take care to choose keys
that are different from those used
<p>
Internally, Lua uses the C <code>longjmp</code> facility to handle errors.
-(You can also choose to use exceptions if you use C++;
-see file <code>luaconf.h</code>.)
+(You can also choose to use exceptions if you compile Lua as C++;
+search for <code>LUAI_THROW</code> in the source code.)
When Lua faces any error
(such as a memory allocation error, type errors, syntax errors,
and runtime errors)
<p>
Compares two Lua values.
-Returns 1 if the value at acceptable index <code>index1</code> satisfies <code>op</code>
-when compared with the value at acceptable index <code>index2</code>,
+Returns 1 if the value at index <code>index1</code> satisfies <code>op</code>
+when compared with the value at index <code>index2</code>,
following the semantics of the corresponding Lua operator
(that is, it may call metamethods).
Otherwise returns 0.
<pre>void lua_copy (lua_State *L, int fromidx, int toidx);</pre>
<p>
-Moves the element at the valid index <code>fromidx</code>
+Moves 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).
<p>
Pushes onto the stack the value <code>t[k]</code>,
-where <code>t</code> is the value at the given valid index.
+where <code>t</code> is the value at the given index.
As in Lua, this function may trigger a metamethod
for the "index" event (see <a href="#2.4">§2.4</a>).
<pre>int lua_getmetatable (lua_State *L, int index);</pre>
<p>
-Pushes onto the stack the metatable of the value at the given
-acceptable index.
+Pushes onto the stack the metatable of the value at the given index.
If the value does not have a metatable,
the function returns 0 and pushes nothing on the stack.
<p>
Pushes onto the stack the value <code>t[k]</code>,
-where <code>t</code> is the value at the given valid index
+where <code>t</code> is the value at the given index
and <code>k</code> is the value at the top of the stack.
<p>
Moves the top element into the given valid index,
shifting up the elements above this index to open space.
-Cannot be called with a pseudo-index,
+This function cannot be called with a pseudo-index,
because a pseudo-index is not an actual stack position.
<pre>int lua_isboolean (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is a boolean,
+Returns 1 if the value at the given index is a boolean,
and 0 otherwise.
<pre>int lua_iscfunction (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is a C function,
+Returns 1 if the value at the given index is a C function,
and 0 otherwise.
<pre>int lua_isfunction (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is a function
+Returns 1 if the value at the given index is a function
(either C or Lua), and 0 otherwise.
<pre>int lua_islightuserdata (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is a light userdata,
+Returns 1 if the value at the given index is a light userdata,
and 0 otherwise.
<pre>int lua_isnil (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is <b>nil</b>,
+Returns 1 if the value at the given index is <b>nil</b>,
and 0 otherwise.
<pre>int lua_isnone (lua_State *L, int index);</pre>
<p>
-Returns 1 if the given acceptable index is not valid
-(that is, it refers to an element outside the current stack),
+Returns 1 if the given index is not valid,
and 0 otherwise.
<pre>int lua_isnoneornil (lua_State *L, int index);</pre>
<p>
-Returns 1 if the given acceptable index is not valid
-(that is, it refers to an element outside the current stack)
+Returns 1 if the given index is not valid
or if the value at this index is <b>nil</b>,
and 0 otherwise.
<pre>int lua_isnumber (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is a number
+Returns 1 if the value at the given index is a number
or a string convertible to a number,
and 0 otherwise.
<pre>int lua_isstring (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is a string
+Returns 1 if the value at the given index is a string
or a number (which is always convertible to a string),
and 0 otherwise.
<pre>int lua_istable (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is a table,
+Returns 1 if the value at the given index is a table,
and 0 otherwise.
<pre>int lua_isthread (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is a thread,
+Returns 1 if the value at the given index is a thread,
and 0 otherwise.
<pre>int lua_isuserdata (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index is a userdata
+Returns 1 if the value at the given index is a userdata
(either full or light), and 0 otherwise.
<pre>void lua_len (lua_State *L, int index);</pre>
<p>
-Returns the "length" of the value at the given acceptable index;
+Returns the "length" of the value at the given index;
it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">§3.4.6</a>).
The result is pushed on the stack.
<p>
+<code>lua_load</code> uses the stack internally,
+so the reader function should always leave the stack
+unmodified when returning.
+
+
+<p>
If the resulting function has one upvalue,
this upvalue is set to the value of the global environment
stored at index <code>LUA_RIDX_GLOBALS</code> in the registry (see <a href="#4.5">§4.5</a>).
<p>
Pushes onto the stack a formatted string
and returns a pointer to this string.
-It is similar to the C function <code>sprintf</code>,
+It is similar to the ANSI C function <code>sprintf</code>,
but has some important differences:
<ul>
+<hr><h3><a name="lua_pushglobaltable"><code>lua_pushglobaltable</code></a></h3><p>
+<span class="apii">[-0, +1, –]</span>
+<pre>void lua_pushglobaltable (lua_State *L);</pre>
+
+<p>
+Pushes the global environment onto the stack.
+
+
+
+
+
<hr><h3><a name="lua_pushinteger"><code>lua_pushinteger</code></a></h3><p>
<span class="apii">[-0, +1, –]</span>
<pre>void lua_pushinteger (lua_State *L, lua_Integer n);</pre>
+<hr><h3><a name="lua_pushunsigned"><code>lua_pushunsigned</code></a></h3><p>
+<span class="apii">[-0, +1, –]</span>
+<pre>void lua_pushunsigned (lua_State *L, lua_Unsigned n);</pre>
+
+<p>
+Pushes a number 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, –]</span>
<pre>void lua_pushvalue (lua_State *L, int index);</pre>
<p>
-Pushes a copy of the element at the given valid index
+Pushes a copy of the element at the given index
onto the stack.
<pre>int lua_rawequal (lua_State *L, int index1, int index2);</pre>
<p>
-Returns 1 if the two values in acceptable indices <code>index1</code> and
+Returns 1 if the two values in indices <code>index1</code> and
<code>index2</code> are primitively equal
(that is, without calling metamethods).
Otherwise returns 0.
<p>
Pushes onto the stack the value <code>t[n]</code>,
-where <code>t</code> is the table at the given valid index.
+where <code>t</code> is the table at the given index.
The access is raw;
that is, it does not invoke metamethods.
<p>
Pushes onto the stack the value <code>t[k]</code>,
-where <code>t</code> is the table at the given valid index and
+where <code>t</code> is the table at the given index and
<code>k</code> is the pointer <code>p</code> represented as a light userdata.
The access is raw;
that is, it does not invoke metamethods.
<pre>size_t lua_rawlen (lua_State *L, int index);</pre>
<p>
-Returns the raw "length" of the value at the given acceptable index:
+Returns the raw "length" of the value at the given index:
for strings, this is the string length;
for tables, this is the result of the length operator ('<code>#</code>')
with no metamethods;
<p>
Does the equivalent of <code>t[n] = v</code>,
-where <code>t</code> is the table at the given valid index
+where <code>t</code> is the table at the given index
and <code>v</code> is the value at the top of the stack.
<p>
Does the equivalent of <code>t[k] = v</code>,
-where <code>t</code> is the table at the given valid index,
+where <code>t</code> is the table at the given index,
<code>k</code> is the pointer <code>p</code> represented as a light userdata,
and <code>v</code> is the value at the top of the stack.
<p>
Removes the element at the given valid index,
shifting down the elements above this index to fill the gap.
-Cannot be called with a pseudo-index,
+This function cannot be called with a pseudo-index,
because a pseudo-index is not an actual stack position.
<pre>void lua_replace (lua_State *L, int index);</pre>
<p>
-Moves the top element into the given position
+Moves the top element into the given valid index
without shifting any element
-(therefore replacing the value at the given position),
+(therefore replacing the value at the given index),
and then pops the top element.
<p>
-To resume a coroutine, you put on its stack only the values to
+To resume a coroutine,
+you remove any results from the last <a href="#lua_yield"><code>lua_yield</code></a>,
+put on its stack only the values to
be passed as results from <code>yield</code>,
and then call <a href="#lua_resume"><code>lua_resume</code></a>.
<p>
Does the equivalent to <code>t[k] = v</code>,
-where <code>t</code> is the value at the given valid index
+where <code>t</code> is the value at the given index
and <code>v</code> is the value at the top of the stack.
<p>
Pops a table from the stack and
-sets it as the new metatable for the value at the given
-acceptable index.
+sets it as the new metatable for the value at the given index.
<p>
Does the equivalent to <code>t[k] = v</code>,
-where <code>t</code> is the value at the given valid index,
+where <code>t</code> is the value at the given index,
<code>v</code> is the value at the top of the stack,
and <code>k</code> is the value just below the top.
<pre>void lua_settop (lua_State *L, int index);</pre>
<p>
-Accepts any acceptable index, or 0,
+Accepts any index, or 0,
and sets the stack top to this index.
If the new top is larger than the old one,
then the new elements are filled with <b>nil</b>.
<pre>int lua_toboolean (lua_State *L, int index);</pre>
<p>
-Converts the Lua value at the given acceptable index to a C boolean
+Converts the Lua value at the given index to a C boolean
value (0 or 1).
Like all tests in Lua,
<a href="#lua_toboolean"><code>lua_toboolean</code></a> returns true for any Lua value
different from <b>false</b> and <b>nil</b>;
otherwise it returns false.
-It also returns false when called with a non-valid index.
(If you want to accept only actual boolean values,
use <a href="#lua_isboolean"><code>lua_isboolean</code></a> to test the value's type.)
<pre>lua_CFunction lua_tocfunction (lua_State *L, int index);</pre>
<p>
-Converts a value at the given acceptable index to a C function.
+Converts a value at the given index to a C function.
That value must be a C function;
otherwise, returns <code>NULL</code>.
<pre>lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);</pre>
<p>
-Converts the Lua value at the given acceptable index
+Converts the Lua value at the given index
to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>.
The Lua value must be a number or a string convertible to a number
(see <a href="#3.4.2">§3.4.2</a>);
<pre>const char *lua_tolstring (lua_State *L, int index, size_t *len);</pre>
<p>
-Converts the Lua value at the given acceptable index to a C string.
+Converts the Lua value at the given index to a C string.
If <code>len</code> is not <code>NULL</code>,
it also sets <code>*len</code> with the string length.
The Lua value must be a string or a number;
<pre>lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);</pre>
<p>
-Converts the Lua value at the given acceptable index
+Converts the Lua value at the given index
to the C type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>).
The Lua value must be a number or a string convertible to a number
(see <a href="#3.4.2">§3.4.2</a>);
<pre>const void *lua_topointer (lua_State *L, int index);</pre>
<p>
-Converts the value at the given acceptable index to a generic
+Converts the value at the given index to a generic
C pointer (<code>void*</code>).
The value can be a userdata, a table, a thread, or a function;
otherwise, <code>lua_topointer</code> returns <code>NULL</code>.
<pre>lua_State *lua_tothread (lua_State *L, int index);</pre>
<p>
-Converts the value at the given acceptable index to a Lua thread
+Converts the value at the given index to a Lua thread
(represented as <code>lua_State*</code>).
This value must be a thread;
otherwise, the function returns <code>NULL</code>.
<pre>lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);</pre>
<p>
-Converts the Lua value at the given acceptable index
+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 a number or a string convertible to a number
(see <a href="#3.4.2">§3.4.2</a>);
<pre>void *lua_touserdata (lua_State *L, int index);</pre>
<p>
-If the value at the given acceptable index is a full userdata,
+If the value at the given index is a full userdata,
returns its block address.
If the value is a light userdata,
returns its pointer.
<pre>int lua_type (lua_State *L, int index);</pre>
<p>
-Returns the type of the value in the given acceptable index,
-or <code>LUA_TNONE</code> for a non-valid index.
+Returns the type of the value in the given valid index,
+or <code>LUA_TNONE</code> for a non-valid (but acceptable) index.
The types returned by <a href="#lua_type"><code>lua_type</code></a> are coded by the following constants
defined in <code>lua.h</code>:
<a name="pdf-LUA_TNIL"><code>LUA_TNIL</code></a>,
+<hr><h3><a name="lua_upvalueindex"><code>lua_upvalueindex</code></a></h3><p>
+<span class="apii">[-0, +0, –]</span>
+<pre>int lua_upvalueindex (int i);</pre>
+
+<p>
+Returns the pseudo-index that represents the <code>i</code>-th upvalue of
+the running function (see <a href="#4.4">§4.4</a>).
+
+
+
+
+
<hr><h3><a name="lua_version"><code>lua_version</code></a></h3><p>
<span class="apii">[-0, +0, <em>v</em>]</span>
<pre>const lua_Number *lua_version (lua_State *L);</pre>
<p>
Ensures that the value <code>t[fname]</code>,
-where <code>t</code> is the value at the valid index <code>idx</code>,
+where <code>t</code> is the value at index <code>idx</code>,
is a table,
and pushes that table onto the stack.
Returns true if it finds a previous table there
<pre>int luaL_len (lua_State *L, int index);</pre>
<p>
-Returns the "length" of the value at the given acceptable index
+Returns the "length" of the value at the given index
as a number;
it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">§3.4.6</a>).
Raises an error if the result of the operation is not a number.
<hr><h3><a name="luaL_newlib"><code>luaL_newlib</code></a></h3><p>
<span class="apii">[-0, +1, <em>e</em>]</span>
-<pre>int luaL_newlib (lua_State *L, const luaL_Reg *l);</pre>
+<pre>void luaL_newlib (lua_State *L, const luaL_Reg *l);</pre>
<p>
Creates a new table and registers there
<hr><h3><a name="luaL_newlibtable"><code>luaL_newlibtable</code></a></h3><p>
<span class="apii">[-0, +1, <em>e</em>]</span>
-<pre>int luaL_newlibtable (lua_State *L, const luaL_Reg l[]);</pre>
+<pre>void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);</pre>
<p>
Creates a new table with a size optimized
<pre>const char *luaL_tolstring (lua_State *L, int idx, size_t *len);</pre>
<p>
-Converts any Lua value at the given acceptable index to a C string
+Converts any Lua value at the given index to a C string
in a reasonable format.
The resulting string is pushed onto the stack and also
returned by the function.
<p>
If the resulting function has upvalues,
-the first upvalue is set to the value of the
-global environment or to <code>env</code>,
-if that parameter is given.
-When loading main chunks,
-the first upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>).
+the first upvalue is set to the value of <code>env</code>,
+if that parameter is given,
+or to the value of the global environment.
+(When you load a main chunk,
+the resulting function will always have exactly one upvalue,
+the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>).
+When you load a binary chunk created from a function (see <a href="#pdf-string.dump"><code>string.dump</code></a>),
+the resulting function can have arbitrary upvalues.)
<p>
<p>
-
<hr><h3><a name="pdf-package.loaded"><code>package.loaded</code></a></h3>
Otherwise,
it looks for a function <code>funcname</code> inside the library
and returns this function as a C function.
-(So, <code>funcname</code> must follow the prototype <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
+So, <code>funcname</code> must follow the <a href="#lua_CFunction"><code>lua_CFunction</code></a> prototype
+(see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
<p>
<p>
Returns a formatted version of its variable number of arguments
following the description given in its first argument (which must be a string).
-The format string follows the same rules as the C function <code>sprintf</code>.
+The format string follows the same rules as the ANSI C function <code>sprintf</code>.
The only differences are that the options/modifiers
<code>*</code>, <code>h</code>, <code>L</code>, <code>l</code>, <code>n</code>,
and <code>p</code> are not supported
<p>
Given a list where all elements are strings or numbers,
-returns <code>list[i]..sep..list[i+1] ··· sep..list[j]</code>.
+returns the string <code>list[i]..sep..list[i+1] ··· sep..list[j]</code>.
The default value for <code>sep</code> is the empty string,
the default for <code>i</code> is 1,
and the default for <code>j</code> is <code>#list</code>.
<p>
Removes from <code>list</code> the element at position <code>pos</code>,
-shifting down the elements
+returning the value of the removed element.
+When <code>pos</code> is an integer between 1 and <code>#list</code>,
+it shifts down the elements
<code>list[pos+1], list[pos+2], ···, list[#list]</code>
-and erasing element <code>list[#list]</code>.
-Returns the value of the removed element.
+and erases element <code>list[#list]</code>;
+The index <code>pos</code> can also be 0 when <code>#list</code> is 0,
+or <code>#list + 1</code>;
+in those cases, the function erases the element <code>list[pos]</code>.
+
+
+<p>
The default value for <code>pos</code> is <code>#list</code>,
so that a call <code>table.remove(t)</code> removes the last element
of list <code>t</code>.
(plus an error message as a second result and
a system-dependent error code as a third result)
and some value different from <b>nil</b> on success.
+On non-Posix systems,
+the computation of the error message and error code
+in case of errors
+may be not thread safe,
+because they rely on the global C variable <code>errno</code>.
<p>
<p>
If <code>format</code> is not "<code>*t</code>",
then <code>date</code> returns the date as a string,
-formatted according to the same rules as the C function <code>strftime</code>.
+formatted according to the same rules as the ANSI C function <code>strftime</code>.
<p>
<p>
-On some systems,
-this function may be not thread safe.
+On non-Posix systems,
+this function may be not thread safe
+because of its reliance on C function <code>gmtime</code> and C function <code>localtime</code>.
<p>
-This function is equivalent to the C function <code>system</code>.
+This function is equivalent to the ANSI C function <code>system</code>.
It passes <code>command</code> to be executed by an operating system shell.
Its first result is <b>true</b>
if the command terminated successfully,
<p>
-Calls the C function <code>exit</code> to terminate the host program.
+Calls the ANSI C function <code>exit</code> to terminate the host program.
If <code>code</code> is <b>true</b>,
the returned status is <code>EXIT_SUCCESS</code>;
if <code>code</code> is <b>false</b>,
for the given category.
+<p>
+This function may be not thread safe
+because of its reliance on C function <code>setlocale</code>.
+
+
<p>
<p>
-Variable names starting with '<code>(</code>' (open parentheses)
+Variable names starting with '<code>(</code>' (open parenthesis)
represent internal variables
(loop control variables, temporaries, varargs, and C function locals).
<HR>
<SMALL CLASS="footer">
Last update:
-Fri Jun 8 16:13:40 BRT 2012
+Thu Mar 21 12:58:59 BRT 2013
</SMALL>
<!--
-Last change: revised for Lua 5.2.1
+Last change: revised for Lua 5.2.2
-->
</body></html>
<OL>
<LI>
Open a terminal window and move to
-the top-level directory, which is named <TT>lua-5.2.1</TT>.
+the top-level directory, which is named <TT>lua-5.2.2</TT>.
The Makefile there controls both the build process and the installation process.
<P>
<LI>
<P>
If you're running Linux and get compilation errors,
make sure you have installed the <TT>readline</TT> development package.
+If you get link errors after that,
+then try "<KBD>make linux MYLIBS=-ltermcap</KBD>".
<H3>Installing Lua</H3>
<P>
<A HREF="http://www.lua.org/license.html">this</A>.
<BLOCKQUOTE STYLE="padding-bottom: 0em">
-Copyright © 1994–2012 Lua.org, PUC-Rio.
+Copyright © 1994–2013 Lua.org, PUC-Rio.
<P>
Permission is hereby granted, free of charge, to any person obtaining a copy
<HR>
<SMALL CLASS="footer">
Last update:
-Tue May 29 21:57:51 BRT 2012
+Fri Feb 22 09:24:20 BRT 2013
</SMALL>
<!--
-Last change: revised for Lua 5.2.1
+Last change: revised for Lua 5.2.2
-->
</BODY>
generic: $(ALL)
linux:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -lncurses"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
macosx:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
/*
-** $Id: lapi.c,v 2.164 2012/06/08 15:14:04 roberto Exp $
+** $Id: lapi.c,v 2.171 2013/03/16 21:10:18 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
/* corresponding test */
#define isvalid(o) ((o) != luaO_nilobject)
-#define api_checkvalidindex(L, i) api_check(L, isvalid(i), "invalid index")
+/* test for pseudo index */
+#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
+
+/* test for valid but not pseudo index */
+#define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
+
+#define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index")
+
+#define api_checkstackindex(L, i, o) \
+ api_check(L, isstackindex(i, o), "index not in the stack")
static TValue *index2addr (lua_State *L, int idx) {
if (o >= L->top) return NONVALIDVALUE;
else return o;
}
- else if (idx > LUA_REGISTRYINDEX) {
+ else if (!ispseudo(idx)) { /* negative index */
api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
return L->top + idx;
}
** convert an acceptable stack index into an absolute index
*/
LUA_API int lua_absindex (lua_State *L, int idx) {
- return (idx > 0 || idx <= LUA_REGISTRYINDEX)
+ return (idx > 0 || ispseudo(idx))
? idx
: cast_int(L->top - L->ci->func + idx);
}
StkId p;
lua_lock(L);
p = index2addr(L, idx);
- api_checkvalidindex(L, p);
+ api_checkstackindex(L, idx, p);
while (++p < L->top) setobjs2s(L, p-1, p);
L->top--;
lua_unlock(L);
StkId q;
lua_lock(L);
p = index2addr(L, idx);
- api_checkvalidindex(L, p);
- for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
+ api_checkstackindex(L, idx, p);
+ for (q = L->top; q > p; q--) /* use L->top as a temporary */
+ setobjs2s(L, q, q - 1);
setobjs2s(L, p, L->top);
lua_unlock(L);
}
TValue *fr;
lua_lock(L);
fr = index2addr(L, fromidx);
- api_checkvalidindex(L, fr);
moveto(L, fr, toidx);
lua_unlock(L);
}
}
-LUA_API void lua_arith (lua_State *L, int op) {
+LUA_API void lua_arith (lua_State *L, int op) {
StkId o1; /* 1st operand */
StkId o2; /* 2nd operand */
lua_lock(L);
o1 = L->top - 2;
o2 = L->top - 1;
if (ttisnumber(o1) && ttisnumber(o2)) {
- changenvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2)));
+ setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2)));
}
else
luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD));
StkId t;
lua_lock(L);
t = index2addr(L, idx);
- api_checkvalidindex(L, t);
luaV_gettable(L, t, L->top - 1, L->top - 1);
lua_unlock(L);
}
StkId t;
lua_lock(L);
t = index2addr(L, idx);
- api_checkvalidindex(L, t);
setsvalue2s(L, L->top, luaS_new(L, k));
api_incr_top(L);
luaV_gettable(L, t, L->top - 1, L->top - 1);
StkId o;
lua_lock(L);
o = index2addr(L, idx);
- api_checkvalidindex(L, o);
api_check(L, ttisuserdata(o), "userdata expected");
if (uvalue(o)->env) {
sethvalue(L, L->top, uvalue(o)->env);
lua_lock(L);
api_checknelems(L, 2);
t = index2addr(L, idx);
- api_checkvalidindex(L, t);
luaV_settable(L, t, L->top - 2, L->top - 1);
L->top -= 2; /* pop index and value */
lua_unlock(L);
lua_lock(L);
api_checknelems(L, 1);
t = index2addr(L, idx);
- api_checkvalidindex(L, t);
setsvalue2s(L, L->top++, luaS_new(L, k));
luaV_settable(L, t, L->top - 1, L->top - 2);
L->top -= 2; /* pop value and key */
lua_lock(L);
api_checknelems(L, 1);
obj = index2addr(L, objindex);
- api_checkvalidindex(L, obj);
if (ttisnil(L->top - 1))
mt = NULL;
else {
switch (ttypenv(obj)) {
case LUA_TTABLE: {
hvalue(obj)->metatable = mt;
- if (mt)
+ if (mt) {
luaC_objbarrierback(L, gcvalue(obj), mt);
luaC_checkfinalizer(L, gcvalue(obj), mt);
+ }
break;
}
case LUA_TUSERDATA: {
lua_lock(L);
api_checknelems(L, 1);
o = index2addr(L, idx);
- api_checkvalidindex(L, o);
api_check(L, ttisuserdata(o), "userdata expected");
if (ttisnil(L->top - 1))
uvalue(o)->env = NULL;
func = 0;
else {
StkId o = index2addr(L, errfunc);
- api_checkvalidindex(L, o);
+ api_checkstackindex(L, errfunc, o);
func = savestack(L, o);
}
c.func = L->top - (nargs+1); /* function to be called */
}
-LUA_API int lua_status (lua_State *L) {
+LUA_API int lua_status (lua_State *L) {
return L->status;
}
lua_lock(L);
api_checknelems(L, 1);
luaG_errormsg(L);
- lua_unlock(L);
+ /* code unreachable; will unlock when control actually leaves the kernel */
return 0; /* to avoid warnings */
}
/*
-** $Id: lauxlib.c,v 1.244 2012/05/31 20:28:45 roberto Exp $
+** $Id: lauxlib.c,v 1.248 2013/03/21 13:54:57 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
if (*ar->namewhat != '\0') /* is there a name? */
lua_pushfstring(L, "function " LUA_QS, ar->name);
else if (*ar->what == 'm') /* main? */
- lua_pushfstring(L, "main chunk");
+ lua_pushliteral(L, "main chunk");
else if (*ar->what == 'C') {
if (pushglobalfuncname(L, ar)) {
lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
if (strcmp(ar.namewhat, "method") == 0) {
narg--; /* do not count `self' */
if (narg == 0) /* error is in the self argument itself? */
- return luaL_error(L, "calling " LUA_QS " on bad self", ar.name);
+ return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
+ ar.name, extramsg);
}
if (ar.name == NULL)
ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
if (fname)
lua_pushfstring(L, "%s: %s", fname, strerror(en));
else
- lua_pushfstring(L, "%s", strerror(en));
+ lua_pushstring(L, strerror(en));
lua_pushinteger(L, en);
return 3;
}
if (B->size - B->n < sz) { /* not enough space? */
char *newbuff;
size_t newsize = B->size * 2; /* double buffer size */
- if (newsize - B->n < sz) /* not bit enough? */
+ if (newsize - B->n < sz) /* not big enough? */
newsize = B->n + sz;
if (newsize < B->n || newsize - B->n < sz)
luaL_error(L, "buffer too large");
lf->n = 0;
do {
c = getc(lf->f);
- if (c == EOF || c != *(unsigned char *)p++) return c;
+ if (c == EOF || c != *(const unsigned char *)p++) return c;
lf->buff[lf->n++] = c; /* to be read by the parser */
} while (*p != '\0');
lf->n = 0; /* prefix matched; discard it */
/*
-** $Id: lbaselib.c,v 1.274 2012/04/27 14:13:19 roberto Exp $
+** $Id: lbaselib.c,v 1.276 2013/02/21 13:44:53 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
}
-static int load_aux (lua_State *L, int status) {
- if (status == LUA_OK)
+static int load_aux (lua_State *L, int status, int envidx) {
+ if (status == LUA_OK) {
+ if (envidx != 0) { /* 'env' parameter? */
+ lua_pushvalue(L, envidx); /* environment for loaded function */
+ if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */
+ lua_pop(L, 1); /* remove 'env' if not used by previous call */
+ }
return 1;
- else {
+ }
+ else { /* error (message is on top of the stack) */
lua_pushnil(L);
lua_insert(L, -2); /* put before error message */
return 2; /* return nil plus error message */
static int luaB_loadfile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
const char *mode = luaL_optstring(L, 2, NULL);
- int env = !lua_isnone(L, 3); /* 'env' parameter? */
+ int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */
int status = luaL_loadfilex(L, fname, mode);
- if (status == LUA_OK && env) { /* 'env' parameter? */
- lua_pushvalue(L, 3);
- lua_setupvalue(L, -2, 1); /* set it as 1st upvalue of loaded chunk */
- }
- return load_aux(L, status);
+ return load_aux(L, status, env);
}
static int luaB_load (lua_State *L) {
int status;
size_t l;
- int top = lua_gettop(L);
const char *s = lua_tolstring(L, 1, &l);
const char *mode = luaL_optstring(L, 3, "bt");
+ int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */
if (s != NULL) { /* loading a string? */
const char *chunkname = luaL_optstring(L, 2, s);
status = luaL_loadbufferx(L, s, l, chunkname, mode);
lua_settop(L, RESERVEDSLOT); /* create reserved slot */
status = lua_load(L, generic_reader, NULL, chunkname, mode);
}
- if (status == LUA_OK && top >= 4) { /* is there an 'env' argument */
- lua_pushvalue(L, 4); /* environment for loaded function */
- lua_setupvalue(L, -2, 1); /* set it as 1st upvalue */
- }
- return load_aux(L, status);
+ return load_aux(L, status, env);
}
/* }====================================================== */
static int luaB_dofile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
lua_settop(L, 1);
- if (luaL_loadfile(L, fname) != LUA_OK) lua_error(L);
+ if (luaL_loadfile(L, fname) != LUA_OK)
+ return lua_error(L);
lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
return dofilecont(L);
}
/*
-** $Id: lbitlib.c,v 1.16 2011/06/20 16:35:23 roberto Exp $
+** $Id: lbitlib.c,v 1.18 2013/03/19 13:19:12 roberto Exp $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/
/*
** get field and width arguments for field-manipulation functions,
-** checking whether they are valid
+** checking whether they are valid.
+** ('luaL_error' called without 'return' to avoid later warnings about
+** 'width' being used uninitialized.)
*/
static int fieldargs (lua_State *L, int farg, int *width) {
int f = luaL_checkint(L, farg);
/*
-** $Id: lcode.c,v 2.60 2011/08/30 16:26:41 roberto Exp $
+** $Id: lcode.c,v 2.62 2012/08/16 17:34:28 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
setnvalue(&o, r);
if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
/* use raw representation as key to avoid numeric problems */
- setsvalue(L, L->top, luaS_newlstr(L, (char *)&r, sizeof(r)));
- incr_top(L);
- n = addk(fs, L->top - 1, &o);
- L->top--;
+ setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
+ n = addk(fs, L->top - 1, &o);
+ L->top--;
}
else
n = addk(fs, &o, &o); /* regular case */
luaK_nil(fs, reg, 1);
break;
}
- case VFALSE: case VTRUE: {
+ case VFALSE: case VTRUE: {
luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
break;
}
/*
-** $Id: lcorolib.c,v 1.4 2012/04/27 18:59:04 roberto Exp $
+** $Id: lcorolib.c,v 1.5 2013/02/21 13:44:53 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
lua_insert(L, -2);
lua_concat(L, 2);
}
- lua_error(L); /* propagate error */
+ return lua_error(L); /* propagate error */
}
return r;
}
/*
-** $Id: ldebug.c,v 2.89 2012/01/20 22:05:50 roberto Exp $
+** $Id: ldebug.c,v 2.90 2012/08/16 17:34:28 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
static void collectvalidlines (lua_State *L, Closure *f) {
if (noLuaClosure(f)) {
setnilvalue(L->top);
- incr_top(L);
+ api_incr_top(L);
}
else {
int i;
int *lineinfo = f->l.p->lineinfo;
Table *t = luaH_new(L); /* new table to store active lines */
sethvalue(L, L->top, t); /* push it on stack */
- incr_top(L);
+ api_incr_top(L);
setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
status = auxgetinfo(L, what, ar, cl, ci);
if (strchr(what, 'f')) {
setobjs2s(L, L->top, func);
- incr_top(L);
+ api_incr_top(L);
}
if (strchr(what, 'L'))
collectvalidlines(L, cl);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
setobjs2s(L, L->top, L->top - 1); /* move argument */
setobjs2s(L, L->top - 1, errfunc); /* push function */
- incr_top(L);
+ L->top++;
luaD_call(L, L->top - 2, 1, 0); /* call it */
}
luaD_throw(L, LUA_ERRRUN);
/*
-** $Id: ldo.c,v 2.105 2012/06/08 15:14:04 roberto Exp $
+** $Id: ldo.c,v 2.108 2012/10/01 14:05:04 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
ci->callstatus = 0;
+ luaC_checkGC(L); /* stack grow uses memory */
if (L->hookmask & LUA_MASKCALL)
luaD_hook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = CIST_LUA;
L->top = ci->top;
+ luaC_checkGC(L); /* stack grow uses memory */
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
return 0;
luaV_execute(L); /* call it */
if (!allowyield) L->nny--;
L->nCcalls--;
- luaC_checkGC(L);
}
int n;
lua_assert(ci->u.c.k != NULL); /* must have a continuation */
lua_assert(L->nny == 0);
- /* finish 'lua_callk' */
+ if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
+ ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */
+ L->errfunc = ci->u.c.old_errfunc;
+ }
+ /* finish 'lua_callk'/'lua_pcall' */
adjustresults(L, ci->nresults);
/* call continuation function */
if (!(ci->callstatus & CIST_STAT)) /* no call status? */
static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
L->top = firstArg; /* remove args from the stack */
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
- incr_top(L);
+ api_incr_top(L);
luaD_throw(L, -1); /* jump back to 'lua_resume' */
}
api_checknelems(L, nresults);
if (L->nny > 0) {
if (L != G(L)->mainthread)
- luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
+ luaG_runerror(L, "attempt to yield across a C-call boundary");
else
luaG_runerror(L, "attempt to yield from outside a coroutine");
}
/*
-** $Id: lfunc.c,v 2.29 2012/05/08 13:53:33 roberto Exp $
+** $Id: lfunc.c,v 2.30 2012/10/03 12:36:46 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
while (*pp != NULL && (p = gco2uv(*pp))->v >= level) {
GCObject *o = obj2gco(p);
lua_assert(p->v != &p->u.value);
+ lua_assert(!isold(o) || isold(obj2gco(L)));
if (p->v == level) { /* found a corresponding upvalue? */
if (isdead(g, o)) /* is it dead? */
changewhite(o); /* resurrect it */
return p;
}
- resetoldbit(o); /* may create a newer upval after this one */
pp = &p->next;
}
/* not found: create a new one */
/*
-** $Id: lgc.c,v 2.133 2012/05/31 21:28:59 roberto Exp $
+** $Id: lgc.c,v 2.140 2013/03/16 21:10:18 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
*/
#define STEPMULADJ 200
+
/*
** macro to adjust 'pause': 'pause' is actually used like
** 'pause / PAUSEADJ' (value chosen by tests)
*/
-#define PAUSEADJ 200
-
-
-
-
-/*
-** standard negative debt for GC; a reasonable "time" to wait before
-** starting a new cycle
-*/
-#define stddebtest(g,e) (-cast(l_mem, (e)/PAUSEADJ) * g->gcpause)
-#define stddebt(g) stddebtest(g, gettotalbytes(g))
+#define PAUSEADJ 100
/*
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(isgenerational(g) || g->gcstate != GCSpause);
+ lua_assert(g->gcstate != GCSpause);
lua_assert(gch(o)->tt != LUA_TTABLE);
- if (keepinvariant(g)) /* must keep invariant? */
+ if (keepinvariantout(g)) /* must keep invariant? */
reallymarkobject(g, v); /* restore invariant */
else { /* sweep phase */
lua_assert(issweepphase(g));
** mark root set and reset all gray lists, to start a new
** incremental (or full) collection
*/
-static void markroot (global_State *g) {
+static void restartcollection (global_State *g) {
g->gray = g->grayagain = NULL;
g->weak = g->allweak = g->ephemeron = NULL;
markobject(g, g->mainthread);
else /* not weak */
traversestrongtable(g, h);
return sizeof(Table) + sizeof(TValue) * h->sizearray +
- sizeof(Node) * sizenode(h);
+ sizeof(Node) * cast(size_t, sizenode(h));
}
g->allgc = o;
resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */
lua_assert(!isold(o)); /* see MOVE OLD rule */
- if (!keepinvariant(g)) /* not keeping invariant? */
+ if (!keepinvariantout(g)) /* not keeping invariant? */
makewhite(g, o); /* "sweep" object */
return o;
}
while ((curr = *p) != NULL) { /* traverse all finalizable objects */
lua_assert(!isfinalized(curr));
lua_assert(testbit(gch(curr)->marked, SEPARATED));
- if (!(all || iswhite(curr))) /* not being collected? */
+ if (!(iswhite(curr) || all)) /* not being collected? */
p = &gch(curr)->next; /* don't bother with it */
else {
l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
ho->next = g->finobj; /* link it in list 'finobj' */
g->finobj = o;
l_setbit(ho->marked, SEPARATED); /* mark it as such */
- if (!keepinvariant(g)) /* not keeping invariant? */
+ if (!keepinvariantout(g)) /* not keeping invariant? */
makewhite(g, o); /* "sweep" object */
else
resetoldbit(o); /* see MOVE OLD rule */
*/
+/*
+** set a reasonable "time" to wait before starting a new GC cycle;
+** cycle will start when memory use hits threshold
+*/
+static void setpause (global_State *g, l_mem estimate) {
+ l_mem debt, threshold;
+ estimate = estimate / PAUSEADJ; /* adjust 'estimate' */
+ threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */
+ ? estimate * g->gcpause /* no overflow */
+ : MAX_LMEM; /* overflow; truncate to maximum */
+ debt = -cast(l_mem, threshold - gettotalbytes(g));
+ luaE_setdebt(g, debt);
+}
+
+
#define sweepphases \
(bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
** object inside the list (instead of to the header), so that the real
** sweep do not need to skip objects created between "now" and the start
** of the real sweep.
-** Returns how many objects it sweeped.
+** Returns how many objects it swept.
*/
static int entersweep (lua_State *L) {
global_State *g = G(L);
static l_mem atomic (lua_State *L) {
global_State *g = G(L);
- l_mem work = -g->GCmemtrav; /* start counting work */
+ l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */
GCObject *origweak, *origall;
lua_assert(!iswhite(obj2gco(g->mainthread)));
markobject(g, L); /* mark running thread */
global_State *g = G(L);
switch (g->gcstate) {
case GCSpause: {
- g->GCmemtrav = 0; /* start to count memory traversed */
- if (!isgenerational(g))
- markroot(g); /* start a new collection */
- /* in any case, root must be marked at this point */
- lua_assert(!iswhite(obj2gco(g->mainthread))
- && !iswhite(gcvalue(&g->l_registry)));
+ /* start to count memory traversed */
+ g->GCmemtrav = g->strt.size * sizeof(GCObject*);
+ lua_assert(!isgenerational(g));
+ restartcollection(g);
g->gcstate = GCSpropagate;
return g->GCmemtrav;
}
static void generationalcollection (lua_State *L) {
global_State *g = G(L);
+ lua_assert(g->gcstate == GCSpropagate);
if (g->GCestimate == 0) { /* signal for another major collection? */
luaC_fullgc(L, 0); /* perform a full regular collection */
g->GCestimate = gettotalbytes(g); /* update control */
}
else {
lu_mem estimate = g->GCestimate;
- luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */
- luaC_runtilstate(L, bitmask(GCSpause));
+ luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */
+ g->gcstate = GCSpropagate; /* skip restart */
if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc)
g->GCestimate = 0; /* signal for a major collection */
+ else
+ g->GCestimate = estimate; /* keep estimate from last major coll. */
+
}
- luaE_setdebt(g, stddebt(g));
+ setpause(g, gettotalbytes(g));
+ lua_assert(g->gcstate == GCSpropagate);
}
global_State *g = G(L);
l_mem debt = g->GCdebt;
int stepmul = g->gcstepmul;
- if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values */
+ if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */
/* convert debt from Kb to 'work units' (avoid zero debt and overflows) */
debt = (debt / STEPMULADJ) + 1;
debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
debt -= work;
} while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
if (g->gcstate == GCSpause)
- debt = stddebtest(g, g->GCestimate); /* pause until next cycle */
- else
+ setpause(g, g->GCestimate); /* pause until next cycle */
+ else {
debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */
- luaE_setdebt(g, debt);
+ luaE_setdebt(g, debt);
+ }
}
void luaC_fullgc (lua_State *L, int isemergency) {
global_State *g = G(L);
int origkind = g->gckind;
- int someblack = keepinvariant(g);
lua_assert(origkind != KGC_EMERGENCY);
if (isemergency) /* do not run finalizers during emergency GC */
g->gckind = KGC_EMERGENCY;
g->gckind = KGC_NORMAL;
callallpendingfinalizers(L, 1);
}
- if (someblack) { /* may there be some black objects? */
+ if (keepinvariant(g)) { /* may there be some black objects? */
/* must sweep all objects to turn them back to white
(as white has not changed, nothing will be collected) */
entersweep(L);
}
/* finish any pending sweep phase to start a new cycle */
luaC_runtilstate(L, bitmask(GCSpause));
- /* run entire collector */
- luaC_runtilstate(L, ~bitmask(GCSpause));
- luaC_runtilstate(L, bitmask(GCSpause));
+ luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */
+ luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */
if (origkind == KGC_GEN) { /* generational mode? */
- /* generational mode must always start in propagate phase */
+ /* generational mode must be kept in propagate phase */
luaC_runtilstate(L, bitmask(GCSpropagate));
}
g->gckind = origkind;
- luaE_setdebt(g, stddebt(g));
+ setpause(g, gettotalbytes(g));
if (!isemergency) /* do not run finalizers during emergency GC */
callallpendingfinalizers(L, 1);
}
/*
-** $Id: lgc.h,v 2.56 2012/05/23 15:43:14 roberto Exp $
+** $Id: lgc.h,v 2.58 2012/09/11 12:53:08 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
#define isgenerational(g) ((g)->gckind == KGC_GEN)
/*
-** macro to tell when main invariant (white objects cannot point to black
+** macros to tell when main invariant (white objects cannot point to black
** ones) must be kept. During a non-generational collection, the sweep
** phase may break the invariant, as objects turned white may point to
** still-black objects. The invariant is restored when sweep ends and
** all objects are white again. During a generational collection, the
** invariant must be kept all times.
*/
-#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic)
+
+#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic)
+
+
+/*
+** Outside the collector, the state in generational mode is kept in
+** 'propagate', so 'keepinvariant' is always true.
+*/
+#define keepinvariantout(g) \
+ check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \
+ g->gcstate <= GCSatomic)
/*
/*
-** $Id: liolib.c,v 2.108 2011/11/25 12:50:03 roberto Exp $
+** $Id: liolib.c,v 2.111 2013/03/21 13:57:27 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
#include "lualib.h"
+#if !defined(lua_checkmode)
+
+/*
+** Check whether 'mode' matches '[rwa]%+?b?'.
+** Change this macro to accept other modes for 'fopen' besides
+** the standard ones.
+*/
+#define lua_checkmode(mode) \
+ (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \
+ (*mode != '+' || ++mode) && /* skip if char is '+' */ \
+ (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \
+ (*mode == '\0'))
+
+#endif
/*
** {======================================================
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
LStream *p = newfile(L);
- int i = 0;
- /* check whether 'mode' matches '[rwa]%+?b?' */
- if (!(mode[i] != '\0' && strchr("rwa", mode[i++]) != NULL &&
- (mode[i] != '+' || ++i) && /* skip if char is '+' */
- (mode[i] != 'b' || ++i) && /* skip if char is 'b' */
- (mode[i] == '\0')))
- return luaL_error(L, "invalid mode " LUA_QS
- " (should match " LUA_QL("[rwa]%%+?b?") ")", mode);
+ const char *md = mode; /* to traverse/check mode */
+ luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode");
p->f = fopen(filename, mode);
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
/*
-** $Id: llex.c,v 2.61 2012/01/23 23:05:51 roberto Exp $
+** $Id: llex.c,v 2.63 2013/03/16 21:10:18 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
const char *luaX_token2str (LexState *ls, int token) {
- if (token < FIRST_RESERVED) {
+ if (token < FIRST_RESERVED) { /* single-byte symbols? */
lua_assert(token == cast(unsigned char, token));
return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
luaO_pushfstring(ls->L, "char(%d)", token);
}
else {
const char *s = luaX_tokens[token - FIRST_RESERVED];
- if (token < TK_EOS)
+ if (token < TK_EOS) /* fixed format (symbols and reserved words)? */
return luaO_pushfstring(ls->L, LUA_QS, s);
- else
+ else /* names, strings, and numerals */
return s;
}
}
int c[3], i; /* keep input for error message */
int r = 0; /* result accumulator */
c[0] = 'x'; /* for error message */
- for (i = 1; i < 3; i++) { /* read two hexa digits */
+ for (i = 1; i < 3; i++) { /* read two hexadecimal digits */
c[i] = next(ls);
if (!lisxdigit(c[i]))
escerror(ls, c, i + 1, "hexadecimal digit expected");
/*
-** $Id: llimits.h,v 1.99 2012/05/28 20:32:28 roberto Exp $
+** $Id: llimits.h,v 1.103 2013/02/20 14:08:56 roberto Exp $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
** both small and large values (outside the range of integers).
*/
-#if defined(MS_ASMTRICK) /* { */
+#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */
/* trick with Microsoft assembler for X86 */
#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i}
#if !defined(lua_number2unsigned) /* { */
/* the following definition assures proper modulo behavior */
-#if defined(LUA_NUMBER_DOUBLE)
+#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT)
#include <math.h>
#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1)
#define lua_number2unsigned(i,n) \
#include <math.h>
#define luai_hashnum(i,n) { int e; \
- n = frexp(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \
+ n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \
lua_number2int(i, n); i += e; }
#endif
/*
-** $Id: lmathlib.c,v 1.81 2012/05/18 17:47:53 roberto Exp $
+** $Id: lmathlib.c,v 1.83 2013/03/07 18:21:32 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
#include "lualib.h"
-/* macro 'l_tg' allows the addition of an 'l' or 'f' to all math operations */
-#if !defined(l_tg)
-#define l_tg(x) (x)
-#endif
-
-
#undef PI
-#define PI (l_tg(3.1415926535897932384626433832795))
-#define RADIANS_PER_DEGREE (PI/180.0)
+#define PI ((lua_Number)(3.1415926535897932384626433832795))
+#define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0))
static int math_abs (lua_State *L) {
- lua_pushnumber(L, l_tg(fabs)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
return 1;
}
static int math_sin (lua_State *L) {
- lua_pushnumber(L, l_tg(sin)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
return 1;
}
static int math_sinh (lua_State *L) {
- lua_pushnumber(L, l_tg(sinh)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_cos (lua_State *L) {
- lua_pushnumber(L, l_tg(cos)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
return 1;
}
static int math_cosh (lua_State *L) {
- lua_pushnumber(L, l_tg(cosh)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_tan (lua_State *L) {
- lua_pushnumber(L, l_tg(tan)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
return 1;
}
static int math_tanh (lua_State *L) {
- lua_pushnumber(L, l_tg(tanh)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_asin (lua_State *L) {
- lua_pushnumber(L, l_tg(asin)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
return 1;
}
static int math_acos (lua_State *L) {
- lua_pushnumber(L, l_tg(acos)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
return 1;
}
static int math_atan (lua_State *L) {
- lua_pushnumber(L, l_tg(atan)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1)));
return 1;
}
static int math_atan2 (lua_State *L) {
- lua_pushnumber(L, l_tg(atan2)(luaL_checknumber(L, 1),
+ lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1),
luaL_checknumber(L, 2)));
return 1;
}
static int math_ceil (lua_State *L) {
- lua_pushnumber(L, l_tg(ceil)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1)));
return 1;
}
static int math_floor (lua_State *L) {
- lua_pushnumber(L, l_tg(floor)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1)));
return 1;
}
static int math_fmod (lua_State *L) {
- lua_pushnumber(L, l_tg(fmod)(luaL_checknumber(L, 1),
+ lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
luaL_checknumber(L, 2)));
return 1;
}
static int math_modf (lua_State *L) {
lua_Number ip;
- lua_Number fp = l_tg(modf)(luaL_checknumber(L, 1), &ip);
+ lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip);
lua_pushnumber(L, ip);
lua_pushnumber(L, fp);
return 2;
}
static int math_sqrt (lua_State *L) {
- lua_pushnumber(L, l_tg(sqrt)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
return 1;
}
static int math_pow (lua_State *L) {
- lua_pushnumber(L, l_tg(pow)(luaL_checknumber(L, 1),
- luaL_checknumber(L, 2)));
+ lua_Number x = luaL_checknumber(L, 1);
+ lua_Number y = luaL_checknumber(L, 2);
+ lua_pushnumber(L, l_mathop(pow)(x, y));
return 1;
}
lua_Number x = luaL_checknumber(L, 1);
lua_Number res;
if (lua_isnoneornil(L, 2))
- res = l_tg(log)(x);
+ res = l_mathop(log)(x);
else {
lua_Number base = luaL_checknumber(L, 2);
- if (base == 10.0) res = l_tg(log10)(x);
- else res = l_tg(log)(x)/l_tg(log)(base);
+ if (base == (lua_Number)10.0) res = l_mathop(log10)(x);
+ else res = l_mathop(log)(x)/l_mathop(log)(base);
}
lua_pushnumber(L, res);
return 1;
#if defined(LUA_COMPAT_LOG10)
static int math_log10 (lua_State *L) {
- lua_pushnumber(L, l_tg(log10)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
return 1;
}
#endif
static int math_exp (lua_State *L) {
- lua_pushnumber(L, l_tg(exp)(luaL_checknumber(L, 1)));
+ lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
return 1;
}
static int math_frexp (lua_State *L) {
int e;
- lua_pushnumber(L, l_tg(frexp)(luaL_checknumber(L, 1), &e));
+ lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
lua_pushinteger(L, e);
return 2;
}
static int math_ldexp (lua_State *L) {
- lua_pushnumber(L, l_tg(ldexp)(luaL_checknumber(L, 1),
- luaL_checkint(L, 2)));
+ lua_Number x = luaL_checknumber(L, 1);
+ int ep = luaL_checkint(L, 2);
+ lua_pushnumber(L, l_mathop(ldexp)(x, ep));
return 1;
}
}
case 1: { /* only upper limit */
lua_Number u = luaL_checknumber(L, 1);
- luaL_argcheck(L, 1.0 <= u, 1, "interval is empty");
- lua_pushnumber(L, l_tg(floor)(r*u) + 1.0); /* int in [1, u] */
+ luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty");
+ lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0)); /* [1, u] */
break;
}
case 2: { /* lower and upper limits */
lua_Number l = luaL_checknumber(L, 1);
lua_Number u = luaL_checknumber(L, 2);
luaL_argcheck(L, l <= u, 2, "interval is empty");
- lua_pushnumber(L, l_tg(floor)(r*(u-l+1)) + l); /* int in [l, u] */
+ lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l); /* [l, u] */
break;
}
default: return luaL_error(L, "wrong number of arguments");
/*
-** $Id: lmem.h,v 1.38 2011/12/02 13:26:54 roberto Exp $
+** $Id: lmem.h,v 1.40 2013/02/20 14:08:21 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#include "lua.h"
+/*
+** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is
+** always constant.
+** The macro is somewhat complex to avoid warnings:
+** +1 avoids warnings of "comparison has constant result";
+** cast to 'void' avoids warnings of "value unused".
+*/
#define luaM_reallocv(L,b,on,n,e) \
- ((cast(size_t, (n)+1) > MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
- (luaM_toobig(L), (void *)0) : \
- luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
+ (cast(void, \
+ (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \
+ luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
/*
-** $Id: lobject.c,v 2.55 2011/11/30 19:30:16 roberto Exp $
+** $Id: lobject.c,v 2.58 2013/02/20 14:08:56 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
static lua_Number readhexa (const char **s, lua_Number r, int *count) {
for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */
- r = (r * 16.0) + cast_num(luaO_hexavalue(cast_uchar(**s)));
+ r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s)));
(*count)++;
}
return r;
*endptr = cast(char *, s); /* valid up to here */
ret:
if (neg) r = -r;
- return ldexp(r, e);
+ return l_mathop(ldexp)(r, e);
}
#endif
static void pushstr (lua_State *L, const char *str, size_t l) {
- setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
- incr_top(L);
+ setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
}
for (;;) {
const char *e = strchr(fmt, '%');
if (e == NULL) break;
- setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
- incr_top(L);
+ luaD_checkstack(L, 2); /* fmt + item */
+ pushstr(L, fmt, e - fmt);
switch (*(e+1)) {
case 's': {
const char *s = va_arg(argp, char *);
break;
}
case 'd': {
- setnvalue(L->top, cast_num(va_arg(argp, int)));
- incr_top(L);
+ setnvalue(L->top++, cast_num(va_arg(argp, int)));
break;
}
case 'f': {
- setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
- incr_top(L);
+ setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
break;
}
case 'p': {
n += 2;
fmt = e+2;
}
+ luaD_checkstack(L, 1);
pushstr(L, fmt, strlen(fmt));
if (n > 0) luaV_concat(L, n + 1);
return svalue(L->top - 1);
/*
-** $Id: lobject.h,v 2.70 2012/05/11 14:10:50 roberto Exp $
+** $Id: lobject.h,v 2.71 2012/09/11 18:21:44 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
-/*
-** LUA_TSTRING variants */
+/* Variant tags for strings */
#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */
#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */
#define setnvalue(obj,x) \
{ TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
-#define changenvalue(o,x) check_exp(ttisnumber(o), num_(o)=(x))
-
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
#define setfvalue(obj,x) \
/*
-** $Id: loslib.c,v 1.39 2012/05/23 15:37:09 roberto Exp $
+** $Id: loslib.c,v 1.40 2012/10/19 15:54:02 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
static int os_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
- return luaL_fileresult(L, rename(fromname, toname) == 0, fromname);
+ return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
}
/*
-** $Id: lparser.c,v 2.128 2012/05/20 14:51:23 roberto Exp $
+** $Id: lparser.c,v 2.130 2013/02/06 13:37:39 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
static int searchvar (FuncState *fs, TString *n) {
int i;
- for (i=fs->nactvar-1; i >= 0; i--) {
+ for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
if (luaS_eqstr(n, getlocvar(fs, i)->varname))
return i;
}
/*
-** codes instruction to create new closure in parent function
+** codes instruction to create new closure in parent function.
+** The OP_CLOSURE instruction must use the last available register,
+** so that, if it invokes the GC, the GC knows which registers
+** are in use at that time.
*/
static void codeclosure (LexState *ls, expdesc *v) {
FuncState *fs = ls->fs->prev;
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
- luaK_exp2nextreg(fs, v); /* fix it at stack top (for GC) */
+ luaK_exp2nextreg(fs, v); /* fix it at the last register */
}
/*
-** $Id: lstate.c,v 2.98 2012/05/30 12:33:44 roberto Exp $
+** $Id: lstate.c,v 2.99 2012/10/02 17:40:53 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
*/
#if !defined(luai_makeseed)
#include <time.h>
-#define luai_makeseed() cast(size_t, time(NULL))
+#define luai_makeseed() cast(unsigned int, time(NULL))
#endif
/*
-** $Id: lstate.h,v 2.81 2012/06/08 15:14:04 roberto Exp $
+** $Id: lstate.h,v 2.82 2012/07/02 13:37:04 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
UpVal uvhead; /* head of double-linked list of all open upvalues */
Mbuffer buff; /* temporary buffer for string concatenation */
int gcpause; /* size of pause between successive GCs */
- int gcmajorinc; /* how much to wait for a major GC (only in gen. mode) */
+ int gcmajorinc; /* pause between major collections (only in gen. mode) */
int gcstepmul; /* GC `granularity' */
lua_CFunction panic; /* to be called in unprotected errors */
struct lua_State *mainthread;
/*
-** $Id: lstring.c,v 2.24 2012/05/11 14:14:42 roberto Exp $
+** $Id: lstring.c,v 2.26 2013/01/08 13:50:10 roberto Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {
- unsigned int h = seed ^ l;
+ unsigned int h = seed ^ cast(unsigned int, l);
size_t l1;
size_t step = (l >> LUAI_HASHLIMIT) + 1;
for (l1 = l; l1 >= step; l1 -= step)
o = gch(o)->next) {
TString *ts = rawgco2ts(o);
if (h == ts->tsv.hash &&
- ts->tsv.len == l &&
+ l == ts->tsv.len &&
(memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */
changewhite(o); /* resurrect it */
/*
-** $Id: lstrlib.c,v 1.176 2012/05/23 15:37:09 roberto Exp $
+** $Id: lstrlib.c,v 1.178 2012/08/14 18:12:34 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
#define CAP_UNFINISHED (-1)
#define CAP_POSITION (-2)
+
typedef struct MatchState {
+ int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
const char *src_init; /* init of source string */
const char *src_end; /* end ('\0') of source string */
const char *p_end; /* end ('\0') of pattern */
} MatchState;
+/* recursive function */
+static const char *match (MatchState *ms, const char *s, const char *p);
+
+
+/* maximum recursion depth for 'match' */
+#if !defined(MAXCCALLS)
+#define MAXCCALLS 200
+#endif
+
+
#define L_ESC '%'
#define SPECIALS "^$*+?.([%-"
}
-static int singlematch (int c, const char *p, const char *ep) {
- switch (*p) {
- case '.': return 1; /* matches any char */
- case L_ESC: return match_class(c, uchar(*(p+1)));
- case '[': return matchbracketclass(c, p, ep-1);
- default: return (uchar(*p) == c);
+static int singlematch (MatchState *ms, const char *s, const char *p,
+ const char *ep) {
+ if (s >= ms->src_end)
+ return 0;
+ else {
+ int c = uchar(*s);
+ switch (*p) {
+ case '.': return 1; /* matches any char */
+ case L_ESC: return match_class(c, uchar(*(p+1)));
+ case '[': return matchbracketclass(c, p, ep-1);
+ default: return (uchar(*p) == c);
+ }
}
}
-static const char *match (MatchState *ms, const char *s, const char *p);
-
-
static const char *matchbalance (MatchState *ms, const char *s,
const char *p) {
if (p >= ms->p_end - 1)
static const char *max_expand (MatchState *ms, const char *s,
const char *p, const char *ep) {
ptrdiff_t i = 0; /* counts maximum expand for item */
- while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
+ while (singlematch(ms, s + i, p, ep))
i++;
/* keeps trying to match with the maximum repetitions */
while (i>=0) {
const char *res = match(ms, s, ep+1);
if (res != NULL)
return res;
- else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
+ else if (singlematch(ms, s, p, ep))
s++; /* try with one more repetition */
else return NULL;
}
static const char *match (MatchState *ms, const char *s, const char *p) {
+ if (ms->matchdepth-- == 0)
+ luaL_error(ms->L, "pattern too complex");
init: /* using goto's to optimize tail recursion */
- if (p == ms->p_end) /* end of pattern? */
- return s; /* match succeeded */
- switch (*p) {
- case '(': { /* start capture */
- if (*(p+1) == ')') /* position capture? */
- return start_capture(ms, s, p+2, CAP_POSITION);
- else
- return start_capture(ms, s, p+1, CAP_UNFINISHED);
- }
- case ')': { /* end capture */
- return end_capture(ms, s, p+1);
- }
- case '$': {
- if ((p+1) == ms->p_end) /* is the `$' the last char in pattern? */
- return (s == ms->src_end) ? s : NULL; /* check end of string */
- else goto dflt;
- }
- case L_ESC: { /* escaped sequences not in the format class[*+?-]? */
- switch (*(p+1)) {
- case 'b': { /* balanced string? */
- s = matchbalance(ms, s, p+2);
- if (s == NULL) return NULL;
- p+=4; goto init; /* else return match(ms, s, p+4); */
- }
- case 'f': { /* frontier? */
- const char *ep; char previous;
- p += 2;
- if (*p != '[')
- luaL_error(ms->L, "missing " LUA_QL("[") " after "
- LUA_QL("%%f") " in pattern");
- ep = classend(ms, p); /* points to what is next */
- previous = (s == ms->src_init) ? '\0' : *(s-1);
- if (matchbracketclass(uchar(previous), p, ep-1) ||
- !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
- p=ep; goto init; /* else return match(ms, s, ep); */
- }
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- case '8': case '9': { /* capture results (%0-%9)? */
- s = match_capture(ms, s, uchar(*(p+1)));
- if (s == NULL) return NULL;
- p+=2; goto init; /* else return match(ms, s, p+2) */
- }
- default: goto dflt;
+ if (p != ms->p_end) { /* end of pattern? */
+ switch (*p) {
+ case '(': { /* start capture */
+ if (*(p + 1) == ')') /* position capture? */
+ s = start_capture(ms, s, p + 2, CAP_POSITION);
+ else
+ s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
+ break;
}
- }
- default: dflt: { /* pattern class plus optional suffix */
- const char *ep = classend(ms, p); /* points to what is next */
- int m = s < ms->src_end && singlematch(uchar(*s), p, ep);
- switch (*ep) {
- case '?': { /* optional */
- const char *res;
- if (m && ((res=match(ms, s+1, ep+1)) != NULL))
- return res;
- p=ep+1; goto init; /* else return match(ms, s, ep+1); */
- }
- case '*': { /* 0 or more repetitions */
- return max_expand(ms, s, p, ep);
- }
- case '+': { /* 1 or more repetitions */
- return (m ? max_expand(ms, s+1, p, ep) : NULL);
+ case ')': { /* end capture */
+ s = end_capture(ms, s, p + 1);
+ break;
+ }
+ case '$': {
+ if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */
+ goto dflt; /* no; go to default */
+ s = (s == ms->src_end) ? s : NULL; /* check end of string */
+ break;
+ }
+ case L_ESC: { /* escaped sequences not in the format class[*+?-]? */
+ switch (*(p + 1)) {
+ case 'b': { /* balanced string? */
+ s = matchbalance(ms, s, p + 2);
+ if (s != NULL) {
+ p += 4; goto init; /* return match(ms, s, p + 4); */
+ } /* else fail (s == NULL) */
+ break;
+ }
+ case 'f': { /* frontier? */
+ const char *ep; char previous;
+ p += 2;
+ if (*p != '[')
+ luaL_error(ms->L, "missing " LUA_QL("[") " after "
+ LUA_QL("%%f") " in pattern");
+ ep = classend(ms, p); /* points to what is next */
+ previous = (s == ms->src_init) ? '\0' : *(s - 1);
+ if (!matchbracketclass(uchar(previous), p, ep - 1) &&
+ matchbracketclass(uchar(*s), p, ep - 1)) {
+ p = ep; goto init; /* return match(ms, s, ep); */
+ }
+ s = NULL; /* match failed */
+ break;
+ }
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9': { /* capture results (%0-%9)? */
+ s = match_capture(ms, s, uchar(*(p + 1)));
+ if (s != NULL) {
+ p += 2; goto init; /* return match(ms, s, p + 2) */
+ }
+ break;
+ }
+ default: goto dflt;
}
- case '-': { /* 0 or more repetitions (minimum) */
- return min_expand(ms, s, p, ep);
+ break;
+ }
+ default: dflt: { /* pattern class plus optional suffix */
+ const char *ep = classend(ms, p); /* points to optional suffix */
+ /* does not match at least once? */
+ if (!singlematch(ms, s, p, ep)) {
+ if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */
+ p = ep + 1; goto init; /* return match(ms, s, ep + 1); */
+ }
+ else /* '+' or no suffix */
+ s = NULL; /* fail */
}
- default: {
- if (!m) return NULL;
- s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
+ else { /* matched once */
+ switch (*ep) { /* handle optional suffix */
+ case '?': { /* optional */
+ const char *res;
+ if ((res = match(ms, s + 1, ep + 1)) != NULL)
+ s = res;
+ else {
+ p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */
+ }
+ break;
+ }
+ case '+': /* 1 or more repetitions */
+ s++; /* 1 match already done */
+ /* go through */
+ case '*': /* 0 or more repetitions */
+ s = max_expand(ms, s, p, ep);
+ break;
+ case '-': /* 0 or more repetitions (minimum) */
+ s = min_expand(ms, s, p, ep);
+ break;
+ default: /* no suffix */
+ s++; p = ep; goto init; /* return match(ms, s + 1, ep); */
+ }
}
+ break;
}
}
}
+ ms->matchdepth++;
+ return s;
}
p++; lp--; /* skip anchor character */
}
ms.L = L;
+ ms.matchdepth = MAXCCALLS;
ms.src_init = s;
ms.src_end = s + ls;
ms.p_end = p + lp;
do {
const char *res;
ms.level = 0;
+ lua_assert(ms.matchdepth == MAXCCALLS);
if ((res=match(&ms, s1, p)) != NULL) {
if (find) {
lua_pushinteger(L, s1 - s + 1); /* start */
const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp);
const char *src;
ms.L = L;
+ ms.matchdepth = MAXCCALLS;
ms.src_init = s;
ms.src_end = s+ls;
ms.p_end = p + lp;
src++) {
const char *e;
ms.level = 0;
+ lua_assert(ms.matchdepth == MAXCCALLS);
if ((e = match(&ms, src, p)) != NULL) {
lua_Integer newstart = e-s;
if (e == src) newstart++; /* empty match? go at least one position */
p++; lp--; /* skip anchor character */
}
ms.L = L;
+ ms.matchdepth = MAXCCALLS;
ms.src_init = src;
ms.src_end = src+srcl;
ms.p_end = p + lp;
while (n < max_s) {
const char *e;
ms.level = 0;
+ lua_assert(ms.matchdepth == MAXCCALLS);
e = match(&ms, src, p);
if (e) {
n++;
nb = sprintf(buff, form, luaL_checkint(L, arg));
break;
}
- case 'd': case 'i': {
+ case 'd': case 'i': {
lua_Number n = luaL_checknumber(L, arg);
LUA_INTFRM_T ni = (LUA_INTFRM_T)n;
lua_Number diff = n - (lua_Number)ni;
nb = sprintf(buff, form, ni);
break;
}
- case 'o': case 'u': case 'x': case 'X': {
+ case 'o': case 'u': case 'x': case 'X': {
lua_Number n = luaL_checknumber(L, arg);
unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n;
lua_Number diff = n - (lua_Number)ni;
nb = sprintf(buff, form, ni);
break;
}
- case 'e': case 'E': case 'f':
+ case 'e': case 'E': case 'f':
#if defined(LUA_USE_AFORMAT)
case 'a': case 'A':
#endif
/*
-** $Id: ltable.c,v 2.71 2012/05/23 15:37:09 roberto Exp $
+** $Id: ltable.c,v 2.72 2012/09/11 19:37:16 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
*/
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
- case LUA_TNIL: return luaO_nilobject;
case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
+ case LUA_TNIL: return luaO_nilobject;
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
- if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
+ if (luai_numeq(cast_num(k), n)) /* index is int? */
return luaH_getint(t, k); /* use specialized version */
/* else go through */
}
/*
-** $Id: ltablib.c,v 1.63 2011/11/28 17:26:30 roberto Exp $
+** $Id: ltablib.c,v 1.65 2013/03/07 18:17:24 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
#include "lualib.h"
-#define aux_getn(L,n) \
- (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n))
+#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n))
+
#if defined(LUA_COMPAT_MAXN)
case 3: {
int i;
pos = luaL_checkint(L, 2); /* 2nd argument is the position */
- if (pos > e) e = pos; /* `grow' array if necessary */
+ 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] */
static int tremove (lua_State *L) {
- int e = aux_getn(L, 1);
- int pos = luaL_optint(L, 2, e);
- if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
- return 0; /* nothing to remove */
+ int size = aux_getn(L, 1);
+ int pos = luaL_optint(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] */
- for ( ;pos<e; pos++) {
+ for ( ; pos < size; pos++) {
lua_rawgeti(L, 1, pos+1);
lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
}
lua_pushnil(L);
- lua_rawseti(L, 1, e); /* t[e] = nil */
+ lua_rawseti(L, 1, pos); /* t[pos] = nil */
return 1;
}
/*
-** $Id: lua.c,v 1.205 2012/05/23 15:37:09 roberto Exp $
+** $Id: lua.c,v 1.206 2012/09/29 20:07:06 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
p = lua_tostring(L, -1);
if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
- lua_pop(L, 1); /* remove global */
return p;
}
char *b = buffer;
size_t l;
const char *prmt = get_prompt(L, firstline);
- if (lua_readline(L, b, prmt) == 0)
+ int readstatus = lua_readline(L, b, prmt);
+ lua_pop(L, 1); /* remove result from 'get_prompt' */
+ if (readstatus == 0)
return 0; /* no input */
l = strlen(b);
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
/*
-** $Id: lua.h,v 1.283 2012/04/20 13:18:26 roberto Exp $
+** $Id: lua.h,v 1.285 2013/03/15 13:04:22 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "2"
#define LUA_VERSION_NUM 502
-#define LUA_VERSION_RELEASE "1"
+#define LUA_VERSION_RELEASE "2"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
-#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2012 Lua.org, PUC-Rio"
+#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2013 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
#endif
+/*
+** RCS ident string
+*/
+extern const char lua_ident[];
+
/*
** state manipulation
/******************************************************************************
-* Copyright (C) 1994-2012 Lua.org, PUC-Rio.
+* Copyright (C) 1994-2013 Lua.org, PUC-Rio.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
/*
-** $Id: luaconf.h,v 1.172 2012/05/11 14:14:42 roberto Exp $
+** $Id: luaconf.h,v 1.176 2013/03/16 21:10:18 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
#define LUA_USE_READLINE /* needs some extra libraries */
-#define LUA_USE_STRTODHEX /* assume 'strtod' handles hexa formats */
+#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */
#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
#define LUA_USE_LONGLONG /* assume support for long long */
#endif
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* does not need -ldl */
#define LUA_USE_READLINE /* needs an extra library: -lreadline */
-#define LUA_USE_STRTODHEX /* assume 'strtod' handles hexa formats */
+#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */
#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
#define LUA_USE_LONGLONG /* assume support for long long */
#endif
/*
+@@ l_mathop allows the addition of an 'l' or 'f' to all math operations
+*/
+#define l_mathop(x) (x)
+
+
+/*
@@ lua_str2number converts a decimal numeric string to a number.
@@ lua_strx2number converts an hexadecimal numeric string to a number.
-** In C99, 'strtod' do both conversions. C89, however, has no function
+** In C99, 'strtod' does both conversions. C89, however, has no function
** to convert floating hexadecimal strings to numbers. For these
** systems, you can leave 'lua_strx2number' undefined and Lua will
** provide its own implementation.
/* the following operations need the math library */
#if defined(lobject_c) || defined(lvm_c)
#include <math.h>
-#define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b))
-#define luai_numpow(L,a,b) (pow(a,b))
+#define luai_nummod(L,a,b) ((a) - l_mathop(floor)((a)/(b))*(b))
+#define luai_numpow(L,a,b) (l_mathop(pow)(a,b))
#endif
/* these are quite standard operations */
** Some tricks with doubles
*/
-#if defined(LUA_CORE) && \
- defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
+#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
/*
** The next definitions activate some tricks to speed up the
** conversion from doubles to integer types, mainly to LUA_UNSIGNED.
**
-@@ MS_ASMTRICK uses Microsoft assembler to avoid clashes with a
+@@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a
** DirectX idiosyncrasy.
**
@@ LUA_IEEE754TRICK uses a trick that should work on any machine
/* Microsoft compiler on a Pentium (32 bit) ? */
#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */
-#define MS_ASMTRICK
+#define LUA_MSASMTRICK
#define LUA_IEEEENDIAN 0
#define LUA_NANTRICK
/*
-** $Id: lvm.c,v 2.152 2012/06/08 15:14:04 roberto Exp $
+** $Id: lvm.c,v 2.155 2013/03/16 21:10:18 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
if (counthook)
L->hookcount = 1; /* undo decrement to zero */
ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
- ci->callstatus |= CIST_HOOKYIELD; /* mark that it yieled */
+ ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
ci->func = L->top - 1; /* protect stack below results */
luaD_throw(L, LUA_YIELD);
}
setobj2s(L, L->top++, p2); /* 2nd argument */
if (!hasres) /* no result? 'p3' is third argument */
setobj2s(L, L->top++, p3); /* 3rd argument */
- luaD_checkstack(L, 0);
/* metamethod may yield only when called from Lua code */
luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci));
if (hasres) { /* if has result, move it to its place */
L->top = ci->top; /* adjust results */
break;
}
- case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
+ case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
break;
default: lua_assert(0);
}
/*
-** $Id: lvm.h,v 2.17 2011/05/31 18:27:56 roberto Exp $
+** $Id: lvm.h,v 2.18 2013/01/08 14:06:55 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
#define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2))
-#define luaV_rawequalobj(t1,t2) \
- (ttisequal(t1,t2) && luaV_equalobj_(NULL,t1,t2))
+#define luaV_rawequalobj(o1,o2) equalobj(NULL,o1,o2)
/* not to called directly */