Lua diffu-lua-5.3.0-lua-5.3.1


Makefile

@@ -46,7 +46,7 @@
 
 # Lua version and release.
 V= 5.3
-R= $V.0
+R= $V.1
 
 # Targets start here.
 all:	$(PLAT)

README

@@ -1,5 +1,5 @@
 
-This is Lua 5.3.0, released on 06 Jan 2015.
+This is Lua 5.3.1, released on 10 Jun 2015.
 
 For installation instructions, license details, and
 further information about Lua, see doc/readme.html.

doc/contents.html

@@ -3,35 +3,34 @@
 <HEAD>
 <TITLE>Lua 5.3 Reference Manual - contents</TITLE>
 <LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
+<LINK REL="stylesheet" TYPE="text/css" HREF="index.css">
 <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
-<STYLE TYPE="text/css">
-ul {
-	list-style-type: none ;
-	list-style-position: outside ;
-}
-</STYLE>
 </HEAD>
 
 <BODY>
 
-<HR>
 <H1>
-<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="" BORDER=0></A>
+<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
 Lua 5.3 Reference Manual
 </H1>
 
 <P>
 The reference manual is the official definition of the Lua language.
+<BR>
 For a complete introduction to Lua programming, see the book
 <A HREF="http://www.lua.org/pil/">Programming in Lua</A>.
 
-<P>
+<DIV CLASS="menubar">
 <A HREF="manual.html">start</A>
 &middot;
 <A HREF="#contents">contents</A>
 &middot;
 <A HREF="#index">index</A>
-<HR>
+&middot;
+<A HREF="http://www.lua.org/manual/">other versions</A>
+</DIV>
+
+<P>
 <SMALL>
 Copyright &copy; 2015 Lua.org, PUC-Rio.
 Freely available under the terms of the

@@ -39,7 +38,7 @@
 </SMALL>
 
 <H2><A NAME="contents">Contents</A></H2>
-<UL style="padding: 0">
+<UL CLASS="contents menubar">
 <LI><A HREF="manual.html">1 &ndash; Introduction</A>
 <P>
 <LI><A HREF="manual.html#2">2 &ndash; Basic Concepts</A>

@@ -136,15 +135,14 @@
 </UL>
 
 <H2><A NAME="index">Index</A></H2>
-<TABLE WIDTH="100%">
-<TR VALIGN="top">
+<TABLE CLASS="menubar" WIDTH="100%">
+<TR>
 <TD>
 <H3><A NAME="functions">Lua functions</A></H3>
 <P>
 <A HREF="manual.html#6.1">basic</A><BR>
 <A HREF="manual.html#pdf-_G">_G</A><BR>
 <A HREF="manual.html#pdf-_VERSION">_VERSION</A><BR>
-
 <A HREF="manual.html#pdf-assert">assert</A><BR>
 <A HREF="manual.html#pdf-collectgarbage">collectgarbage</A><BR>
 <A HREF="manual.html#pdf-dofile">dofile</A><BR>

@@ -321,6 +319,7 @@
 <A HREF="manual.html#pdf-utf8.offset">utf8.offset</A><BR>
 
 <H3><A NAME="env">environment<BR>variables</A></H3>
+<P>
 <A HREF="manual.html#pdf-LUA_CPATH">LUA_CPATH</A><BR>
 <A HREF="manual.html#pdf-LUA_CPATH_5_3">LUA_CPATH_5_3</A><BR>
 <A HREF="manual.html#pdf-LUA_INIT">LUA_INIT</A><BR>

@@ -546,6 +545,7 @@
 <A HREF="manual.html#pdf-luaopen_utf8">luaopen_utf8</A><BR>
 
 <H3><A NAME="constants">constants</A></H3>
+<P>
 <A HREF="manual.html#pdf-LUA_ERRERR">LUA_ERRERR</A><BR>
 <A HREF="manual.html#pdf-LUA_ERRFILE">LUA_ERRFILE</A><BR>
 <A HREF="manual.html#pdf-LUA_ERRGCMM">LUA_ERRGCMM</A><BR>

@@ -606,13 +606,12 @@
 </TR>
 </TABLE>
 
-<HR>
-<SMALL CLASS="footer">
+<P CLASS="footer">
 Last update:
-Tue Dec  9 21:26:07 BRST 2014
-</SMALL>
+Wed Jun  3 08:27:30 BRT 2015
+</P>
 <!--
-Last change: updated for Lua 5.3.0 (final)
+Last change: revised for Lua 5.3.1
 -->
 
 </BODY>
Only in lua-5.3.1/doc: index.css

doc/lua.css

@@ -3,84 +3,90 @@
 }
 
 body {
-	border: solid #a0a0a0 1px ;
-	border-radius: 20px ;
-	padding: 26px ;
-	margin: 16px ;
-	color: #000000 ;
 	background-color: #FFFFFF ;
+	color: #000000 ;
 	font-family: Helvetica, Arial, sans-serif ;
 	text-align: justify ;
+	line-height: 1.25 ;
+	margin: 16px auto ;
+	padding: 32px ;
+	border: solid #a0a0a0 1px ;
+	border-radius: 20px ;
+	max-width: 70em ;
+	width: 90% ;
 }
 
 h1, h2, h3, h4 {
+	color: #000080 ;
 	font-family: Verdana, Geneva, sans-serif ;
 	font-weight: normal ;
 	font-style: normal ;
+	text-align: left ;
 }
 
-h2 {
-	padding-top: 0.4em ;
-	padding-bottom: 0.4em ;
-	padding-left: 0.8em ;
-	padding-right: 0.8em ;
-	background-color: #D0D0FF ;
-	border-radius: 8px ;
-	border: solid #a0a0a0 1px ;
+h1 {
+	font-size: 28pt ;
 }
 
-h3 {
-	padding-left: 0.5em ;
-	border-left: solid #D0D0FF 1em ;
+h1 img {
+	vertical-align: text-bottom ;
 }
 
-table h3 {
-	padding-left: 0px ;
-	border-left: none ;
+h2:before {
+	content: "\2756" ;
+	padding-right: 0.5em ;
 }
 
-a:link {
-	color: #000080 ;
-	background-color: inherit ;
+a {
 	text-decoration: none ;
 }
 
-a:visited {
-	background-color: inherit ;
-	text-decoration: none ;
+a:link {
+	color: #000080 ;
 }
 
 a:link:hover, a:visited:hover {
-	color: #000080 ;
 	background-color: #D0D0FF ;
-	border-radius: 4px;
+	color: #000080 ;
+	border-radius: 4px ;
 }
 
 a:link:active, a:visited:active {
 	color: #FF0000 ;
 }
 
-h1 a img {
-	vertical-align: text-bottom ;
+div.menubar {
+	padding-bottom: 0.5em ;
 }
 
-hr {
-	border: 0 ;
-	height: 1px ;
-	color: #a0a0a0 ;
-	background-color: #a0a0a0 ;
-	display: none ;
+p.menubar {
+	margin-left: 2.5em ;
 }
 
-table hr {
-	display: block ;
+.menubar a:hover  {
+	margin: -3px -3px -3px -3px ;
+	padding: 3px  3px  3px  3px ;
+	border-radius: 4px ;
 }
 
 :target {
-	background-color: #F8F8F8 ;
+	background-color: #F0F0F0 ;
+	margin: -8px ;
 	padding: 8px ;
-	border: solid #a0a0a0 2px ;
 	border-radius: 8px ;
+	outline: none ;
+}
+
+hr {
+	display: none ;
+}
+
+table hr {
+	background-color: #a0a0a0 ;
+	color: #a0a0a0 ;
+	border: 0 ;
+	height: 1px ;
+	display: block ;
 }
 
 .footer {

@@ -103,3 +109,25 @@
 	padding: 1em ;
 	border-radius: 8px ;
 }
+
+td.gutter {
+	width: 4% ;
+}
+
+table.columns {
+	border: none ;
+	border-spacing: 0 ;
+	border-collapse: collapse ;
+}
+
+table.columns td {
+	vertical-align: top ;
+	padding: 0 ;
+	padding-bottom: 1em ;
+	text-align: justify ;
+	line-height: 1.25 ;
+}
+
+p.logos a:link:hover, p.logos a:visited:hover {
+	background-color: inherit ;
+}

doc/manual.css

@@ -8,20 +8,14 @@
 }
 
 span.apii {
+	color: gray ;
 	float: right ;
 	font-family: inherit ;
 	font-style: normal ;
 	font-size: small ;
-	color: gray ;
 }
 
-p+h1, ul+h1 {
-	font-style: normal ;
-	padding-top: 0.4em ;
-	padding-bottom: 0.4em ;
-	padding-left: 16px ;
-	margin-left: -16px ;
-	background-color: #D0D0FF ;
-	border-radius: 8px ;
-	border: solid #000080 1px ;
+h2:before {
+	content: "" ;
+	padding-right: 0em ;
 }

doc/manual.html

@@ -1,39 +1,41 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-
-<head>
-<title>Lua 5.3 Reference Manual</title>
-<link rel="stylesheet" type="text/css" href="lua.css">
-<link rel="stylesheet" type="text/css" href="manual.css">
+<HTML>
+<HEAD>
+<TITLE>Lua 5.3 Reference Manual</TITLE>
+<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
+<LINK REL="stylesheet" TYPE="text/css" HREF="manual.css">
 <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
-</head>
+</HEAD>
 
-<body>
+<BODY>
 
-<hr>
-<h1>
-<a href="http://www.lua.org/"><img src="logo.gif" alt="" border="0"></a>
+<H1>
+<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
 Lua 5.3 Reference Manual
-</h1>
+</H1>
 
+<P>
 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
-<p>
-<small>
+
+<P>
+<SMALL>
 Copyright &copy; 2015 Lua.org, PUC-Rio.
 Freely available under the terms of the
 <a href="http://www.lua.org/license.html">Lua license</a>.
-</small>
-<hr>
-<p>
+</SMALL>
 
-<a href="contents.html#contents">contents</A>
+<DIV CLASS="menubar">
+<A HREF="contents.html#contents">contents</A>
+&middot;
+<A HREF="contents.html#index">index</A>
 &middot;
-<a href="contents.html#index">index</A>
+<A HREF="http://www.lua.org/manual/">other versions</A>
+</DIV>
 
 <!-- ====================================================================== -->
 <p>
 
-<!-- $Id: manual.of,v 1.146 2015/01/06 11:23:01 roberto Exp $ -->
+<!-- $Id: manual.of,v 1.151 2015/06/10 21:08:57 roberto Exp $ -->
 
 
 

@@ -113,15 +115,15 @@
 <em>nil</em>, <em>boolean</em>, <em>number</em>,
 <em>string</em>, <em>function</em>, <em>userdata</em>,
 <em>thread</em>, and <em>table</em>.
-<em>Nil</em> is the type of the value <b>nil</b>,
+The type <em>nil</em> has one single value, <b>nil</b>,
 whose main property is to be different from any other value;
 it usually represents the absence of a useful value.
-<em>Boolean</em> is the type of the values <b>false</b> and <b>true</b>.
+The type <em>boolean</em> has two values, <b>false</b> and <b>true</b>.
 Both <b>nil</b> and <b>false</b> make a condition false;
 any other value makes it true.
-<em>Number</em> represents both
+The type <em>number</em> represents both
 integer numbers and real (floating-point) numbers.
-<em>String</em> represents immutable sequences of bytes.
+The type <em>string</em> represents immutable sequences of bytes.
 
 Lua is 8-bit clean:
 strings can contain any 8-bit value,

@@ -132,6 +134,7 @@
 
 <p>
 The type <em>number</em> uses two internal representations,
+or two subtypes,
 one called <em>integer</em> and the other called <em>float</em>.
 Lua has explicit rules about when each representation is used,
 but it also converts between them automatically as needed (see <a href="#3.4.3">&sect;3.4.3</a>).

@@ -142,7 +145,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 for both integers and floats 
+The option with 32 bits for both integers and floats
 is particularly attractive
 for small machines and embedded systems.
 (See macro <code>LUA_32BITS</code> in file <code>luaconf.h</code>.)

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

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

@@ -425,12 +428,7 @@
 string "<code>__add</code>".
 Note that queries for metamethods are always raw;
 the access to a metamethod does not invoke other metamethods.
-You can emulate how Lua queries a metamethod for an object <code>obj</code>
-with the following code:
 
-<pre>
-     rawget(getmetatable(obj) or {}, "__" .. event_name)
-</pre>
 
 <p>
 For the unary operators (negation, length, and bitwise not),

@@ -510,7 +508,7 @@
 
 Behavior similar to the "add" operation,
 except that Lua will try a metamethod
-if any operator is neither an integer
+if any operand is neither an integer
 nor a value coercible to an integer (see <a href="#3.4.3">&sect;3.4.3</a>).
 </li>
 

@@ -549,7 +547,7 @@
 
 Behavior similar to the "add" operation,
 except that Lua will try a metamethod
-if any operator is neither a string nor a number
+if any operand is neither a string nor a number
 (which is always coercible to a string).
 </li>
 

@@ -599,6 +597,8 @@
 assuming that <code>a &lt;= b</code> is equivalent to <code>not (b &lt; a)</code>.
 As with the other comparison operators,
 the result is always a boolean.
+(This use of the "<code>__lt</code>" event can be removed in future versions;
+it is also slower than a real "<code>__le</code>" metamethod.)
 </li>
 
 <li><b>"index": </b>

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

@@ -752,8 +759,6 @@
 Note that if you set a metatable without a <code>__gc</code> field
 and later create that field in the metatable,
 the object will not be marked for finalization.
-However, after an object has been marked,
-you can freely change the <code>__gc</code> field of its metatable.
 
 
 <p>

@@ -794,7 +799,7 @@
 its finalizer will be called again in the next cycle where the
 object is unreachable.
 In any case,
-the object memory is freed only in the GC cycle where
+the object memory is freed only in a GC cycle where
 the object is unreachable and not marked for finalization.
 
 

@@ -822,8 +827,8 @@
 
 <p>
 A weak table can have weak keys, weak values, or both.
-A table with weak keys allows the collection of its keys,
-but prevents the collection of its values.
+A table with weak values allows the collection of its values,
+but prevents the collection of its keys.
 A table with both weak keys and weak values allows the collection of
 both keys and values.
 In any case, if either the key or the value is collected,

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

@@ -1111,7 +1116,7 @@
 Strings in Lua can contain any 8-bit value, including embedded zeros,
 which can be specified as '<code>\0</code>'.
 More generally,
-we can specify any byte in a literal string by its numerical value.
+we can specify any byte in a literal string by its numeric value.
 This can be done
 with the escape sequence <code>\x<em>XX</em></code>,
 where <em>XX</em> is a sequence of exactly two hexadecimal digits,

@@ -1186,7 +1191,7 @@
 </pre>
 
 <p>
-A <em>numerical constant</em> (or <em>numeral</em>)
+A <em>numeric constant</em> (or <em>numeral</em>)
 can be written with an optional fractional part
 and an optional decimal exponent,
 marked by a letter '<code>e</code>' or '<code>E</code>'.

@@ -1581,11 +1586,11 @@
 <p>
 
 The <b>for</b> statement has two forms:
-one numeric and one generic.
+one numerical and one generic.
 
 
 <p>
-The numeric <b>for</b> loop repeats a block of code while a
+The numerical <b>for</b> loop repeats a block of code while a
 control variable runs through an arithmetic progression.
 It has the following syntax:
 

@@ -1879,13 +1884,13 @@
 
 <p>
 Floor division (<code>//</code>) is a division 
-that rounds the quotient towards minus infinite,
+that rounds the quotient towards minus infinity,
 that is, the floor of the division of its operands.
 
 
 <p>
 Modulo is defined as the remainder of a division
-that rounds the quotient towards minus infinite (floor division).
+that rounds the quotient towards minus infinity (floor division).
 
 
 <p>

@@ -1972,8 +1977,9 @@
 First, the string is converted to an integer or a float,
 following its syntax and the rules of the Lua lexer.
 (The string may have also leading and trailing spaces and a sign.)
-Then, the resulting number is converted to the required type
-(float or integer) according to the previous rules.
+Then, the resulting number (float or integer)
+is converted to the type (float or integer) required by the context
+(e.g., the operation that forced the conversion).
 
 
 <p>

@@ -2006,11 +2012,7 @@
 If the types are different, then the result is <b>false</b>.
 Otherwise, the values of the operands are compared.
 Strings are compared in the obvious way.
-Numbers follow the usual rule for binary operations:
-if both operands are integers,
-they are compared as integers;
-otherwise, they are converted to floats
-and compared as such.
+Numbers are equal if they denote the same mathematical value.
 
 
 <p>

@@ -2045,8 +2047,8 @@
 <p>
 The order operators work as follows.
 If both arguments are numbers,
-then they are compared following
-the usual rule for binary operations.
+then they are compared according to their mathematical values
+(regardless of their subtypes).
 Otherwise, if both arguments are strings,
 then their values are compared according to the current locale.
 Otherwise, Lua tries to call the "lt" or the "le"

@@ -2055,6 +2057,12 @@
 and <code>a &gt;= b</code> is translated to <code>b &lt;= a</code>.
 
 
+<p>
+Following the IEEE 754 standard,
+NaN is considered neither smaller than,
+nor equal to, nor greater than any value (including itself).
+
+
 
 
 

@@ -2636,29 +2644,22 @@
 
 <p>
 A <em>valid index</em> is an index that refers to a
-real position within the stack, that is,
-its position lies between&nbsp;1 and the stack top
-(<code>1 &le; abs(index) &le; top</code>).
-
-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&nbsp;code
-but which are not in the stack.
-Pseudo-indices are used to access the registry
+position that stores a modifiable Lua value.
+It comprises stack indices between&nbsp;1 and the stack top
+(<code>1 &le; abs(index) &le; top</code>)
+
+plus <em>pseudo-indices</em>,
+which represent some positions that are accessible to C&nbsp;code
+but that are not in the stack.
+Pseudo-indices are used to access the registry (see <a href="#4.5">&sect;4.5</a>)
 and the upvalues of a C&nbsp;function (see <a href="#4.4">&sect;4.4</a>).
 
 
 <p>
-Functions that do not need a specific stack position,
-but only a value in the stack (e.g., query functions),
+Functions that do not need a specific mutable position,
+but only a value (e.g., query functions),
 can be called with acceptable indices.
 An <em>acceptable index</em> can be any valid index,
-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.

@@ -2701,7 +2702,7 @@
 its upvalues are located at specific pseudo-indices.
 These pseudo-indices are produced by the macro
 <a href="#lua_upvalueindex"><code>lua_upvalueindex</code></a>.
-The first value associated with a function is at position
+The first upvalue associated with a function is at index
 <code>lua_upvalueindex(1)</code>, and so on.
 Any access to <code>lua_upvalueindex(<em>n</em>)</code>,
 where <em>n</em> is greater than the number of upvalues of the

@@ -2719,8 +2720,7 @@
 a predefined table that can be used by any C&nbsp;code to
 store whatever Lua values it needs to store.
 The registry table is always located at pseudo-index
-<a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>,
-which is a valid index.
+<a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>.
 Any C&nbsp;library can store data into this table,
 but it must take care to choose keys
 that are different from those used

@@ -2981,7 +2981,8 @@
 <pre>int lua_absindex (lua_State *L, int idx);</pre>
 
 <p>
-Converts the acceptable index <code>idx</code> into an absolute index
+Converts the acceptable index <code>idx</code>
+into an equivalent absolute index
 (that is, one that does not depend on the stack top).
 
 

@@ -3224,7 +3225,7 @@
 
 <p>
 As an example, the following function receives a variable number
-of numerical arguments and returns their average and their sum:
+of numeric arguments and returns their average and their sum:
 
 <pre>
      static int foo (lua_State *L) {

@@ -3383,8 +3384,9 @@
 
 <p>
 If <code>strip</code> is true,
-the binary representation is created without debug information
-about the function.
+the binary representation may not include all debug information
+about the function,
+to save space.
 
 
 <p>

@@ -3661,7 +3663,7 @@
 (usually a 64-bit two-complement integer),
 but that can be changed to <code>long</code> or <code>int</code>
 (usually a 32-bit two-complement integer).
-(See <code>LUA_INT</code> in <code>luaconf.h</code>.)
+(See <code>LUA_INT_TYPE</code> in <code>luaconf.h</code>.)
 
 
 <p>

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

@@ -4068,7 +4070,7 @@
 
 
 <hr><h3><a name="lua_Number"><code>lua_Number</code></a></h3>
-<pre>typedef double lua_Number;</pre>
+<pre>typedef ... lua_Number;</pre>
 
 <p>
 The type of floats in Lua.

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

@@ -4133,7 +4135,7 @@
 is exactly the original error message.
 Otherwise, <code>msgh</code> is the stack index of a
 <em>message handler</em>.
-(In the current implementation, this index cannot be a pseudo-index.)
+(This index cannot be a pseudo-index.)
 In case of runtime errors,
 this function will be called with the error message
 and its return value will be the message

@@ -4267,20 +4269,11 @@
 
 
 <p>
-Any function to be registered in Lua must
+Any function to be callable by Lua must
 follow the correct protocol to receive its parameters
 and return its results (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
 
 
-<p>
-<code>lua_pushcfunction</code> is defined as a macro:
-
-<pre>
-     #define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)
-</pre><p>
-Note that <code>f</code> is used twice.
-
-
 
 
 

@@ -4309,7 +4302,7 @@
 '<code>%%</code>' (inserts the character '<code>%</code>'),
 '<code>%s</code>' (inserts a zero-terminated string, with no size restrictions),
 '<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>),
-'<code>%L</code>' (inserts a <a href="#lua_Integer"><code>lua_Integer</code></a>),
+'<code>%I</code>' (inserts a <a href="#lua_Integer"><code>lua_Integer</code></a>),
 '<code>%p</code>' (inserts a pointer as a hexadecimal numeral),
 '<code>%d</code>' (inserts an <code>int</code>),
 '<code>%c</code>' (inserts an <code>int</code> as a one-byte character), and

@@ -4369,9 +4362,8 @@
 <pre>const char *lua_pushliteral (lua_State *L, const char *s);</pre>
 
 <p>
-This macro is equivalent to <a href="#lua_pushlstring"><code>lua_pushlstring</code></a>,
-but can be used only when <code>s</code> is a literal string.
-It automatically provides the string length.
+This macro is equivalent to <a href="#lua_pushstring"><code>lua_pushstring</code></a>,
+but should be used only when <code>s</code> is a literal string.
 
 
 

@@ -4598,9 +4590,9 @@
 <pre>void lua_rawsetp (lua_State *L, int index, const void *p);</pre>
 
 <p>
-Does the equivalent of <code>t[k] = v</code>,
+Does the equivalent of <code>t[p] = v</code>,
 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,
+<code>p</code> is encoded as a light userdata,
 and <code>v</code> is the value at the top of the stack.
 
 

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

@@ -4684,7 +4676,7 @@
 <pre>int lua_resume (lua_State *L, lua_State *from, int nargs);</pre>
 
 <p>
-Starts and resumes a coroutine in a given thread.
+Starts and resumes a coroutine in the given thread <code>L</code>.
 
 
 <p>

@@ -4731,12 +4723,16 @@
 <pre>void lua_rotate (lua_State *L, int idx, int n);</pre>
 
 <p>
-Rotates the stack elements from <code>idx</code> to the top <code>n</code> positions
-in the direction of the top, for a positive <code>n</code>,
+Rotates the stack elements between the valid index <code>idx</code>
+and the top of the stack.
+The elements are rotated <code>n</code> positions in the direction of the top,
+for a positive <code>n</code>,
 or <code>-n</code> positions in the direction of the bottom,
 for a negative <code>n</code>.
 The absolute value of <code>n</code> must not be greater than the size
 of the slice being rotated.
+This function cannot be called with a pseudo-index,
+because a pseudo-index is not an actual stack position.
 
 
 

@@ -5072,7 +5068,7 @@
 
 
 <p>
-Typically this function is used only for debug information.
+Typically this function is used only for hashing and debug information.
 
 
 

@@ -5127,7 +5123,7 @@
 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>,
+<a name="pdf-LUA_TNIL"><code>LUA_TNIL</code></a> (0),
 <a name="pdf-LUA_TNUMBER"><code>LUA_TNUMBER</code></a>,
 <a name="pdf-LUA_TBOOLEAN"><code>LUA_TBOOLEAN</code></a>,
 <a name="pdf-LUA_TSTRING"><code>LUA_TSTRING</code></a>,

@@ -5618,24 +5614,26 @@
 <pre>const char *lua_getupvalue (lua_State *L, int funcindex, int n);</pre>
 
 <p>
-Gets information about a closure's upvalue.
-(For Lua functions,
-upvalues are the external local variables that the function uses,
-and that are consequently included in its closure.)
-<a href="#lua_getupvalue"><code>lua_getupvalue</code></a> gets the index <code>n</code> of an upvalue,
-pushes the upvalue's value onto the stack,
+Gets information about the <code>n</code>-th upvalue
+of the closure at index <code>funcindex</code>.
+It pushes the upvalue's value onto the stack
 and returns its name.
-<code>funcindex</code> points to the closure in the stack.
-(Upvalues have no particular order,
-as they are active through the whole function.
-So, they are numbered in an arbitrary order.)
+Returns <code>NULL</code> (and pushes nothing)
+when the index <code>n</code> is greater than the number of upvalues.
 
 
 <p>
-Returns <code>NULL</code> (and pushes nothing)
-when the index is greater than the number of upvalues.
 For C&nbsp;functions, this function uses the empty string <code>""</code>
 as a name for all upvalues.
+(For Lua functions,
+upvalues are the external local variables that the function uses,
+and that are consequently included in its closure.)
+
+
+<p>
+Upvalues have no particular order,
+as they are active through the whole function.
+They are numbered in an arbitrary order.
 
 
 

@@ -5680,10 +5678,10 @@
 
 <p>
 Hook functions can yield under the following conditions:
-Only count and line events can yield
-and they cannot yield any value;
-to yield a hook function must finish its execution
-calling <a href="#lua_yield"><code>lua_yield</code></a> with <code>nresults</code> equal to zero.
+Only count and line events can yield;
+to yield, a hook function must finish its execution
+calling <a href="#lua_yield"><code>lua_yield</code></a> with <code>nresults</code> equal to zero
+(that is, with no values).
 
 
 

@@ -5748,9 +5746,7 @@
 
 <p>
 Sets the value of a local variable of a given activation record.
-Parameters <code>ar</code> and <code>n</code> are as in <a href="#lua_getlocal"><code>lua_getlocal</code></a>
-(see <a href="#lua_getlocal"><code>lua_getlocal</code></a>).
-<a href="#lua_setlocal"><code>lua_setlocal</code></a> assigns the value at the top of the stack
+It assigns the value at the top of the stack
 to the variable and returns its name.
 It also pops the value from the stack.
 

@@ -5761,6 +5757,10 @@
 the number of active local variables.
 
 
+<p>
+Parameters <code>ar</code> and <code>n</code> are as in function <a href="#lua_getlocal"><code>lua_getlocal</code></a>.
+
+
 
 
 

@@ -5773,13 +5773,15 @@
 It assigns the value at the top of the stack
 to the upvalue and returns its name.
 It also pops the value from the stack.
-Parameters <code>funcindex</code> and <code>n</code> are as in the <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>
-(see <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>).
 
 
 <p>
 Returns <code>NULL</code> (and pops nothing)
-when the index is greater than the number of upvalues.
+when the index <code>n</code> is greater than the number of upvalues.
+
+
+<p>
+Parameters <code>funcindex</code> and <code>n</code> are as in function <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>.
 
 
 

@@ -5792,9 +5794,6 @@
 <p>
 Returns a unique identifier for the upvalue numbered <code>n</code>
 from the closure at index <code>funcindex</code>.
-Parameters <code>funcindex</code> and <code>n</code> are as in the <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>
-(see <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>)
-(but <code>n</code> cannot be greater than the number of upvalues).
 
 
 <p>

@@ -5805,6 +5804,11 @@
 will return identical ids for those upvalue indices.
 
 
+<p>
+Parameters <code>funcindex</code> and <code>n</code> are as in function <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>,
+but <code>n</code> cannot be greater than the number of upvalues.
+
+
 
 
 

@@ -6367,9 +6371,9 @@
 
 <p>
 Pushes onto the stack the metatable associated with name <code>tname</code>
-in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>).
-If there is no metatable associated with <code>tname</code>,
-returns false and pushes <b>nil</b>.
+in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>)
+(<b>nil</b> if there is no metatable associated with that name).
+Returns the type of the pushed value.
 
 
 

@@ -7333,7 +7337,7 @@
 <p>
 The order in which the indices are enumerated is not specified,
 <em>even for numeric indices</em>.
-(To traverse a table in numeric order,
+(To traverse a table in numerical order,
 use a numerical <b>for</b>.)
 
 

@@ -7522,8 +7526,6 @@
 <hr><h3><a name="pdf-tostring"><code>tostring (v)</code></a></h3>
 Receives a value of any type and
 converts it to a string in a human-readable format.
-Floats always produce strings with some
-floating-point indication (either a decimal dot or an exponent).
 (For complete control of how numbers are converted,
 use <a href="#pdf-string.format"><code>string.format</code></a>.)
 

@@ -7579,8 +7581,8 @@
 <h2>6.2 &ndash; <a name="6.2">Coroutine Manipulation</a></h2>
 
 <p>
-The operations related to coroutines comprise a sub-library of
-the basic library and come inside the table <a name="pdf-coroutine"><code>coroutine</code></a>.
+This library comprises the operations to manipulate coroutines,
+which come inside the table <a name="pdf-coroutine"><code>coroutine</code></a>.
 See <a href="#2.6">&sect;2.6</a> for a general description of coroutines.
 
 

@@ -7590,7 +7592,7 @@
 
 <p>
 Creates a new coroutine, with body <code>f</code>.
-<code>f</code> must be a Lua function.
+<code>f</code> must be a function.
 Returns this new coroutine,
 an object with type <code>"thread"</code>.
 

@@ -7674,7 +7676,7 @@
 
 <p>
 Creates a new coroutine, with body <code>f</code>.
-<code>f</code> must be a Lua function.
+<code>f</code> must be a function.
 Returns a function that resumes the coroutine each time it is called.
 Any arguments passed to the function behave as the
 extra arguments to <code>resume</code>.

@@ -8073,7 +8075,7 @@
 
 <p>
 <hr><h3><a name="pdf-string.byte"><code>string.byte (s [, i [, j]])</code></a></h3>
-Returns the internal numerical codes of the characters <code>s[i]</code>,
+Returns the internal numeric codes of the characters <code>s[i]</code>,
 <code>s[i+1]</code>, ..., <code>s[j]</code>.
 The default value for <code>i</code> is&nbsp;1;
 the default value for <code>j</code> is&nbsp;<code>i</code>.

@@ -8082,7 +8084,7 @@
 
 
 <p>
-Numerical codes are not necessarily portable across platforms.
+Numeric codes are not necessarily portable across platforms.
 
 
 

@@ -8091,12 +8093,12 @@
 <hr><h3><a name="pdf-string.char"><code>string.char (&middot;&middot;&middot;)</code></a></h3>
 Receives zero or more integers.
 Returns a string with length equal to the number of arguments,
-in which each character has the internal numerical code equal
+in which each character has the internal numeric code equal
 to its corresponding argument.
 
 
 <p>
-Numerical codes are not necessarily portable across platforms.
+Numeric codes are not necessarily portable across platforms.
 
 
 

@@ -8112,9 +8114,9 @@
 so that a later <a href="#pdf-load"><code>load</code></a> on this string returns
 a copy of the function (but with new upvalues).
 If <code>strip</code> is a true value,
-the binary representation is created without debug information
-about the function
-(local variable names, lines, etc.).
+the binary representation may not include all debug information
+about the function,
+to save space.
 
 
 <p>

@@ -8138,7 +8140,7 @@
 If it finds a match, then <code>find</code> returns the indices of&nbsp;<code>s</code>
 where this occurrence starts and ends;
 otherwise, it returns <b>nil</b>.
-A third, optional numerical argument <code>init</code> specifies
+A third, optional numeric argument <code>init</code> specifies
 where to start the search;
 its default value is&nbsp;1 and can be negative.
 A value of <b>true</b> as a fourth, optional argument <code>plain</code>

@@ -8186,18 +8188,23 @@
 
 <p>
 Options
-<code>A</code> and <code>a</code> (when available),
-<code>E</code>, <code>e</code>, <code>f</code>,
+<code>A</code>, <code>a</code>, <code>E</code>, <code>e</code>, <code>f</code>,
 <code>G</code>, and <code>g</code> all expect a number as argument.
 Options <code>c</code>, <code>d</code>,
 <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code>
 expect an integer.
-Option <code>q</code> expects a string;
-option <code>s</code> expects a string without embedded zeros.
-If the argument to option <code>s</code> is not a string,
+Option <code>q</code> expects a string.
+Option <code>s</code> expects a string without embedded zeros;
+if its argument is not a string,
 it is converted to one following the same rules of <a href="#pdf-tostring"><code>tostring</code></a>.
 
 
+<p>
+When Lua is compiled with a non-C99 compiler,
+options <code>A</code> and <code>a</code> (hexadecimal floats)
+do not support any modifier (flags, width, length).
+
+
 
 
 <p>

@@ -8344,7 +8351,7 @@
 otherwise it returns <b>nil</b>.
 If <code>pattern</code> specifies no captures,
 then the whole match is returned.
-A third, optional numerical argument <code>init</code> specifies
+A third, optional numeric argument <code>init</code> specifies
 where to start the search;
 its default value is&nbsp;1 and can be negative.
 

@@ -8499,7 +8506,7 @@
 represents the character <em>x</em>.
 This is the standard way to escape the magic characters.
 Any non-alphanumeric character
-(including all punctuations, even the non-magical)
+(including all punctuation characters, even the non-magical)
 can be preceded by a '<code>%</code>'
 when used to represent itself in a pattern.
 </li>

@@ -8904,7 +8911,7 @@
 <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.
+The number of elements to be moved must fit in a Lua integer.
 
 
 

@@ -9120,7 +9127,7 @@
 
 <p>
 The float value <code>HUGE_VAL</code>,
-a value larger than any other numerical value.
+a value larger than any other numeric value.
 
 
 

@@ -9602,16 +9609,12 @@
 following the lexical conventions of Lua.
 (The numeral may have leading spaces and a sign.)
 This format always reads the longest input sequence that
-is a valid prefix for a number;
-if that prefix does not form a valid number
+is a valid prefix for a numeral;
+if that prefix does not form a valid numeral
 (e.g., an empty string, "<code>0x</code>", or "<code>3.4e-</code>"),
 it is discarded and the function returns <b>nil</b>.
 </li>
 
-<li><b>"<code>i</code>": </b>
-reads an integral number and returns it as an integer.
-</li>
-
 <li><b>"<code>a</code>": </b>
 reads the whole file, starting at the current position.
 On end of file, it returns the empty string.

@@ -9946,17 +9949,26 @@
 
 <p>
 Returns the current time when called without arguments,
-or a time representing the date and time specified by the given table.
+or a time representing the local date and time specified by the given table.
 This table must have fields <code>year</code>, <code>month</code>, and <code>day</code>,
 and may have fields
 <code>hour</code> (default is 12),
 <code>min</code> (default is 0),
 <code>sec</code> (default is 0),
 and <code>isdst</code> (default is <b>nil</b>).
+Other fields are ignored.
 For a description of these fields, see the <a href="#pdf-os.date"><code>os.date</code></a> function.
 
 
 <p>
+The values in these fields do not need to be inside their valid ranges.
+For instance, if <code>sec</code> is -10,
+it means -10 seconds from the time specified by the other fields;
+if <code>hour</code> is 1000,
+it means +1000 hours from the time specified by the other fields.
+
+
+<p>
 The returned value is a number, whose meaning depends on your system.
 In POSIX, Windows, and some other systems,
 this number counts the number

@@ -10093,7 +10105,7 @@
 
 <p>
 For instance, the expression <code>debug.getinfo(1,"n").name</code> returns
-a table with a name for the current function,
+a name for the current function,
 if a reasonable name can be found,
 and the expression <code>debug.getinfo(print)</code>
 returns a table with all available information

@@ -10599,7 +10611,8 @@
 It is easy to require a compatible external library or,
 better yet, to replace its functions with appropriate bitwise operations.
 (Keep in mind that <code>bit32</code> operates on 32-bit integers,
-while the bitwise operators in standard Lua operate on 64-bit integers.)
+while the bitwise operators in Lua&nbsp;5.3 operate on Lua integers,
+which by default have 64&nbsp;bits.)
 </li>
 
 <li>

@@ -10614,7 +10627,7 @@
 
 <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.
+For compatibility, Lua will continue to accept (and ignore) this character.
 </li>
 
 <li>

@@ -10641,6 +10654,12 @@
 but it did not document the change.)
 </li>
 
+<li>
+The call <code>collectgarbage("count")</code> now returns only one result.
+(You can compute that second result from the fractional part
+of the first result.)
+</li>
+
 </ul>
 
 

@@ -10776,13 +10795,12 @@
 
 
 
-<HR>
-<SMALL CLASS="footer">
+<P CLASS="footer">
 Last update:
-Tue Jan  6 10:10:50 BRST 2015
-</SMALL>
+Wed Jun 10 18:31:15 BRT 2015
+</P>
 <!--
-Last change: revised for Lua 5.3.0 (final)
+Last change: revised for Lua 5.3.1
 -->
 
 </body></html>

doc/readme.html

@@ -7,9 +7,9 @@
 <STYLE TYPE="text/css">
 blockquote, .display {
 	border: solid #a0a0a0 2px ;
+	border-radius: 8px ;
 	padding: 1em ;
 	margin: 0px ;
-	border-radius: 8px ;
 }
 
 .display {

@@ -28,13 +28,12 @@
 
 <BODY>
 
-<HR>
 <H1>
-<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A>
-Welcome to Lua 5.3.0
+<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
+Welcome to Lua 5.3
 </H1>
 
-<P>
+<DIV CLASS="menubar">
 <A HREF="#about">about</A>
 &middot;
 <A HREF="#install">installation</A>

@@ -44,9 +43,9 @@
 <A HREF="#license">license</A>
 &middot;
 <A HREF="contents.html">reference manual</A>
+</DIV>
 
 <H2><A NAME="about">About Lua</A></H2>
-
 <P>
 Lua is a powerful, fast, lightweight, embeddable scripting language
 developed by a

@@ -76,7 +75,6 @@
 distributed in this package.
 
 <H2><A NAME="install">Installing Lua</A></H2>
-
 <P>
 Lua is distributed in
 <A HREF="http://www.lua.org/ftp/">source</A>

@@ -102,7 +100,6 @@
 a multi-platform distribution of Lua that includes batteries.
 
 <H3>Building Lua</H3>
-
 <P>
 In most Unix-like platforms, simply do "<KBD>make</KBD>" with a suitable target.
 Here are the details.

@@ -110,7 +107,7 @@
 <OL>
 <LI>
 Open a terminal window and move to
-the top-level directory, which is named <TT>lua-5.3.0</TT>.
+the top-level directory, which is named <TT>lua-5.3.x</TT>.
 The <TT>Makefile</TT> there controls both the build process and the installation process.
 <P>
 <LI>

@@ -140,7 +137,8 @@
 </OL>
 <P>
 If you're running Linux and get compilation errors,
-make sure you have installed the <TT>readline</TT> development package.
+make sure you have installed the <TT>readline</TT> development package
+(which is probably named <TT>libreadline-dev</TT> or <TT>readline-devel</TT>).
 If you get link errors after that,
 then try "<KBD>make linux MYLIBS=-ltermcap</KBD>".
 

@@ -174,7 +172,7 @@
 <DT>
     include:
 <DD>
-    lauxlib.h lua.h lua.hpp luaconf.h lualib.h
+    lua.h luaconf.h lualib.h lauxlib.h lua.hpp
 <DT>
     lib:
 <DD>

@@ -215,7 +213,6 @@
   Further customization is available to experts by editing the Lua sources.
 
 <H3><A NAME="other">Building Lua on other systems</A></H3>
-
 <P>
   If you're not using the usual Unix tools, then the instructions for
   building Lua depend on the compiler you use. You'll need to create

@@ -258,7 +255,6 @@
   some features before building Lua.
 
 <H2><A NAME="changes">Changes since Lua 5.2</A></H2>
-
 <P>
 Here are the main changes introduced in Lua 5.3.
 The

@@ -315,11 +311,10 @@
 </UL>
 
 <H2><A NAME="license">License</A></H2>
+<P>
 <A HREF="http://www.opensource.org/docs/definition.php">
-<IMG SRC="osi-certified-72x60.png" ALIGN="right" BORDER="0" ALT="[osi certified]" STYLE="padding-left: 30px ;">
+<IMG SRC="osi-certified-72x60.png" ALIGN="right" ALT="[osi certified]" STYLE="padding-left: 30px ;">
 </A>
-
-<P>
 Lua is free software distributed under the terms of the
 <A HREF="http://www.opensource.org/licenses/mit-license.html">MIT license</A>
 reproduced below;

@@ -358,13 +353,12 @@
 </BLOCKQUOTE>
 <P>
 
-<HR>
-<SMALL CLASS="footer">
+<P CLASS="footer">
 Last update:
-Fri Dec 12 09:58:42 BRST 2014
-</SMALL>
+Mon Jun  1 21:48:24 BRT 2015
+</P>
 <!--
-Last change: updated for Lua 5.3.0 (final)
+Last change: revised for Lua 5.3.1
 -->
 
 </BODY>

src/Makefile

@@ -130,68 +130,68 @@
 # DO NOT DELETE
 
 lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
-  lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
-  ltable.h lundump.h lvm.h
+ lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
+ ltable.h lundump.h lvm.h
 lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
 lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
-  llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
-  ldo.h lgc.h lstring.h ltable.h lvm.h
+ llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
+ ldo.h lgc.h lstring.h ltable.h lvm.h
 lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h
 ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
-  lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
-  ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
+ lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
+ ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
 ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
-  lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
-  lparser.h lstring.h ltable.h lundump.h lvm.h
+ lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
+ lparser.h lstring.h ltable.h lundump.h lvm.h
 ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
-  ltm.h lzio.h lmem.h lundump.h
+ ltm.h lzio.h lmem.h lundump.h
 lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
-  lgc.h lstate.h ltm.h lzio.h lmem.h
+ lgc.h lstate.h ltm.h lzio.h lmem.h
 lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
-  llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
+ llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
 linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
 liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldo.h \
-  lobject.h lstate.h ltm.h lzio.h lmem.h lgc.h llex.h lparser.h lstring.h \
-  ltable.h
+llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
+ lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \
+ lstring.h ltable.h
 lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
-  llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
+ llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
 loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
-  ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
-  lvm.h
+ ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
+ lvm.h
 lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h
 loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
-  llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
-  ldo.h lfunc.h lstring.h lgc.h ltable.h
+ llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
+ ldo.h lfunc.h lstring.h lgc.h ltable.h
 lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
-  lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
-  lstring.h ltable.h
+ lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
+ lstring.h ltable.h
 lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
-  lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
+ lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
 lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
-  llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
+ llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
 ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
-  llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
+ llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
 lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \
-  lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
+ lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
 lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
-  lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
-  lundump.h
+ lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
+ lundump.h
 lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
 lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
-  llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
-  ltable.h lvm.h
+ llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
+ ltable.h lvm.h
 lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
-  lobject.h ltm.h lzio.h
+ lobject.h ltm.h lzio.h
 
 # (end of Makefile)

src/lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.244 2014/12/26 14:43:45 roberto Exp $
+** $Id: lapi.c,v 2.249 2015/04/06 12:23:48 roberto Exp $
 ** Lua API
 ** See Copyright Notice in lua.h
 */

@@ -51,29 +51,29 @@
 /* test for valid but not pseudo index */
 #define isstackindex(i, o)	(isvalid(o) && !ispseudo(i))
 
-#define api_checkvalidindex(o)  api_check(isvalid(o), "invalid index")
+#define api_checkvalidindex(l,o)  api_check(l, isvalid(o), "invalid index")
 
-#define api_checkstackindex(i, o)  \
-	api_check(isstackindex(i, o), "index not in the stack")
+#define api_checkstackindex(l, i, o)  \
+	api_check(l, isstackindex(i, o), "index not in the stack")
 
 
 static TValue *index2addr (lua_State *L, int idx) {
   CallInfo *ci = L->ci;
   if (idx > 0) {
     TValue *o = ci->func + idx;
-    api_check(idx <= ci->top - (ci->func + 1), "unacceptable index");
+    api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
     if (o >= L->top) return NONVALIDVALUE;
     else return o;
   }
   else if (!ispseudo(idx)) {  /* negative index */
-    api_check(idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
+    api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
     return L->top + idx;
   }
   else if (idx == LUA_REGISTRYINDEX)
     return &G(L)->l_registry;
   else {  /* upvalues */
     idx = LUA_REGISTRYINDEX - idx;
-    api_check(idx <= MAXUPVAL + 1, "upvalue index too large");
+    api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
     if (ttislcf(ci->func))  /* light C function? */
       return NONVALIDVALUE;  /* it has no upvalues */
     else {

@@ -98,7 +98,7 @@
   int res;
   CallInfo *ci = L->ci;
   lua_lock(L);
-  api_check(n >= 0, "negative 'n'");
+  api_check(L, n >= 0, "negative 'n'");
   if (L->stack_last - L->top > n)  /* stack large enough? */
     res = 1;  /* yes; check is OK */
   else {  /* no; need to grow stack */

@@ -120,11 +120,12 @@
   if (from == to) return;
   lua_lock(to);
   api_checknelems(from, n);
-  api_check(G(from) == G(to), "moving among independent states");
-  api_check(to->ci->top - to->top >= n, "not enough elements to move");
+  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");
   from->top -= n;
   for (i = 0; i < n; i++) {
-    setobj2s(to, to->top++, from->top + i);
+    setobj2s(to, to->top, from->top + i);
+    api_incr_top(to);
   }
   lua_unlock(to);
 }

@@ -159,7 +160,7 @@
 LUA_API int lua_absindex (lua_State *L, int idx) {
   return (idx > 0 || ispseudo(idx))
          ? idx
-         : cast_int(L->top - L->ci->func + idx);
+         : cast_int(L->top - L->ci->func) + idx;
 }
 
 

@@ -172,13 +173,13 @@
   StkId func = L->ci->func;
   lua_lock(L);
   if (idx >= 0) {
-    api_check(idx <= L->stack_last - (func + 1), "new top too large");
+    api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
     while (L->top < (func + 1) + idx)
       setnilvalue(L->top++);
     L->top = (func + 1) + idx;
   }
   else {
-    api_check(-(idx+1) <= (L->top - (func + 1)), "invalid new top");
+    api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
     L->top += idx+1;  /* 'subtract' index (index is negative) */
   }
   lua_unlock(L);

@@ -208,8 +209,8 @@
   lua_lock(L);
   t = L->top - 1;  /* end of stack segment being rotated */
   p = index2addr(L, idx);  /* start of segment */
-  api_checkstackindex(idx, p);
-  api_check((n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
+  api_checkstackindex(L, idx, p);
+  api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
   m = (n >= 0 ? t - n : p - n - 1);  /* end of prefix */
   reverse(L, p, m);  /* reverse the prefix with length 'n' */
   reverse(L, m + 1, t);  /* reverse the suffix */

@@ -223,7 +224,7 @@
   lua_lock(L);
   fr = index2addr(L, fromidx);
   to = index2addr(L, toidx);
-  api_checkvalidindex(to);
+  api_checkvalidindex(L, to);
   setobj(L, to, fr);
   if (isupvalue(toidx))  /* function upvalue? */
     luaC_barrier(L, clCvalue(L->ci->func), fr);

@@ -255,7 +256,7 @@
 
 LUA_API const char *lua_typename (lua_State *L, int t) {
   UNUSED(L);
-  api_check(LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
+  api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
   return ttypename(t);
 }
 

@@ -305,7 +306,7 @@
   else {  /* for unary operations, add fake 2nd operand */
     api_checknelems(L, 1);
     setobjs2s(L, L->top, L->top - 1);
-    L->top++;
+    api_incr_top(L);
   }
   /* first operand at top - 2, second at top - 1; result go to top - 2 */
   luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);

@@ -325,7 +326,7 @@
       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(0, "invalid option");
+      default: api_check(L, 0, "invalid option");
     }
   }
   lua_unlock(L);

@@ -382,15 +383,17 @@
     luaO_tostring(L, o);
     lua_unlock(L);
   }
-  if (len != NULL) *len = tsvalue(o)->len;
+  if (len != NULL)
+    *len = vslen(o);
   return svalue(o);
 }
 
 
 LUA_API size_t lua_rawlen (lua_State *L, int idx) {
   StkId o = index2addr(L, idx);
-  switch (ttnov(o)) {
-    case LUA_TSTRING: return tsvalue(o)->len;
+  switch (ttype(o)) {
+    case LUA_TSHRSTR: return tsvalue(o)->shrlen;
+    case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
     case LUA_TUSERDATA: return uvalue(o)->len;
     case LUA_TTABLE: return luaH_getn(hvalue(o));
     default: return 0;

@@ -431,9 +434,8 @@
     case LUA_TCCL: return clCvalue(o);
     case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
     case LUA_TTHREAD: return thvalue(o);
-    case LUA_TUSERDATA:
-    case LUA_TLIGHTUSERDATA:
-      return lua_touserdata(L, idx);
+    case LUA_TUSERDATA: return getudatamem(uvalue(o));
+    case LUA_TLIGHTUSERDATA: return pvalue(o);
     default: return NULL;
   }
 }

@@ -482,20 +484,19 @@
 
 
 LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
-  if (s == NULL) {
-    lua_pushnil(L);
-    return NULL;
-  }
+  lua_lock(L);
+  if (s == NULL)
+    setnilvalue(L->top);
   else {
     TString *ts;
-    lua_lock(L);
     luaC_checkGC(L);
     ts = luaS_new(L, s);
     setsvalue2s(L, L->top, ts);
-    api_incr_top(L);
-    lua_unlock(L);
-    return getstr(ts);
+    s = getstr(ts);  /* internal copy's address */
   }
+  api_incr_top(L);
+  lua_unlock(L);
+  return s;
 }
 
 

@@ -531,7 +532,7 @@
   else {
     CClosure *cl;
     api_checknelems(L, n);
-    api_check(n <= MAXUPVAL, "upvalue index too large");
+    api_check(L, n <= MAXUPVAL, "upvalue index too large");
     luaC_checkGC(L);
     cl = luaF_newCclosure(L, n);
     cl->f = fn;

@@ -583,7 +584,8 @@
   const TValue *gt;  /* global table */
   lua_lock(L);
   gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
-  setsvalue2s(L, L->top++, luaS_new(L, name));
+  setsvalue2s(L, L->top, luaS_new(L, name));
+  api_incr_top(L);
   luaV_gettable(L, gt, L->top - 1, L->top - 1);
   lua_unlock(L);
   return ttnov(L->top - 1);

@@ -628,7 +630,7 @@
   StkId t;
   lua_lock(L);
   t = index2addr(L, idx);
-  api_check(ttistable(t), "table expected");
+  api_check(L, ttistable(t), "table expected");
   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
   lua_unlock(L);
   return ttnov(L->top - 1);

@@ -639,7 +641,7 @@
   StkId t;
   lua_lock(L);
   t = index2addr(L, idx);
-  api_check(ttistable(t), "table expected");
+  api_check(L, ttistable(t), "table expected");
   setobj2s(L, L->top, luaH_getint(hvalue(t), n));
   api_incr_top(L);
   lua_unlock(L);

@@ -652,7 +654,7 @@
   TValue k;
   lua_lock(L);
   t = index2addr(L, idx);
-  api_check(ttistable(t), "table expected");
+  api_check(L, ttistable(t), "table expected");
   setpvalue(&k, cast(void *, p));
   setobj2s(L, L->top, luaH_get(hvalue(t), &k));
   api_incr_top(L);

@@ -705,7 +707,7 @@
   StkId o;
   lua_lock(L);
   o = index2addr(L, idx);
-  api_check(ttisfulluserdata(o), "full userdata expected");
+  api_check(L, ttisfulluserdata(o), "full userdata expected");
   getuservalue(L, uvalue(o), L->top);
   api_incr_top(L);
   lua_unlock(L);

@@ -724,7 +726,8 @@
   lua_lock(L);
   api_checknelems(L, 1);
   gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
-  setsvalue2s(L, L->top++, luaS_new(L, name));
+  setsvalue2s(L, L->top, luaS_new(L, name));
+  api_incr_top(L);
   luaV_settable(L, gt, L->top - 1, L->top - 2);
   L->top -= 2;  /* pop value and key */
   lua_unlock(L);

@@ -747,7 +750,8 @@
   lua_lock(L);
   api_checknelems(L, 1);
   t = index2addr(L, idx);
-  setsvalue2s(L, L->top++, luaS_new(L, k));
+  setsvalue2s(L, L->top, luaS_new(L, k));
+  api_incr_top(L);
   luaV_settable(L, t, L->top - 1, L->top - 2);
   L->top -= 2;  /* pop value and key */
   lua_unlock(L);

@@ -759,7 +763,8 @@
   lua_lock(L);
   api_checknelems(L, 1);
   t = index2addr(L, idx);
-  setivalue(L->top++, n);
+  setivalue(L->top, n);
+  api_incr_top(L);
   luaV_settable(L, t, L->top - 1, L->top - 2);
   L->top -= 2;  /* pop value and key */
   lua_unlock(L);

@@ -772,7 +777,7 @@
   lua_lock(L);
   api_checknelems(L, 2);
   o = index2addr(L, idx);
-  api_check(ttistable(o), "table expected");
+  api_check(L, ttistable(o), "table expected");
   t = hvalue(o);
   setobj2t(L, luaH_set(L, t, L->top-2), L->top-1);
   invalidateTMcache(t);

@@ -788,7 +793,7 @@
   lua_lock(L);
   api_checknelems(L, 1);
   o = index2addr(L, idx);
-  api_check(ttistable(o), "table expected");
+  api_check(L, ttistable(o), "table expected");
   t = hvalue(o);
   luaH_setint(L, t, n, L->top - 1);
   luaC_barrierback(L, t, L->top-1);

@@ -804,7 +809,7 @@
   lua_lock(L);
   api_checknelems(L, 1);
   o = index2addr(L, idx);
-  api_check(ttistable(o), "table expected");
+  api_check(L, ttistable(o), "table expected");
   t = hvalue(o);
   setpvalue(&k, cast(void *, p));
   setobj2t(L, luaH_set(L, t, &k), L->top - 1);

@@ -823,7 +828,7 @@
   if (ttisnil(L->top - 1))
     mt = NULL;
   else {
-    api_check(ttistable(L->top - 1), "table expected");
+    api_check(L, ttistable(L->top - 1), "table expected");
     mt = hvalue(L->top - 1);
   }
   switch (ttnov(obj)) {

@@ -859,7 +864,7 @@
   lua_lock(L);
   api_checknelems(L, 1);
   o = index2addr(L, idx);
-  api_check(ttisfulluserdata(o), "full userdata expected");
+  api_check(L, ttisfulluserdata(o), "full userdata expected");
   setuservalue(L, uvalue(o), L->top - 1);
   luaC_barrier(L, gcvalue(o), L->top - 1);
   L->top--;

@@ -873,7 +878,7 @@
 
 
 #define checkresults(L,na,nr) \
-     api_check((nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
+     api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
 	"results from function overflow current stack size")
 
 

@@ -881,10 +886,10 @@
                         lua_KContext ctx, lua_KFunction k) {
   StkId func;
   lua_lock(L);
-  api_check(k == NULL || !isLua(L->ci),
+  api_check(L, k == NULL || !isLua(L->ci),
     "cannot use continuations inside hooks");
   api_checknelems(L, nargs+1);
-  api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
+  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
   checkresults(L, nargs, nresults);
   func = L->top - (nargs+1);
   if (k != NULL && L->nny == 0) {  /* need to prepare continuation? */

@@ -922,16 +927,16 @@
   int status;
   ptrdiff_t func;
   lua_lock(L);
-  api_check(k == NULL || !isLua(L->ci),
+  api_check(L, k == NULL || !isLua(L->ci),
     "cannot use continuations inside hooks");
   api_checknelems(L, nargs+1);
-  api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
+  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
   checkresults(L, nargs, nresults);
   if (errfunc == 0)
     func = 0;
   else {
     StkId o = index2addr(L, errfunc);
-    api_checkstackindex(errfunc, o);
+    api_checkstackindex(L, errfunc, o);
     func = savestack(L, o);
   }
   c.func = L->top - (nargs+1);  /* function to be called */

@@ -1096,7 +1101,7 @@
   int more;
   lua_lock(L);
   t = index2addr(L, idx);
-  api_check(ttistable(t), "table expected");
+  api_check(L, ttistable(t), "table expected");
   more = luaH_next(L, hvalue(t), L->top - 1);
   if (more) {
     api_incr_top(L);

@@ -1228,9 +1233,9 @@
 static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
   LClosure *f;
   StkId fi = index2addr(L, fidx);
-  api_check(ttisLclosure(fi), "Lua function expected");
+  api_check(L, ttisLclosure(fi), "Lua function expected");
   f = clLvalue(fi);
-  api_check((1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
+  api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
   if (pf) *pf = f;
   return &f->upvals[n - 1];  /* get its upvalue pointer */
 }

@@ -1244,11 +1249,11 @@
     }
     case LUA_TCCL: {  /* C closure */
       CClosure *f = clCvalue(fi);
-      api_check(1 <= n && n <= f->nupvalues, "invalid upvalue index");
+      api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
       return &f->upvalue[n - 1];
     }
     default: {
-      api_check(0, "closure expected");
+      api_check(L, 0, "closure expected");
       return NULL;
     }
   }

src/lapi.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.h,v 2.8 2014/07/15 21:26:50 roberto Exp $
+** $Id: lapi.h,v 2.9 2015/03/06 19:49: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->top <= L->ci->top, \
+#define api_incr_top(L)   {L->top++; api_check(L, L->top <= L->ci->top, \
 				"stack overflow");}
 
 #define adjustresults(L,nres) \
     { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
 
-#define api_checknelems(L,n)	api_check((n) < (L->top - L->ci->func), \
+#define api_checknelems(L,n)	api_check(L, (n) < (L->top - L->ci->func), \
 				  "not enough elements in the stack")
 
 

src/lauxlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.c,v 1.279 2014/12/14 18:32:26 roberto Exp $
+** $Id: lauxlib.c,v 1.280 2015/02/03 17:38:24 roberto Exp $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */

@@ -286,7 +286,7 @@
 */
 
 LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
-  if (luaL_getmetatable(L, tname))  /* name already in use? */
+  if (luaL_getmetatable(L, tname) != LUA_TNIL)  /* name already in use? */
     return 0;  /* leave previous value on top, but return 0 */
   lua_pop(L, 1);
   lua_newtable(L);  /* create metatable */

src/lbaselib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbaselib.c,v 1.309 2014/12/10 12:26:42 roberto Exp $
+** $Id: lbaselib.c,v 1.310 2015/03/28 19:14:47 roberto Exp $
 ** Basic library
 ** See Copyright Notice in lua.h
 */

@@ -55,7 +55,7 @@
     return NULL;
   do {
     int digit = (isdigit((unsigned char)*s)) ? *s - '0'
-                   : toupper((unsigned char)*s) - 'A' + 10;
+                   : (toupper((unsigned char)*s) - 'A') + 10;
     if (digit >= base) return NULL;  /* invalid numeral */
     n = n * base + digit;
     s++;

src/lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 2.99 2014/12/29 16:49:25 roberto Exp $
+** $Id: lcode.c,v 2.101 2015/04/29 18:24:11 roberto Exp $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */

@@ -29,8 +29,8 @@
 #include "lvm.h"
 
 
-/* Maximum number of registers in a Lua function */
-#define MAXREGS		250
+/* Maximum number of registers in a Lua function (must fit in 8 bits) */
+#define MAXREGS		255
 
 
 #define hasjumps(e)	((e)->t != (e)->f)

@@ -279,7 +279,8 @@
   int newstack = fs->freereg + n;
   if (newstack > fs->f->maxstacksize) {
     if (newstack >= MAXREGS)
-      luaX_syntaxerror(fs->ls, "function or expression too complex");
+      luaX_syntaxerror(fs->ls,
+        "function or expression needs too many registers");
     fs->f->maxstacksize = cast_byte(newstack);
   }
 }

@@ -573,8 +574,8 @@
     case VKFLT: {
       e->u.info = luaK_numberK(fs, e->u.nval);
       e->k = VK;
-      /* go through */
     }
+    /* FALLTHROUGH */
     case VK: {
      vk:
       if (e->u.info <= MAXINDEXRK)  /* constant fits in 'argC'? */

@@ -793,7 +794,7 @@
 static void codeexpval (FuncState *fs, OpCode op,
                         expdesc *e1, expdesc *e2, int line) {
   lua_assert(op >= OP_ADD);
-  if (op <= OP_BNOT && constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2))
+  if (op <= OP_BNOT && constfolding(fs, (op - OP_ADD) + LUA_OPADD, e1, e2))
     return;  /* result has been folded */
   else {
     int o1, o2;

@@ -920,11 +921,11 @@
       break;
     }
     case OPR_EQ: case OPR_LT: case OPR_LE: {
-      codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
+      codecomp(fs, cast(OpCode, (op - OPR_EQ) + OP_EQ), 1, e1, e2);
       break;
     }
     case OPR_NE: case OPR_GT: case OPR_GE: {
-      codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
+      codecomp(fs, cast(OpCode, (op - OPR_NE) + OP_EQ), 0, e1, e2);
       break;
     }
     default: lua_assert(0);

src/ldblib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldblib.c,v 1.148 2015/01/02 12:52:22 roberto Exp $
+** $Id: ldblib.c,v 1.149 2015/02/19 17:06:21 roberto Exp $
 ** Interface from Lua to its debug API
 ** See Copyright Notice in lua.h
 */

@@ -27,6 +27,17 @@
 static const int HOOKKEY = 0;
 
 
+/*
+** If L1 != L, L1 can be in any state, and therefore there is no
+** garanties about its stack space; any push in L1 must be
+** checked.
+*/
+static void checkstack (lua_State *L, lua_State *L1, int n) {
+  if (L != L1 && !lua_checkstack(L1, n))
+    luaL_error(L, "stack overflow");
+}
+
+
 static int db_getregistry (lua_State *L) {
   lua_pushvalue(L, LUA_REGISTRYINDEX);
   return 1;

@@ -127,12 +138,16 @@
 
 /*
 ** Calls 'lua_getinfo' and collects all results in a new table.
+** L1 needs stack space for an optional input (function) plus
+** two optional outputs (function and line table) from function
+** 'lua_getinfo'.
 */
 static int db_getinfo (lua_State *L) {
   lua_Debug ar;
   int arg;
   lua_State *L1 = getthread(L, &arg);
   const char *options = luaL_optstring(L, arg+2, "flnStu");
+  checkstack(L, L1, 3);
   if (lua_isfunction(L, arg + 1)) {  /* info about a function? */
     options = lua_pushfstring(L, ">%s", options);  /* add '>' to 'options' */
     lua_pushvalue(L, arg + 1);  /* move function to 'L1' stack */

@@ -190,6 +205,7 @@
     int level = (int)luaL_checkinteger(L, arg + 1);
     if (!lua_getstack(L1, level, &ar))  /* out of range? */
       return luaL_argerror(L, arg+1, "level out of range");
+    checkstack(L, L1, 1);
     name = lua_getlocal(L1, &ar, nvar);
     if (name) {
       lua_xmove(L1, L, 1);  /* move local value */

@@ -216,6 +232,7 @@
     return luaL_argerror(L, arg+1, "level out of range");
   luaL_checkany(L, arg+3);
   lua_settop(L, arg+3);
+  checkstack(L, L1, 1);
   lua_xmove(L, L1, 1);
   name = lua_setlocal(L1, &ar, nvar);
   if (name == NULL)

@@ -350,6 +367,7 @@
     lua_pushvalue(L, -1);
     lua_setmetatable(L, -2);  /* setmetatable(hooktable) = hooktable */
   }
+  checkstack(L, L1, 1);
   lua_pushthread(L1); lua_xmove(L1, L, 1);  /* key (thread) */
   lua_pushvalue(L, arg + 1);  /* value (hook function) */
   lua_rawset(L, -3);  /* hooktable[L1] = new Lua hook */

@@ -370,6 +388,7 @@
     lua_pushliteral(L, "external hook");
   else {  /* hook table must exist */
     lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
+    checkstack(L, L1, 1);
     lua_pushthread(L1); lua_xmove(L1, L, 1);
     lua_rawget(L, -2);   /* 1st result = hooktable[L1] */
     lua_remove(L, -2);  /* remove hook table */

src/ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.110 2015/01/02 12:52:22 roberto Exp $
+** $Id: ldebug.c,v 2.115 2015/05/22 17:45:56 roberto Exp $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */

@@ -34,6 +34,10 @@
 #define noLuaClosure(f)		((f) == NULL || (f)->c.tt == LUA_TCCL)
 
 
+/* Active Lua function (given call info) */
+#define ci_func(ci)		(clLvalue((ci)->func))
+
+
 static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
 
 

@@ -49,6 +53,22 @@
 
 
 /*
+** If function yielded, its 'func' can be in the 'extra' field. The
+** next function restores 'func' to its correct value for debugging
+** purposes. (It exchanges 'func' and 'extra'; so, when called again,
+** after debugging, it also "re-restores" ** 'func' to its altered value.
+*/
+static void swapextra (lua_State *L) {
+  if (L->status == LUA_YIELD) {
+    CallInfo *ci = L->ci;  /* get function that yielded */
+    StkId temp = ci->func;  /* exchange its 'func' and 'extra' values */
+    ci->func = restorestack(L, ci->extra);
+    ci->extra = savestack(L, temp);
+  }
+}
+
+
+/*
 ** this function can be called asynchronous (e.g. during a signal)
 */
 LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {

@@ -106,7 +126,7 @@
 
 static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
   int nparams = clLvalue(ci->func)->p->numparams;
-  if (n >= ci->u.l.base - ci->func - nparams)
+  if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
     return NULL;  /* no such vararg */
   else {
     *pos = ci->func + nparams + n;

@@ -144,6 +164,7 @@
 LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
   const char *name;
   lua_lock(L);
+  swapextra(L);
   if (ar == NULL) {  /* information about non-active function? */
     if (!isLfunction(L->top - 1))  /* not a Lua function? */
       name = NULL;

@@ -151,26 +172,30 @@
       name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
   }
   else {  /* active function; get information through 'ar' */
-    StkId pos = 0;  /* to avoid warnings */
+    StkId pos = NULL;  /* to avoid warnings */
     name = findlocal(L, ar->i_ci, n, &pos);
     if (name) {
       setobj2s(L, L->top, pos);
       api_incr_top(L);
     }
   }
+  swapextra(L);
   lua_unlock(L);
   return name;
 }
 
 
 LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
-  StkId pos = 0;  /* to avoid warnings */
-  const char *name = findlocal(L, ar->i_ci, n, &pos);
+  StkId pos = NULL;  /* to avoid warnings */
+  const char *name;
   lua_lock(L);
+  swapextra(L);
+  name = findlocal(L, ar->i_ci, n, &pos);
   if (name) {
     setobjs2s(L, pos, L->top - 1);
     L->top--;  /* pop value */
   }
+  swapextra(L);
   lua_unlock(L);
   return name;
 }

@@ -270,10 +295,11 @@
   CallInfo *ci;
   StkId func;
   lua_lock(L);
+  swapextra(L);
   if (*what == '>') {
     ci = NULL;
     func = L->top - 1;
-    api_check(ttisfunction(func), "function expected");
+    api_check(L, ttisfunction(func), "function expected");
     what++;  /* skip the '>' */
     L->top--;  /* pop function */
   }

@@ -288,6 +314,7 @@
     setobjs2s(L, L->top, func);
     api_incr_top(L);
   }
+  swapextra(L);  /* correct before option 'L', which can raise a mem. error */
   if (strchr(what, 'L'))
     collectvalidlines(L, cl);
   lua_unlock(L);

@@ -572,19 +599,16 @@
 }
 
 
-static void addinfo (lua_State *L, const char *msg) {
-  CallInfo *ci = L->ci;
-  if (isLua(ci)) {  /* is Lua code? */
-    char buff[LUA_IDSIZE];  /* add file:line information */
-    int line = currentline(ci);
-    TString *src = ci_func(ci)->p->source;
-    if (src)
-      luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
-    else {  /* no source available; use "?" instead */
-      buff[0] = '?'; buff[1] = '\0';
-    }
-    luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
+/* add src:line information to 'msg' */
+const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
+                                        int line) {
+  char buff[LUA_IDSIZE];
+  if (src)
+    luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
+  else {  /* no source available; use "?" instead */
+    buff[0] = '?'; buff[1] = '\0';
   }
+  return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
 }
 
 

@@ -601,10 +625,14 @@
 
 
 l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
+  CallInfo *ci = L->ci;
+  const char *msg;
   va_list argp;
   va_start(argp, fmt);
-  addinfo(L, luaO_pushvfstring(L, fmt, argp));
+  msg = luaO_pushvfstring(L, fmt, argp);  /* format message */
   va_end(argp);
+  if (isLua(ci))  /* if Lua function, add source:line information */
+    luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
   luaG_errormsg(L);
 }
 

src/ldebug.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.h,v 2.12 2014/11/10 14:46:05 roberto Exp $
+** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $
 ** Auxiliary functions from Debug Interface module
 ** See Copyright Notice in lua.h
 */

@@ -17,9 +17,6 @@
 
 #define resethookcount(L)	(L->hookcount = L->basehookcount)
 
-/* Active Lua function (given call info) */
-#define ci_func(ci)		(clLvalue((ci)->func))
-
 
 LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
                                                 const char *opname);

@@ -33,6 +30,8 @@
 LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
                                                  const TValue *p2);
 LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
+LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
+                                                  TString *src, int line);
 LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
 LUAI_FUNC void luaG_traceexec (lua_State *L);
 

src/ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.135 2014/11/11 17:13:39 roberto Exp $
+** $Id: ldo.c,v 2.138 2015/05/22 17:48:19 roberto Exp $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */

@@ -323,6 +323,7 @@
     case LUA_TCCL: {  /* C closure */
       f = clCvalue(func)->f;
      Cfunc:
+      luaC_checkGC(L);  /* stack grow uses memory */
       luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
       ci = next_ci(L);  /* now 'enter' new function */
       ci->nresults = nresults;

@@ -330,20 +331,20 @@
       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);
       n = (*f)(L);  /* do the actual call */
       lua_lock(L);
       api_checknelems(L, n);
-      luaD_poscall(L, L->top - n);
+      luaD_poscall(L, L->top - n, n);
       return 1;
     }
     case LUA_TLCL: {  /* Lua function: prepare its call */
       StkId base;
       Proto *p = clLvalue(func)->p;
       n = cast_int(L->top - func) - 1;  /* number of real arguments */
+      luaC_checkGC(L);  /* stack grow uses memory */
       luaD_checkstack(L, p->maxstacksize);
       for (; n < p->numparams; n++)
         setnilvalue(L->top++);  /* complete missing arguments */

@@ -364,7 +365,6 @@
       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;

@@ -379,7 +379,7 @@
 }
 
 
-int luaD_poscall (lua_State *L, StkId firstResult) {
+int luaD_poscall (lua_State *L, StkId firstResult, int nres) {
   StkId res;
   int wanted, i;
   CallInfo *ci = L->ci;

@@ -393,9 +393,9 @@
   }
   res = ci->func;  /* res == final position of 1st result */
   wanted = ci->nresults;
-  L->ci = ci = ci->previous;  /* back to caller */
+  L->ci = ci->previous;  /* back to caller */
   /* move results to correct place */
-  for (i = wanted; i != 0 && firstResult < L->top; i--)
+  for (i = wanted; i != 0 && nres-- > 0; i--)
     setobjs2s(L, res++, firstResult++);
   while (i-- > 0)
     setnilvalue(res++);

@@ -449,7 +449,7 @@
   lua_lock(L);
   api_checknelems(L, n);
   /* finish 'luaD_precall' */
-  luaD_poscall(L, L->top - n);
+  luaD_poscall(L, L->top - n, n);
 }
 
 

@@ -533,7 +533,8 @@
 */
 static void resume (lua_State *L, void *ud) {
   int nCcalls = L->nCcalls;
-  StkId firstArg = cast(StkId, ud);
+  int n = *(cast(int*, ud));  /* number of arguments */
+  StkId firstArg = L->top - n;  /* first argument */
   CallInfo *ci = L->ci;
   if (nCcalls >= LUAI_MAXCCALLS)
     resume_error(L, "C stack overflow", firstArg);

@@ -553,14 +554,13 @@
       luaV_execute(L);  /* just continue running Lua code */
     else {  /* 'common' yield */
       if (ci->u.c.k != NULL) {  /* does it have a continuation function? */
-        int n;
         lua_unlock(L);
         n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
         lua_lock(L);
         api_checknelems(L, n);
         firstArg = L->top - n;  /* yield results come from continuation */
       }
-      luaD_poscall(L, firstArg);  /* finish 'luaD_precall' */
+      luaD_poscall(L, firstArg, n);  /* finish 'luaD_precall' */
     }
     unroll(L, NULL);  /* run continuation */
   }

@@ -576,7 +576,7 @@
   L->nCcalls = (from) ? from->nCcalls + 1 : 1;
   L->nny = 0;  /* allow yields */
   api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
-  status = luaD_rawrunprotected(L, resume, L->top - nargs);
+  status = luaD_rawrunprotected(L, resume, &nargs);
   if (status == -1)  /* error calling 'lua_resume'? */
     status = LUA_ERRRUN;
   else {  /* continue running after recoverable errors */

@@ -619,7 +619,7 @@
   L->status = LUA_YIELD;
   ci->extra = savestack(L, ci->func);  /* save current 'func' */
   if (isLua(ci)) {  /* inside a hook? */
-    api_check(k == NULL, "hooks cannot continue after yielding");
+    api_check(L, k == NULL, "hooks cannot continue after yielding");
   }
   else {
     if ((ci->u.c.k = k) != NULL)  /* is there a continuation? */

src/ldo.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 2.21 2014/10/25 11:50:46 roberto Exp $
+** $Id: ldo.h,v 2.22 2015/05/22 17:48:19 roberto Exp $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */

@@ -34,7 +34,7 @@
                                         int allowyield);
 LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
                                         ptrdiff_t oldtop, ptrdiff_t ef);
-LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
+LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult, int nres);
 LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
 LUAI_FUNC void luaD_growstack (lua_State *L, int n);
 LUAI_FUNC void luaD_shrinkstack (lua_State *L);

src/ldump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldump.c,v 2.34 2014/11/02 19:19:04 roberto Exp $
+** $Id: ldump.c,v 2.36 2015/03/30 15:43:51 roberto Exp $
 ** save precompiled Lua chunks
 ** See Copyright Notice in lua.h
 */

@@ -74,14 +74,15 @@
   if (s == NULL)
     DumpByte(0, D);
   else {
-    size_t size = s->len + 1;  /* include trailing '\0' */
+    size_t size = tsslen(s) + 1;  /* include trailing '\0' */
+    const char *str = getstr(s);
     if (size < 0xFF)
       DumpByte(cast_int(size), D);
     else {
       DumpByte(0xFF, D);
       DumpVar(size, D);
     }
-    DumpVector(getstr(s), size - 1, D);  /* no need to save '\0' */
+    DumpVector(str, size - 1, D);  /* no need to save '\0' */
   }
 }
 

src/lfunc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.h,v 2.14 2014/06/19 18:27:20 roberto Exp $
+** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */

@@ -23,6 +23,13 @@
 
 
 /*
+** maximum number of upvalues in a closure (both C and Lua). (Value
+** must fit in a VM register.)
+*/
+#define MAXUPVAL	255
+
+
+/*
 ** Upvalues for Lua closures
 */
 struct UpVal {

src/lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.201 2014/12/20 13:58:15 roberto Exp $
+** $Id: lgc.c,v 2.205 2015/03/25 13:42:19 roberto Exp $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */

@@ -83,8 +83,13 @@
 #define markvalue(g,o) { checkconsistency(o); \
   if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
 
-#define markobject(g,t) \
-  { if ((t) && iswhite(t)) reallymarkobject(g, obj2gco(t)); }
+#define markobject(g,t)	{ if (iswhite(t)) reallymarkobject(g, obj2gco(t)); }
+
+/*
+** mark an object that can be NULL (either because it is really optional,
+** or it was stripped as debug info, or inside an uncompleted structure)
+*/
+#define markobjectN(g,t)	{ if (t) markobject(g,t); }
 
 static void reallymarkobject (global_State *g, GCObject *o);
 

@@ -226,15 +231,19 @@
  reentry:
   white2gray(o);
   switch (o->tt) {
-    case LUA_TSHRSTR:
+    case LUA_TSHRSTR: {
+      gray2black(o);
+      g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
+      break;
+    }
     case LUA_TLNGSTR: {
       gray2black(o);
-      g->GCmemtrav += sizestring(gco2ts(o));
+      g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
       break;
     }
     case LUA_TUSERDATA: {
       TValue uvalue;
-      markobject(g, gco2u(o)->metatable);  /* mark its metatable */
+      markobjectN(g, gco2u(o)->metatable);  /* mark its metatable */
       gray2black(o);
       g->GCmemtrav += sizeudata(gco2u(o));
       getuservalue(g->mainthread, gco2u(o), &uvalue);

@@ -275,7 +284,7 @@
 static void markmt (global_State *g) {
   int i;
   for (i=0; i < LUA_NUMTAGS; i++)
-    markobject(g, g->mt[i]);
+    markobjectN(g, g->mt[i]);
 }
 
 

@@ -437,7 +446,7 @@
 static lu_mem traversetable (global_State *g, Table *h) {
   const char *weakkey, *weakvalue;
   const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
-  markobject(g, h->metatable);
+  markobjectN(g, h->metatable);
   if (mode && ttisstring(mode) &&  /* is there a weak mode? */
       ((weakkey = strchr(svalue(mode), 'k')),
        (weakvalue = strchr(svalue(mode), 'v')),

@@ -457,19 +466,24 @@
 }
 
 
+/*
+** Traverse a prototype. (While a prototype is being build, its
+** arrays can be larger than needed; the extra slots are filled with
+** NULL, so the use of 'markobjectN')
+*/
 static int traverseproto (global_State *g, Proto *f) {
   int i;
   if (f->cache && iswhite(f->cache))
     f->cache = NULL;  /* allow cache to be collected */
-  markobject(g, f->source);
+  markobjectN(g, f->source);
   for (i = 0; i < f->sizek; i++)  /* mark literals */
     markvalue(g, &f->k[i]);
   for (i = 0; i < f->sizeupvalues; i++)  /* mark upvalue names */
-    markobject(g, f->upvalues[i].name);
+    markobjectN(g, f->upvalues[i].name);
   for (i = 0; i < f->sizep; i++)  /* mark nested protos */
-    markobject(g, f->p[i]);
+    markobjectN(g, f->p[i]);
   for (i = 0; i < f->sizelocvars; i++)  /* mark local-variable names */
-    markobject(g, f->locvars[i].varname);
+    markobjectN(g, f->locvars[i].varname);
   return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
                          sizeof(Proto *) * f->sizep +
                          sizeof(TValue) * f->sizek +

@@ -494,7 +508,7 @@
 */
 static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
   int i;
-  markobject(g, cl->p);  /* mark its prototype */
+  markobjectN(g, cl->p);  /* mark its prototype */
   for (i = 0; i < cl->nupvalues; i++) {  /* mark its upvalues */
     UpVal *uv = cl->upvals[i];
     if (uv != NULL) {

@@ -689,9 +703,10 @@
     case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
     case LUA_TSHRSTR:
       luaS_remove(L, gco2ts(o));  /* remove it from hash table */
-      /* go through */
+      luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
+      break;
     case LUA_TLNGSTR: {
-      luaM_freemem(L, o, sizestring(gco2ts(o)));
+      luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
       break;
     }
     default: lua_assert(0);

@@ -1002,6 +1017,7 @@
   /* clear values from resurrected weak tables */
   clearvalues(g, g->weak, origweak);
   clearvalues(g, g->allweak, origall);
+  luaS_clearcache(g);
   g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
   work += g->GCmemtrav;  /* complete counting */
   return work;  /* estimate of memory marked by 'atomic' */

src/liolib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: liolib.c,v 2.142 2015/01/02 12:50:28 roberto Exp $
+** $Id: liolib.c,v 2.144 2015/04/03 18:41:57 roberto Exp $
 ** Standard I/O (and system) library
 ** See Copyright Notice in lua.h
 */

@@ -410,12 +410,6 @@
 }
 
 
-/* access to locale "radix character" (decimal point) */
-#if !defined(l_getlocaledecpoint)
-#define l_getlocaledecpoint()     (localeconv()->decimal_point[0])
-#endif
-
-
 /*
 ** Read a number: first reads a valid prefix of a numeral into a buffer.
 ** Then it calls 'lua_stringtonumber' to check whether the format is

@@ -425,9 +419,10 @@
   RN rn;
   int count = 0;
   int hex = 0;
-  char decp[2] = ".";
+  char decp[2];
   rn.f = f; rn.n = 0;
-  decp[0] = l_getlocaledecpoint();  /* get decimal point from locale */
+  decp[0] = lua_getlocaledecpoint();  /* get decimal point from locale */
+  decp[1] = '\0';
   l_lockfile(rn.f);
   do { rn.c = l_getc(rn.f); } while (isspace(rn.c));  /* skip spaces */
   test2(&rn, "-+");  /* optional signal */

@@ -457,7 +452,7 @@
 static int test_eof (lua_State *L, FILE *f) {
   int c = getc(f);
   ungetc(c, f);  /* no-op when c == EOF */
-  lua_pushlstring(L, NULL, 0);
+  lua_pushliteral(L, "");
   return (c != EOF);
 }
 

src/llex.c

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.c,v 2.89 2014/11/14 16:06:09 roberto Exp $
+** $Id: llex.c,v 2.93 2015/05/22 17:45:56 roberto Exp $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */

@@ -16,6 +16,7 @@
 #include "lua.h"
 
 #include "lctype.h"
+#include "ldebug.h"
 #include "ldo.h"
 #include "lgc.h"
 #include "llex.h"

@@ -68,7 +69,7 @@
 
 void luaX_init (lua_State *L) {
   int i;
-  TString *e = luaS_new(L, LUA_ENV);  /* create env name */
+  TString *e = luaS_newliteral(L, LUA_ENV);  /* create env name */
   luaC_fix(L, obj2gco(e));  /* never collect this name */
   for (i=0; i<NUM_RESERVED; i++) {
     TString *ts = luaS_new(L, luaX_tokens[i]);

@@ -106,9 +107,7 @@
 
 
 static l_noret lexerror (LexState *ls, const char *msg, int token) {
-  char buff[LUA_IDSIZE];
-  luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
-  msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
+  msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber);
   if (token)
     luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
   luaD_throw(ls->L, LUA_ERRSYNTAX);

@@ -172,7 +171,7 @@
   ls->linenumber = 1;
   ls->lastline = 1;
   ls->source = source;
-  ls->envn = luaS_new(L, LUA_ENV);  /* get env name */
+  ls->envn = luaS_newliteral(L, LUA_ENV);  /* get env name */
   luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
 }
 

@@ -221,11 +220,6 @@
 }
 
 
-#if !defined(l_getlocaledecpoint)
-#define l_getlocaledecpoint()	(localeconv()->decimal_point[0])
-#endif
-
-
 #define buff2num(b,o)	(luaO_str2num(luaZ_buffer(b), o) != 0)
 
 /*

@@ -234,7 +228,7 @@
 */
 static void trydecpoint (LexState *ls, TValue *o) {
   char old = ls->decpoint;
-  ls->decpoint = l_getlocaledecpoint();
+  ls->decpoint = lua_getlocaledecpoint();
   buffreplace(ls, old, ls->decpoint);  /* try new decimal separator */
   if (!buff2num(ls->buff, o)) {
     /* format error with correct decimal point: no more options */

@@ -283,8 +277,9 @@
 
 
 /*
-** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
-** -1 if sequence is malformed
+** skip a sequence '[=*[' or ']=*]'; if sequence is wellformed, return
+** its number of '='s; otherwise, return a negative number (-1 iff there
+** are no '='s after initial bracket)
 */
 static int skip_sep (LexState *ls) {
   int count = 0;

@@ -501,8 +496,9 @@
           read_long_string(ls, seminfo, sep);
           return TK_STRING;
         }
-        else if (sep == -1) return '[';
-        else lexerror(ls, "invalid long string delimiter", TK_STRING);
+        else if (sep != -1)  /* '[=...' missing second bracket */
+          lexerror(ls, "invalid long string delimiter", TK_STRING);
+        return '[';
       }
       case '=': {
         next(ls);

src/llimits.h

@@ -1,5 +1,5 @@
 /*
-** $Id: llimits.h,v 1.125 2014/12/19 13:30:23 roberto Exp $
+** $Id: llimits.h,v 1.135 2015/06/09 14:21:00 roberto Exp $
 ** Limits, basic types, and some other 'installation-dependent' definitions
 ** See Copyright Notice in lua.h
 */

@@ -52,11 +52,11 @@
 
 
 /*
-** conversion of pointer to integer:
+** conversion of pointer to unsigned integer:
 ** this is for hashing only; there is no problem if the integer
 ** cannot hold the whole pointer value
 */
-#define point2int(p)	((unsigned int)((size_t)(p) & UINT_MAX))
+#define point2uint(p)	((unsigned int)((size_t)(p) & UINT_MAX))
 
 
 

@@ -88,22 +88,20 @@
 /*
 ** assertion for checking API calls
 */
-#if defined(LUA_USE_APICHECK)
-#include <assert.h>
-#define luai_apicheck(e)	assert(e)
-#else
-#define luai_apicheck(e)	lua_assert(e)
+#if !defined(luai_apicheck)
+#define luai_apicheck(l,e)	lua_assert(e)
 #endif
 
-
-#define api_check(e,msg)	luai_apicheck((e) && msg)
+#define api_check(l,e,msg)	luai_apicheck(l,(e) && msg)
 
 
+/* macro to avoid warnings about unused variables */
 #if !defined(UNUSED)
-#define UNUSED(x)	((void)(x))	/* to avoid warnings */
+#define UNUSED(x)	((void)(x))
 #endif
 
 
+/* type casts (a macro highlights casts in the code) */
 #define cast(t, exp)	((t)(exp))
 
 #define cast_void(i)	cast(void, (i))

@@ -149,11 +147,6 @@
 #define LUAI_MAXCCALLS		200
 #endif
 
-/*
-** maximum number of upvalues in a closure (both C and Lua). (Value
-** must fit in an unsigned char.)
-*/
-#define MAXUPVAL	UCHAR_MAX
 
 
 /*

@@ -168,10 +161,33 @@
 
 
 
+/*
+** Maximum length for short strings, that is, strings that are
+** internalized. (Cannot be smaller than reserved words or tags for
+** metamethods, as these strings must be internalized;
+** #("function") = 8, #("__newindex") = 10.)
+*/
+#if !defined(LUAI_MAXSHORTLEN)
+#define LUAI_MAXSHORTLEN	40
+#endif
+
 
-/* minimum size for the string table (must be power of 2) */
+/*
+** Initial size for the string table (must be power of 2).
+** The Lua core alone registers ~50 strings (reserved words +
+** metaevent keys + a few others). Libraries would typically add
+** a few dozens more.
+*/
 #if !defined(MINSTRTABSIZE)
-#define MINSTRTABSIZE	64	/* minimum size for "predefined" strings */
+#define MINSTRTABSIZE	128
+#endif
+
+
+/*
+** Size of cache for strings in the API (better be a prime)
+*/
+#if !defined(STRCACHE_SIZE)
+#define STRCACHE_SIZE		127
 #endif
 
 

@@ -181,11 +197,19 @@
 #endif
 
 
+/*
+** macros that are executed whenether program enters the Lua core
+** ('lua_lock') and leaves the core ('lua_unlock')
+*/
 #if !defined(lua_lock)
 #define lua_lock(L)	((void) 0)
 #define lua_unlock(L)	((void) 0)
 #endif
 
+/*
+** macro executed during Lua functions at points where the
+** function can yield.
+*/
 #if !defined(luai_threadyield)
 #define luai_threadyield(L)	{lua_unlock(L); lua_lock(L);}
 #endif

@@ -223,6 +247,53 @@
 
 
 /*
+** The luai_num* macros define the primitive operations over numbers.
+*/
+
+/* floor division (defined as 'floor(a/b)') */
+#if !defined(luai_numidiv)
+#define luai_numidiv(L,a,b)     ((void)L, l_floor(luai_numdiv(L,a,b)))
+#endif
+
+/* float division */
+#if !defined(luai_numdiv)
+#define luai_numdiv(L,a,b)      ((a)/(b))
+#endif
+
+/*
+** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when
+** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of
+** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b)
+** ~= floor(a/b)'. That happens when the division has a non-integer
+** negative result, which is equivalent to the test below.
+*/
+#if !defined(luai_nummod)
+#define luai_nummod(L,a,b,m)  \
+  { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
+#endif
+
+/* exponentiation */
+#if !defined(luai_numpow)
+#define luai_numpow(L,a,b)      ((void)L, l_mathop(pow)(a,b))
+#endif
+
+/* the others are quite standard operations */
+#if !defined(luai_numadd)
+#define luai_numadd(L,a,b)      ((a)+(b))
+#define luai_numsub(L,a,b)      ((a)-(b))
+#define luai_nummul(L,a,b)      ((a)*(b))
+#define luai_numunm(L,a)        (-(a))
+#define luai_numeq(a,b)         ((a)==(b))
+#define luai_numlt(a,b)         ((a)<(b))
+#define luai_numle(a,b)         ((a)<=(b))
+#define luai_numisnan(a)        (!luai_numeq((a), (a)))
+#endif
+
+
+
+
+
+/*
 ** macro to control inclusion of some hard tests on stack reallocation
 */
 #if !defined(HARDSTACKTESTS)

src/lmathlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lmathlib.c,v 1.114 2014/12/27 20:32:26 roberto Exp $
+** $Id: lmathlib.c,v 1.115 2015/03/12 14:04:04 roberto Exp $
 ** Standard mathematical library
 ** See Copyright Notice in lua.h
 */

@@ -183,6 +183,9 @@
     res = l_mathop(log)(x);
   else {
     lua_Number base = luaL_checknumber(L, 2);
+#if !defined(LUA_USE_C89)
+    if (base == 2.0) res = l_mathop(log2)(x); else
+#endif
     if (base == 10.0) res = l_mathop(log10)(x);
     else res = l_mathop(log)(x)/l_mathop(log)(base);
   }

src/lmem.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lmem.c,v 1.89 2014/11/02 19:33:33 roberto Exp $
+** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $
 ** Interface to Memory Manager
 ** See Copyright Notice in lua.h
 */

@@ -85,10 +85,11 @@
 #endif
   newblock = (*g->frealloc)(g->ud, block, osize, nsize);
   if (newblock == NULL && nsize > 0) {
-    api_check( nsize > realosize,
-                 "realloc cannot fail when shrinking a block");
-    luaC_fullgc(L, 1);  /* try to free some memory... */
-    newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
+    lua_assert(nsize > realosize);  /* cannot fail when shrinking a block */
+    if (g->version) {  /* is state fully built? */
+      luaC_fullgc(L, 1);  /* try to free some memory... */
+      newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
+    }
     if (newblock == NULL)
       luaD_throw(L, LUA_ERRMEM);
   }

src/loadlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: loadlib.c,v 1.124 2015/01/05 13:51:39 roberto Exp $
+** $Id: loadlib.c,v 1.126 2015/02/16 13:14:33 roberto Exp $
 ** Dynamic library loader for Lua
 ** See Copyright Notice in lua.h
 **

@@ -14,6 +14,7 @@
 #include "lprefix.h"
 
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 

@@ -136,8 +137,8 @@
 #include <dlfcn.h>
 
 /*
-** Macro to covert pointer to void* to pointer to function. This cast
-** is undefined according to ISO C, but POSIX assumes that it must work.
+** Macro to convert pointer-to-void* to pointer-to-function. This cast
+** is undefined according to ISO C, but POSIX assumes that it works.
 ** (The '__extension__' in gnu compilers is only to avoid warnings.)
 */
 #if defined(__GNUC__)

src/lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 2.101 2014/12/26 14:43:45 roberto Exp $
+** $Id: lobject.c,v 2.104 2015/04/11 18:30:08 roberto Exp $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */

@@ -10,6 +10,8 @@
 #include "lprefix.h"
 
 
+#include <locale.h>
+#include <math.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>

@@ -39,8 +41,12 @@
 int luaO_int2fb (unsigned int x) {
   int e = 0;  /* exponent */
   if (x < 8) return x;
-  while (x >= 0x10) {
-    x = (x+1) >> 1;
+  while (x >= (8 << 4)) {  /* coarse steps */
+    x = (x + 0xf) >> 4;  /* x = ceil(x / 16) */
+    e += 4;
+  }
+  while (x >= (8 << 1)) {  /* fine steps */
+    x = (x + 1) >> 1;  /* x = ceil(x / 2) */
     e++;
   }
   return ((e+1) << 3) | (cast_int(x) - 8);

@@ -55,8 +61,11 @@
 }
 
 
+/*
+** Computes ceil(log2(x))
+*/
 int luaO_ceillog2 (unsigned int x) {
-  static const lu_byte log_2[256] = {
+  static const lu_byte log_2[256] = {  /* log_2[i] = ceil(log2(i - 1)) */
     0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

@@ -149,13 +158,13 @@
   }
   /* could not perform raw operation; try metamethod */
   lua_assert(L != NULL);  /* should not fail when folding (compile time) */
-  luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
+  luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
 }
 
 
 int luaO_hexavalue (int c) {
   if (lisdigit(c)) return c - '0';
-  else return ltolower(c) - 'a' + 10;
+  else return (ltolower(c) - 'a') + 10;
 }
 
 

@@ -172,9 +181,8 @@
 ** Lua's implementation for 'lua_strx2number'
 ** ===================================================================
 */
-#if !defined(lua_strx2number)
 
-#include <math.h>
+#if !defined(lua_strx2number)
 
 /* maximum number of significant digits to read (to avoid overflows
    even with single floats) */

@@ -185,21 +193,22 @@
 ** C99 specification for 'strtod'
 */
 static lua_Number lua_strx2number (const char *s, char **endptr) {
+  int dot = lua_getlocaledecpoint();
   lua_Number r = 0.0;  /* result (accumulator) */
   int sigdig = 0;  /* number of significant digits */
   int nosigdig = 0;  /* number of non-significant digits */
   int e = 0;  /* exponent correction */
   int neg;  /* 1 if number is negative */
-  int dot = 0;  /* true after seen a dot */
+  int hasdot = 0;  /* true after seen a dot */
   *endptr = cast(char *, s);  /* nothing is valid yet */
   while (lisspace(cast_uchar(*s))) s++;  /* skip initial spaces */
   neg = isneg(&s);  /* check signal */
   if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')))  /* check '0x' */
     return 0.0;  /* invalid format (no '0x') */
   for (s += 2; ; s++) {  /* skip '0x' and read numeral */
-    if (*s == '.') {
-      if (dot) break;  /* second dot? stop loop */
-      else dot = 1;
+    if (*s == dot) {
+      if (hasdot) break;  /* second dot? stop loop */
+      else hasdot = 1;
     }
     else if (lisxdigit(cast_uchar(*s))) {
       if (sigdig == 0 && *s == '0')  /* non-significant digit (zero)? */

@@ -207,7 +216,7 @@
       else if (++sigdig <= MAXSIGDIG)  /* can read it without overflow? */
           r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
       else e++; /* too many digits; ignore, but still count for exponent */
-      if (dot) e--;  /* decimal digit? correct exponent */
+      if (hasdot) e--;  /* decimal digit? correct exponent */
     }
     else break;  /* neither a dot nor a digit */
   }

@@ -244,7 +253,7 @@
     *result = lua_strx2number(s, &endptr);
   else
     *result = lua_str2number(s, &endptr);
-  if (endptr == s) return 0;  /* nothing recognized */
+  if (endptr == s) return NULL;  /* nothing recognized */
   while (lisspace(cast_uchar(*endptr))) endptr++;
   return (*endptr == '\0' ? endptr : NULL);  /* OK if no trailing characters */
 }

@@ -290,7 +299,7 @@
   }
   else
     return 0;  /* conversion failed */
-  return (e - s + 1);  /* success; return string size */
+  return (e - s) + 1;  /* success; return string size */
 }
 
 

@@ -329,7 +338,7 @@
     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++] = lua_getlocaledecpoint();
       buff[len++] = '0';  /* adds '.0' to result */
     }
 #endif

src/lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 2.106 2015/01/05 13:52:37 roberto Exp $
+** $Id: lobject.h,v 2.111 2015/06/09 14:21:42 roberto Exp $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */

@@ -35,8 +35,6 @@
 ** bit 6: whether value is collectable
 */
 
-#define VARBITS		(3 << 4)
-
 
 /*
 ** LUA_TFUNCTION variants:

@@ -190,9 +188,15 @@
 #define setfltvalue(obj,x) \
   { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
 
+#define chgfltvalue(obj,x) \
+  { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); }
+
 #define setivalue(obj,x) \
   { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
 
+#define chgivalue(obj,x) \
+  { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); }
+
 #define setnilvalue(obj) settt_(obj, LUA_TNIL)
 
 #define setfvalue(obj,x) \

@@ -303,9 +307,12 @@
 typedef struct TString {
   CommonHeader;
   lu_byte extra;  /* reserved words for short strings; "has hash" for longs */
+  lu_byte shrlen;  /* length for short strings */
   unsigned int hash;
-  size_t len;  /* number of characters in string */
-  struct TString *hnext;  /* linked list for hash table */
+  union {
+    size_t lnglen;  /* length for long strings */
+    struct TString *hnext;  /* linked list for hash table */
+  } u;
 } TString;
 
 

@@ -329,6 +336,12 @@
 /* get the actual string (array of bytes) from a Lua value */
 #define svalue(o)       getstr(tsvalue(o))
 
+/* get string length from 'TString *s' */
+#define tsslen(s)	((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)
+
+/* get string length from 'TValue *o' */
+#define vslen(o)	tsslen(tsvalue(o))
+
 
 /*
 ** Header for userdata; memory area follows the end of this structure

@@ -361,13 +374,13 @@
 
 #define setuservalue(L,u,o) \
 	{ const TValue *io=(o); Udata *iu = (u); \
-	  iu->user_ = io->value_; iu->ttuv_ = io->tt_; \
+	  iu->user_ = io->value_; iu->ttuv_ = rttype(io); \
 	  checkliveness(G(L),io); }
 
 
 #define getuservalue(L,u,o) \
 	{ TValue *io=(o); const Udata *iu = (u); \
-	  io->value_ = iu->user_; io->tt_ = iu->ttuv_; \
+	  io->value_ = iu->user_; settt_(io, iu->ttuv_); \
 	  checkliveness(G(L),io); }
 
 

@@ -376,7 +389,7 @@
 */
 typedef struct Upvaldesc {
   TString *name;  /* upvalue name (for debug information) */
-  lu_byte instack;  /* whether it is in stack */
+  lu_byte instack;  /* whether it is in stack (register) */
   lu_byte idx;  /* index of upvalue (in stack or in outer function's list) */
 } Upvaldesc;
 

@@ -399,7 +412,7 @@
   CommonHeader;
   lu_byte numparams;  /* number of fixed parameters */
   lu_byte is_vararg;
-  lu_byte maxstacksize;  /* maximum stack used by this function */
+  lu_byte maxstacksize;  /* number of registers needed by this function */
   int sizeupvalues;  /* size of 'upvalues' */
   int sizek;  /* size of 'k' */
   int sizecode;

@@ -409,12 +422,12 @@
   int linedefined;
   int lastlinedefined;
   TValue *k;  /* constants used by the function */
-  Instruction *code;
+  Instruction *code;  /* opcodes */
   struct Proto **p;  /* functions defined inside the function */
   int *lineinfo;  /* map from opcodes to source lines (debug information) */
   LocVar *locvars;  /* information about local variables (debug information) */
   Upvaldesc *upvalues;  /* upvalue information */
-  struct LClosure *cache;  /* last created closure with this prototype */
+  struct LClosure *cache;  /* last-created closure with this prototype */
   TString  *source;  /* used for debug information */
   GCObject *gclist;
 } Proto;

src/loslib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: loslib.c,v 1.54 2014/12/26 14:46:07 roberto Exp $
+** $Id: loslib.c,v 1.57 2015/04/10 17:41:04 roberto Exp $
 ** Standard Operating System library
 ** See Copyright Notice in lua.h
 */

@@ -22,10 +22,12 @@
 #include "lualib.h"
 
 
-#if !defined(LUA_STRFTIMEOPTIONS)	/* { */
 /*
+** {==================================================================
 ** list of valid conversion specifiers for the 'strftime' function
+** ===================================================================
 */
+#if !defined(LUA_STRFTIMEOPTIONS)	/* { */
 
 #if defined(LUA_USE_C89)
 #define LUA_STRFTIMEOPTIONS	{ "aAbBcdHIjmMpSUwWxXyYz%", "" }

@@ -37,8 +39,14 @@
 #endif
 
 #endif					/* } */
+/* }================================================================== */
 
 
+/*
+** {==================================================================
+** Configuration for time-related stuff
+** ===================================================================
+*/
 
 #if !defined(l_time_t)		/* { */
 /*

@@ -51,12 +59,38 @@
 #endif				/* } */
 
 
+#if !defined(l_gmtime)		/* { */
+/*
+** By default, Lua uses gmtime/localtime, except when POSIX is available,
+** where it uses gmtime_r/localtime_r
+*/
+
+#if defined(LUA_USE_POSIX)	/* { */
+
+#define l_gmtime(t,r)		gmtime_r(t,r)
+#define l_localtime(t,r)	localtime_r(t,r)
+
+#else				/* }{ */
+
+/* ISO C definitions */
+#define l_gmtime(t,r)		((void)(r)->tm_sec, gmtime(t))
+#define l_localtime(t,r)  	((void)(r)->tm_sec, localtime(t))
+
+#endif				/* } */
+
+#endif				/* } */
+
+/* }================================================================== */
+
 
-#if !defined(lua_tmpnam)	/* { */
 /*
-** By default, Lua uses tmpnam except when POSIX is available, where it
-** uses mkstemp.
+** {==================================================================
+** Configuration for 'tmpnam':
+** By default, Lua uses tmpnam except when POSIX is available, where
+** it uses mkstemp.
+** ===================================================================
 */
+#if !defined(lua_tmpnam)	/* { */
 
 #if defined(LUA_USE_POSIX)	/* { */
 

@@ -83,31 +117,10 @@
 #endif				/* } */
 
 #endif				/* } */
+/* }================================================================== */
 
 
 
-#if !defined(l_gmtime)		/* { */
-/*
-** By default, Lua uses gmtime/localtime, except when POSIX is available,
-** where it uses gmtime_r/localtime_r
-*/
-
-#if defined(LUA_USE_POSIX)	/* { */
-
-#define l_gmtime(t,r)		gmtime_r(t,r)
-#define l_localtime(t,r)	localtime_r(t,r)
-
-#else				/* }{ */
-
-/* ISO C definitions */
-#define l_gmtime(t,r)		((void)(r)->tm_sec, gmtime(t))
-#define l_localtime(t,r)  	((void)(r)->tm_sec, localtime(t))
-
-#endif				/* } */
-
-#endif				/* } */
-
-
 
 static int os_execute (lua_State *L) {
   const char *cmd = luaL_optstring(L, 1, NULL);

@@ -287,7 +300,7 @@
     t = mktime(&ts);
   }
   if (t != (time_t)(l_timet)t)
-    luaL_error(L, "time result cannot be represented in this Lua instalation");
+    luaL_error(L, "time result cannot be represented in this Lua installation");
   else if (t == (time_t)(-1))
     lua_pushnil(L);
   else

@@ -297,8 +310,9 @@
 
 
 static int os_difftime (lua_State *L) {
-  double res = difftime((l_checktime(L, 1)), (l_checktime(L, 2)));
-  lua_pushnumber(L, (lua_Number)res);
+  time_t t1 = l_checktime(L, 1);
+  time_t t2 = l_checktime(L, 2);
+  lua_pushnumber(L, (lua_Number)difftime(t1, t2));
   return 1;
 }
 

src/lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.127 2014/11/02 19:33:33 roberto Exp $
+** $Id: lstate.c,v 2.128 2015/03/04 13:31:21 roberto Exp $
 ** Global State
 ** See Copyright Notice in lua.h
 */

@@ -37,9 +37,6 @@
 #endif
 
 
-#define MEMERRMSG	"not enough memory"
-
-
 /*
 ** a macro to help the creation of a unique random seed when a state is
 ** created; the seed is used to randomize hashes.

@@ -200,12 +197,9 @@
   UNUSED(ud);
   stack_init(L, L);  /* init stack */
   init_registry(L, g);
-  luaS_resize(L, MINSTRTABSIZE);  /* initial size of string table */
+  luaS_init(L);
   luaT_init(L);
   luaX_init(L);
-  /* pre-create memory-error message */
-  g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
-  luaC_fix(L, obj2gco(g->memerrmsg));  /* it should never be collected */
   g->gcrunning = 1;  /* allow gc */
   g->version = lua_version(NULL);
   luai_userstateopen(L);

src/lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.119 2014/10/30 18:53:28 roberto Exp $
+** $Id: lstate.h,v 2.122 2015/06/01 16:34:37 roberto Exp $
 ** Global State
 ** See Copyright Notice in lua.h
 */

@@ -94,6 +94,7 @@
 #define CIST_YPCALL	(1<<4)	/* call is a yieldable protected call */
 #define CIST_TAIL	(1<<5)	/* call was tail called */
 #define CIST_HOOKYIELD	(1<<6)	/* last hook called yielded */
+#define CIST_LEQ	(1<<7)  /* using __lt for __le */
 
 #define isLua(ci)	((ci)->callstatus & CIST_LUA)
 

@@ -140,6 +141,7 @@
   TString *memerrmsg;  /* memory-error message */
   TString *tmname[TM_N];  /* array with tag-method names */
   struct Table *mt[LUA_NUMTAGS];  /* metatables for basic types */
+  TString *strcache[STRCACHE_SIZE][1];  /* cache for strings in API */
 } global_State;
 
 

src/lstring.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.c,v 2.45 2014/11/02 19:19:04 roberto Exp $
+** $Id: lstring.c,v 2.49 2015/06/01 16:34:37 roberto Exp $
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */

@@ -22,6 +22,8 @@
 #include "lstring.h"
 
 
+#define MEMERRMSG       "not enough memory"
+
 
 /*
 ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to

@@ -36,10 +38,10 @@
 ** equality for long strings
 */
 int luaS_eqlngstr (TString *a, TString *b) {
-  size_t len = a->len;
+  size_t len = a->u.lnglen;
   lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
   return (a == b) ||  /* same instance or... */
-    ((len == b->len) &&  /* equal length and ... */
+    ((len == b->u.lnglen) &&  /* equal length and ... */
      (memcmp(getstr(a), getstr(b), len) == 0));  /* equal contents */
 }
 

@@ -69,9 +71,9 @@
     TString *p = tb->hash[i];
     tb->hash[i] = NULL;
     while (p) {  /* for each node in the list */
-      TString *hnext = p->hnext;  /* save next */
+      TString *hnext = p->u.hnext;  /* save next */
       unsigned int h = lmod(p->hash, newsize);  /* new position */
-      p->hnext = tb->hash[h];  /* chain it */
+      p->u.hnext = tb->hash[h];  /* chain it */
       tb->hash[h] = p;
       p = hnext;
     }

@@ -85,6 +87,34 @@
 }
 
 
+/*
+** Clear API string cache. (Entries cannot be empty, so fill them with
+** a non-collectable string.)
+*/
+void luaS_clearcache (global_State *g) {
+  int i;
+  for (i = 0; i < STRCACHE_SIZE; i++) {
+    if (iswhite(g->strcache[i][0]))  /* will entry be collected? */
+      g->strcache[i][0] = g->memerrmsg;  /* replace it with something fixed */
+  }
+}
+
+
+/*
+** Initialize the string table and the string cache
+*/
+void luaS_init (lua_State *L) {
+  global_State *g = G(L);
+  int i;
+  luaS_resize(L, MINSTRTABSIZE);  /* initial size of string table */
+  /* pre-create memory-error message */
+  g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
+  luaC_fix(L, obj2gco(g->memerrmsg));  /* it should never be collected */
+  for (i = 0; i < STRCACHE_SIZE; i++)  /* fill cache with valid strings */
+    g->strcache[i][0] = g->memerrmsg;
+}
+
+
 
 /*
 ** creates a new string object

@@ -97,7 +127,6 @@
   totalsize = sizelstring(l);
   o = luaC_newobj(L, tag, totalsize);
   ts = gco2ts(o);
-  ts->len = l;
   ts->hash = h;
   ts->extra = 0;
   memcpy(getaddrstr(ts), str, l * sizeof(char));

@@ -110,8 +139,8 @@
   stringtable *tb = &G(L)->strt;
   TString **p = &tb->hash[lmod(ts->hash, tb->size)];
   while (*p != ts)  /* find previous element */
-    p = &(*p)->hnext;
-  *p = (*p)->hnext;  /* remove element from its list */
+    p = &(*p)->u.hnext;
+  *p = (*p)->u.hnext;  /* remove element from its list */
   tb->nuse--;
 }
 

@@ -124,8 +153,8 @@
   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->hnext) {
-    if (l == ts->len &&
+  for (ts = *list; ts != NULL; ts = ts->u.hnext) {
+    if (l == ts->shrlen &&
         (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
       /* found! */
       if (isdead(g, ts))  /* dead (but not collected yet)? */

@@ -138,7 +167,8 @@
     list = &g->strt.hash[lmod(h, g->strt.size)];  /* recompute with new size */
   }
   ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
-  ts->hnext = *list;
+  ts->shrlen = cast_byte(l);
+  ts->u.hnext = *list;
   *list = ts;
   g->strt.nuse++;
   return ts;

@@ -152,18 +182,32 @@
   if (l <= LUAI_MAXSHORTLEN)  /* short string? */
     return internshrstr(L, str, l);
   else {
+    TString *ts;
     if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
       luaM_toobig(L);
-    return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
+    ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
+    ts->u.lnglen = l;
+    return ts;
   }
 }
 
 
 /*
-** new zero-terminated string
+** Create or reuse a zero-terminated string, first checking in the
+** cache (using the string address as a key). The cache can contain
+** only zero-terminated strings, so it is safe to use 'strcmp' to
+** check hits.
 */
 TString *luaS_new (lua_State *L, const char *str) {
-  return luaS_newlstr(L, str, strlen(str));
+  unsigned int i = point2uint(str) % STRCACHE_SIZE;  /* hash */
+  TString **p = G(L)->strcache[i];
+  if (strcmp(str, getstr(p[0])) == 0)  /* hit? */
+    return p[0];  /* that it is */
+  else {  /* normal route */
+    TString *s = luaS_newlstr(L, str, strlen(str));
+    p[0] = s;
+    return s;
+  }
 }
 
 

src/lstring.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.h,v 1.56 2014/07/18 14:46:47 roberto Exp $
+** $Id: lstring.h,v 1.59 2015/03/25 13:42:19 roberto Exp $
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */

@@ -13,7 +13,6 @@
 
 
 #define sizelstring(l)  (sizeof(union UTString) + ((l) + 1) * sizeof(char))
-#define sizestring(s)	sizelstring((s)->len)
 
 #define sizeludata(l)	(sizeof(union UUdata) + (l))
 #define sizeudata(u)	sizeludata((u)->len)

@@ -37,6 +36,8 @@
 LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
 LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
 LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
+LUAI_FUNC void luaS_clearcache (global_State *g);
+LUAI_FUNC void luaS_init (lua_State *L);
 LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
 LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
 LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);

src/lstrlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstrlib.c,v 1.221 2014/12/11 14:03:07 roberto Exp $
+** $Id: lstrlib.c,v 1.229 2015/05/20 17:39:23 roberto Exp $
 ** Standard library for string operations and pattern-matching
 ** See Copyright Notice in lua.h
 */

@@ -11,6 +11,7 @@
 
 
 #include <ctype.h>
+#include <float.h>
 #include <limits.h>
 #include <stddef.h>
 #include <stdio.h>

@@ -70,7 +71,7 @@
   if (start < 1) start = 1;
   if (end > (lua_Integer)l) end = l;
   if (start <= end)
-    lua_pushlstring(L, s + start - 1, (size_t)(end - start + 1));
+    lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1);
   else lua_pushliteral(L, "");
   return 1;
 }

@@ -149,9 +150,9 @@
   if (posi < 1) posi = 1;
   if (pose > (lua_Integer)l) pose = l;
   if (posi > pose) return 0;  /* empty interval; return no values */
-  n = (int)(pose -  posi + 1);
-  if (posi + n <= pose)  /* arithmetic overflow? */
+  if (pose - posi >= INT_MAX)  /* arithmetic overflow? */
     return luaL_error(L, "string slice too long");
+  n = (int)(pose -  posi) + 1;
   luaL_checkstack(L, n, "string slice too long");
   for (i=0; i<n; i++)
     lua_pushinteger(L, uchar(s[posi+i-1]));

@@ -499,7 +500,7 @@
             }
             case '+':  /* 1 or more repetitions */
               s++;  /* 1 match already done */
-              /* go through */
+              /* FALLTHROUGH */
             case '*':  /* 0 or more repetitions */
               s = max_expand(ms, s, p, ep);
               break;

@@ -554,7 +555,7 @@
     ptrdiff_t l = ms->capture[i].len;
     if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
     if (l == CAP_POSITION)
-      lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
+      lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
     else
       lua_pushlstring(ms->L, ms->capture[i].init, l);
   }

@@ -598,8 +599,8 @@
     /* do a plain search */
     const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp);
     if (s2) {
-      lua_pushinteger(L, s2 - s + 1);
-      lua_pushinteger(L, s2 - s + lp);
+      lua_pushinteger(L, (s2 - s) + 1);
+      lua_pushinteger(L, (s2 - s) + lp);
       return 2;
     }
   }

@@ -621,7 +622,7 @@
       lua_assert(ms.matchdepth == MAXCCALLS);
       if ((res=match(&ms, s1, p)) != NULL) {
         if (find) {
-          lua_pushinteger(L, s1 - s + 1);  /* start */
+          lua_pushinteger(L, (s1 - s) + 1);  /* start */
           lua_pushinteger(L, res - s);   /* end */
           return push_captures(&ms, NULL, 0) + 2;
         }

@@ -797,17 +798,100 @@
 ** =======================================================
 */
 
-/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
-#define MAX_ITEM	512
+#if !defined(lua_number2strx)	/* { */
+
+/*
+** Hexadecimal floating-point formatter
+*/
+
+#include <locale.h>
+#include <math.h>
+
+#define SIZELENMOD	(sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
+
+
+/*
+** Number of bits that goes into the first digit. It can be any value
+** between 1 and 4; the following definition tries to align the number
+** to nibble boundaries by making what is left after that first digit a
+** multiple of 4.
+*/
+#define L_NBFD		((l_mathlim(MANT_DIG) - 1)%4 + 1)
+
+
+/*
+** Add integer part of 'x' to buffer and return new 'x'
+*/
+static lua_Number adddigit (char *buff, int n, lua_Number x) {
+  lua_Number dd = l_mathop(floor)(x);  /* get integer part from 'x' */
+  int d = (int)dd;
+  buff[n] = (d < 10 ? d + '0' : d - 10 + 'a');  /* add to buffer */
+  return x - dd;  /* return what is left */
+}
+
+
+static int num2straux (char *buff, lua_Number x) {
+  if (x != x || x == HUGE_VAL || x == -HUGE_VAL)  /* inf or NaN? */
+    return sprintf(buff, LUA_NUMBER_FMT, x);  /* equal to '%g' */
+  else if (x == 0) {  /* can be -0... */
+    sprintf(buff, LUA_NUMBER_FMT, x);
+    strcat(buff, "x0p+0");  /* reuses '0/-0' from 'sprintf'... */
+    return strlen(buff);
+  }
+  else {
+    int e;
+    lua_Number m = l_mathop(frexp)(x, &e);  /* 'x' fraction and exponent */
+    int n = 0;  /* character count */
+    if (m < 0) {  /* is number negative? */
+      buff[n++] = '-';  /* add signal */
+      m = -m;  /* make it positive */
+    }
+    buff[n++] = '0'; buff[n++] = 'x';  /* add "0x" */
+    m = adddigit(buff, n++, m * (1 << L_NBFD));  /* add first digit */
+    e -= L_NBFD;  /* this digit goes before the radix point */
+    if (m > 0) {  /* more digits? */
+      buff[n++] = lua_getlocaledecpoint();  /* add radix point */
+      do {  /* add as many digits as needed */
+        m = adddigit(buff, n++, m * 16);
+      } while (m > 0);
+    }
+    n += sprintf(buff + n, "p%+d", e);  /* add exponent */
+    return n;
+  }
+}
+
+
+static int lua_number2strx (lua_State *L, char *buff, const char *fmt,
+                            lua_Number x) {
+  int n = num2straux(buff, x);
+  if (fmt[SIZELENMOD] == 'A') {
+    int i;
+    for (i = 0; i < n; i++)
+      buff[i] = toupper(uchar(buff[i]));
+  }
+  else if (fmt[SIZELENMOD] != 'a')
+    luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
+  return n;
+}
+
+#endif				/* } */
+
+
+/*
+** Maximum size of each formatted item. This maximum size is produced
+** by format('%.99f', minfloat), and is equal to 99 + 2 ('-' and '.') +
+** number of decimal digits to represent minfloat.
+*/
+#define MAX_ITEM	(120 + l_mathlim(MAX_10_EXP))
+
 
 /* valid flags in a format specification */
 #define FLAGS	"-+ #0"
 
 /*
 ** maximum size of each format specification (such as "%-099.99d")
-** (+2 for length modifiers; +10 accounts for %99.99x plus margin of error)
 */
-#define MAX_FORMAT	(sizeof(FLAGS) + 2 + 10)
+#define MAX_FORMAT	32
 
 
 static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {

@@ -849,8 +933,8 @@
   if (isdigit(uchar(*p)))
     luaL_error(L, "invalid format (width or precision too long)");
   *(form++) = '%';
-  memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char));
-  form += p - strfrmt + 1;
+  memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char));
+  form += (p - strfrmt) + 1;
   *form = '\0';
   return p;
 }

@@ -901,9 +985,10 @@
           nb = sprintf(buff, form, n);
           break;
         }
-#if defined(LUA_USE_AFORMAT)
         case 'a': case 'A':
-#endif
+          addlenmod(form, LUA_NUMBER_FRMLEN);
+          nb = lua_number2strx(L, buff, form, luaL_checknumber(L, arg));
+          break;
         case 'e': case 'E': case 'f':
         case 'g': case 'G': {
           addlenmod(form, LUA_NUMBER_FRMLEN);

@@ -921,13 +1006,12 @@
             /* no precision and string is too long to be formatted;
                keep original string */
             luaL_addvalue(&b);
-            break;
           }
           else {
             nb = sprintf(buff, form, s);
             lua_pop(L, 1);  /* remove result from 'luaL_tolstring' */
-            break;
           }
+          break;
         }
         default: {  /* also treat cases 'pnLlh' */
           return luaL_error(L, "invalid option '%%%c' to 'format'",

@@ -1249,7 +1333,7 @@
         totalsize += len + 1;
         break;
       }
-      case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE);  /* go through */
+      case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE);  /* FALLTHROUGH */
       case Kpaddalign: case Knop:
         arg--;  /* undo increment */
         break;

src/ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 2.100 2015/01/05 13:52:37 roberto Exp $
+** $Id: ltable.c,v 2.111 2015/06/09 14:21:13 roberto Exp $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */

@@ -14,8 +14,8 @@
 ** Implementation of tables (aka arrays, objects, or hash tables).
 ** Tables keep its elements in two parts: an array part and a hash part.
 ** Non-negative integer keys are all candidates to be kept in the array
-** part. The actual size of the array is the largest 'n' such that at
-** least half the slots between 0 and n are in use.
+** part. The actual size of the array is the largest 'n' such that
+** more than half the slots between 1 and n are in use.
 ** Hash uses a mix of chained scatter table with Brent's variation.
 ** A main invariant of these tables is that, if an element is not
 ** in its main position (i.e. the 'original' position that its hash gives

@@ -23,9 +23,7 @@
 ** Hence even when the load factor reaches 100%, performance remains good.
 */
 
-#include <float.h>
 #include <math.h>
-#include <string.h>
 #include <limits.h>
 
 #include "lua.h"

@@ -71,7 +69,7 @@
 #define hashmod(t,n)	(gnode(t, ((n) % ((sizenode(t)-1)|1))))
 
 
-#define hashpointer(t,p)	hashmod(t, point2int(p))
+#define hashpointer(t,p)	hashmod(t, point2uint(p))
 
 
 #define dummynode		(&dummynode_)

@@ -85,31 +83,33 @@
 
 
 /*
-** Checks whether a float has a value representable as a lua_Integer
-** (and does the conversion if so)
+** Hash for floating-point numbers.
+** The main computation should be just
+**     n = frepx(n, &i); return (n * INT_MAX) + i
+** but there are some numerical subtleties.
+** In a two-complement representation, INT_MAX does not has an exact
+** representation as a float, but INT_MIN does; because the absolute
+** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
+** absolute value of the product 'frexp * -INT_MIN' is smaller or equal
+** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when
+** adding 'i'; the use of '~u' (instead of '-u') avoids problems with
+** INT_MIN.
 */
-static int numisinteger (lua_Number x, lua_Integer *p) {
-  if ((x) == l_floor(x))  /* integral value? */
-    return lua_numbertointeger(x, p);  /* try as an integer */
-  else return 0;
-}
-
-
-/*
-** hash for floating-point numbers
-*/
-static Node *hashfloat (const Table *t, lua_Number n) {
+#if !defined(l_hashfloat)
+static int l_hashfloat (lua_Number n) {
   int i;
-  n = l_mathop(frexp)(n, &i) * cast_num(INT_MAX - DBL_MAX_EXP);
-  i += cast_int(n);
-  if (i < 0) {
-    if (cast(unsigned int, i) == 0u - i)  /* use unsigned to avoid overflows */
-      i = 0;  /* handle INT_MIN */
-    i = -i;  /* must be a positive value */
+  lua_Integer ni;
+  n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN);
+  if (!lua_numbertointeger(n, &ni)) {  /* is 'n' inf/-inf/NaN? */
+    lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == HUGE_VAL);
+    return 0;
+  }
+  else {  /* normal case */
+    unsigned int u = cast(unsigned int, i) + cast(unsigned int, ni);
+    return cast_int(u <= cast(unsigned int, INT_MAX) ? u : ~u);
   }
-  return hashmod(t, i);
 }
-
+#endif
 
 
 /*

@@ -121,13 +121,13 @@
     case LUA_TNUMINT:
       return hashint(t, ivalue(key));
     case LUA_TNUMFLT:
-      return hashfloat(t, fltvalue(key));
+      return hashmod(t, l_hashfloat(fltvalue(key)));
     case LUA_TSHRSTR:
       return hashstr(t, tsvalue(key));
     case LUA_TLNGSTR: {
       TString *s = tsvalue(key);
       if (s->extra == 0) {  /* no hash? */
-        s->hash = luaS_hash(getstr(s), s->len, s->hash);
+        s->hash = luaS_hash(getstr(s), s->u.lnglen, s->hash);
         s->extra = 1;  /* now it has its hash */
       }
       return hashstr(t, tsvalue(key));

@@ -219,28 +219,29 @@
 /*
 ** Compute the optimal size for the array part of table 't'. 'nums' is a
 ** "count array" where 'nums[i]' is the number of integers in the table
-** between 2^(i - 1) + 1 and 2^i. Put in '*narray' the optimal size, and
-** return the number of elements that will go to that part.
+** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of
+** integer keys in the table and leaves with the number of keys that
+** will go to the array part; return the optimal size.
 */
-static unsigned int computesizes (unsigned int nums[], unsigned int *narray) {
+static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
   int i;
-  unsigned int twotoi;  /* 2^i */
+  unsigned int twotoi;  /* 2^i (candidate for optimal size) */
   unsigned int a = 0;  /* number of elements smaller than 2^i */
   unsigned int na = 0;  /* number of elements to go to array part */
-  unsigned int n = 0;  /* optimal size for array part */
-  for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
+  unsigned int optimal = 0;  /* optimal size for array part */
+  /* loop while keys can fill more than half of total size */
+  for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) {
     if (nums[i] > 0) {
       a += nums[i];
       if (a > twotoi/2) {  /* more than half elements present? */
-        n = twotoi;  /* optimal size (till now) */
-        na = a;  /* all elements up to 'n' will go to array part */
+        optimal = twotoi;  /* optimal size (till now) */
+        na = a;  /* all elements up to 'optimal' will go to array part */
       }
     }
-    if (a == *narray) break;  /* all elements already counted */
   }
-  *narray = n;
-  lua_assert(*narray/2 <= na && na <= *narray);
-  return na;
+  lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal);
+  *pna = na;
+  return optimal;
 }
 
 

@@ -255,6 +256,11 @@
 }
 
 
+/*
+** Count keys in array part of table 't': Fill 'nums[i]' with
+** number of keys that will go into corresponding slice and return
+** total number of non-nil keys.
+*/
 static unsigned int numusearray (const Table *t, unsigned int *nums) {
   int lg;
   unsigned int ttlg;  /* 2^lg */

@@ -281,8 +287,7 @@
 }
 
 
-static int numusehash (const Table *t, unsigned int *nums,
-                       unsigned int *pnasize) {
+static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
   int totaluse = 0;  /* total number of elements */
   int ause = 0;  /* elements added to 'nums' (can go to array part) */
   int i = sizenode(t);

@@ -293,7 +298,7 @@
       totaluse++;
     }
   }
-  *pnasize += ause;
+  *pna += ause;
   return totaluse;
 }
 

@@ -363,7 +368,7 @@
     }
   }
   if (!isdummy(nold))
-    luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
+    luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */
 }
 
 

@@ -376,21 +381,22 @@
 ** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
 */
 static void rehash (lua_State *L, Table *t, const TValue *ek) {
-  unsigned int nasize, na;
+  unsigned int asize;  /* optimal size for array part */
+  unsigned int na;  /* number of keys in the array part */
   unsigned int nums[MAXABITS + 1];
   int i;
   int totaluse;
   for (i = 0; i <= MAXABITS; i++) nums[i] = 0;  /* reset counts */
-  nasize = numusearray(t, nums);  /* count keys in array part */
-  totaluse = nasize;  /* all those keys are integer keys */
-  totaluse += numusehash(t, nums, &nasize);  /* count keys in hash part */
+  na = numusearray(t, nums);  /* count keys in array part */
+  totaluse = na;  /* all those keys are integer keys */
+  totaluse += numusehash(t, nums, &na);  /* count keys in hash part */
   /* count extra key */
-  nasize += countint(ek, nums);
+  na += countint(ek, nums);
   totaluse++;
   /* compute new size for array part */
-  na = computesizes(nums, &nasize);
+  asize = computesizes(nums, &na);
   /* resize the table to new computed sizes */
-  luaH_resize(L, t, nasize, totaluse - na);
+  luaH_resize(L, t, asize, totaluse - na);
 }
 
 

@@ -443,14 +449,13 @@
   TValue aux;
   if (ttisnil(key)) luaG_runerror(L, "table index is nil");
   else if (ttisfloat(key)) {
-    lua_Number n = fltvalue(key);
     lua_Integer k;
-    if (luai_numisnan(n))
-      luaG_runerror(L, "table index is NaN");
-    if (numisinteger(n, &k)) {  /* index is int? */
+    if (luaV_tointeger(key, &k, 0)) {  /* index is int? */
       setivalue(&aux, k);
       key = &aux;  /* insert it as an integer */
     }
+    else if (luai_numisnan(fltvalue(key)))
+      luaG_runerror(L, "table index is NaN");
   }
   mp = mainposition(t, key);
   if (!ttisnil(gval(mp)) || isdummy(mp)) {  /* main position is taken? */

@@ -544,10 +549,10 @@
     case LUA_TNIL: return luaO_nilobject;
     case LUA_TNUMFLT: {
       lua_Integer k;
-      if (numisinteger(fltvalue(key), &k)) /* index is int? */
+      if (luaV_tointeger(key, &k, 0)) /* index is int? */
         return luaH_getint(t, k);  /* use specialized version */
-      /* else go through */
-    }
+      /* else... */
+    }  /* FALLTHROUGH */
     default: {
       Node *n = mainposition(t, key);
       for (;;) {  /* check whether 'key' is somewhere in the chain */

src/ltablib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltablib.c,v 1.79 2014/11/02 19:19:04 roberto Exp $
+** $Id: ltablib.c,v 1.80 2015/01/13 16:27:29 roberto Exp $
 ** Library for Table Manipulation
 ** See Copyright Notice in lua.h
 */

@@ -124,8 +124,6 @@
   lua_Integer e = luaL_checkinteger(L, 3);
   lua_Integer t = luaL_checkinteger(L, 4);
   int tt = !lua_isnoneornil(L, 5) ? 5 : 1;  /* destination table */
-  /* the following restriction avoids several problems with overflows */
-  luaL_argcheck(L, f > 0, 2, "initial position must be positive");
   if (e >= f) {  /* otherwise, nothing to move */
     lua_Integer n, i;
     ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL)

@@ -134,7 +132,11 @@
     ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL)
       ? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti)
       : lua_seti;
+    luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
+                  "too many elements to move");
     n = e - f + 1;  /* number of elements to move */
+    luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
+                  "destination wrap around");
     if (t > f) {
       for (i = n - 1; i >= 0; i--) {
         (*ta.geti)(L, 1, f + i);

src/ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.c,v 2.33 2014/11/21 12:15:57 roberto Exp $
+** $Id: ltm.c,v 2.34 2015/03/30 15:42:27 roberto Exp $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */

@@ -117,6 +117,7 @@
     switch (event) {
       case TM_CONCAT:
         luaG_concaterror(L, p1, p2);
+      /* call never returns, but to avoid warnings: *//* FALLTHROUGH */
       case TM_BAND: case TM_BOR: case TM_BXOR:
       case TM_SHL: case TM_SHR: case TM_BNOT: {
         lua_Number dummy;

@@ -124,8 +125,8 @@
           luaG_tointerror(L, p1, p2);
         else
           luaG_opinterror(L, p1, p2, "perform bitwise operation on");
-        /* else go through */
       }
+      /* calls never return, but to avoid warnings: *//* FALLTHROUGH */
       default:
         luaG_opinterror(L, p1, p2, "perform arithmetic on");
     }

src/lua.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.c,v 1.222 2014/11/11 19:41:27 roberto Exp $
+** $Id: lua.c,v 1.225 2015/03/30 15:42:59 roberto Exp $
 ** Lua stand-alone interpreter
 ** See Copyright Notice in lua.h
 */

@@ -80,9 +80,7 @@
 #include <readline/readline.h>
 #include <readline/history.h>
 #define lua_readline(L,b,p)	((void)L, ((b)=readline(p)) != NULL)
-#define lua_saveline(L,idx) \
-        if (lua_rawlen(L,idx) > 0)  /* non-empty line? */ \
-          add_history(lua_tostring(L, idx));  /* add it to history */
+#define lua_saveline(L,line)	((void)L, add_history(line))
 #define lua_freeline(L,b)	((void)L, free(b))
 
 #else				/* }{ */

@@ -90,7 +88,7 @@
 #define lua_readline(L,b,p) \
         ((void)L, fputs(p, stdout), fflush(stdout),  /* show prompt */ \
         fgets(b, LUA_MAXINPUT, stdin) != NULL)  /* get line */
-#define lua_saveline(L,idx)	{ (void)L; (void)idx; }
+#define lua_saveline(L,line)	{ (void)L; (void)line; }
 #define lua_freeline(L,b)	{ (void)L; (void)b; }
 
 #endif				/* } */

@@ -315,11 +313,11 @@
   lua_pop(L, 1);  /* remove prompt */
   l = strlen(b);
   if (l > 0 && b[l-1] == '\n')  /* line ends with newline? */
-    b[l-1] = '\0';  /* remove it */
+    b[--l] = '\0';  /* remove it */
   if (firstline && b[0] == '=')  /* for compatibility with 5.2, ... */
     lua_pushfstring(L, "return %s", b + 1);  /* change '=' to 'return' */
   else
-    lua_pushstring(L, b);
+    lua_pushlstring(L, b, l);
   lua_freeline(L, b);
   return 1;
 }

@@ -336,8 +334,12 @@
   lua_pushvalue(L, -2);  /* duplicate line */
   lua_concat(L, 2);  /* new line is "return ..." */
   line = lua_tolstring(L, -1, &len);
-  if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK)
+  if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) {
     lua_remove(L, -3);  /* remove original line */
+    line += sizeof("return")/sizeof(char);  /* remove 'return' for history */
+    if (line[0] != '\0')  /* non empty? */
+      lua_saveline(L, line);  /* keep history */
+  }
   else
     lua_pop(L, 2);  /* remove result from 'luaL_loadbuffer' and new line */
   return status;

@@ -352,8 +354,10 @@
     size_t len;
     const char *line = lua_tolstring(L, 1, &len);  /* get what it has */
     int status = luaL_loadbuffer(L, line, len, "=stdin");  /* try it */
-    if (!incomplete(L, status) || !pushline(L, 0))
+    if (!incomplete(L, status) || !pushline(L, 0)) {
+      lua_saveline(L, line);  /* keep history */
       return status;  /* cannot or should not try to add continuation line */
+    }
     lua_pushliteral(L, "\n");  /* add newline... */
     lua_insert(L, -2);  /* ...between the two lines */
     lua_concat(L, 3);  /* join them */

@@ -374,7 +378,6 @@
     return -1;  /* no input */
   if ((status = addreturn(L)) != LUA_OK)  /* 'return ...' did not work? */
     status = multiline(L);  /* try as command, maybe with continuation lines */
-  lua_saveline(L, 1);  /* keep history */
   lua_remove(L, 1);  /* remove line from the stack */
   lua_assert(lua_gettop(L) == 1);
   return status;

@@ -482,14 +485,14 @@
         args |= has_E;
         break;
       case 'i':
-        args |= has_i;  /* goes through  (-i implies -v) */
+        args |= has_i;  /* (-i implies -v) *//* FALLTHROUGH */ 
       case 'v':
         if (argv[i][2] != '\0')  /* extra characters after 1st? */
           return has_error;  /* invalid option */
         args |= has_v;
         break;
       case 'e':
-        args |= has_e;  /* go through */
+        args |= has_e;  /* FALLTHROUGH */
       case 'l':  /* both options need an argument */
         if (argv[i][2] == '\0') {  /* no concatenated argument? */
           i++;  /* try next 'argv' */

@@ -513,17 +516,16 @@
 static int runargs (lua_State *L, char **argv, int n) {
   int i;
   for (i = 1; i < n; i++) {
-    int status;
     int option = argv[i][1];
     lua_assert(argv[i][0] == '-');  /* already checked */
     if (option == 'e' || option == 'l') {
+      int status;
       const char *extra = argv[i] + 2;  /* both options need an argument */
       if (*extra == '\0') extra = argv[++i];
       lua_assert(extra != NULL);
-      if (option == 'e')
-        status = dostring(L, extra, "=(command line)");
-      else
-        status = dolibrary(L, extra);
+      status = (option == 'e')
+               ? dostring(L, extra, "=(command line)")
+               : dolibrary(L, extra);
       if (status != LUA_OK) return 0;
     }
   }

src/lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.325 2014/12/26 17:24:27 roberto Exp $
+** $Id: lua.h,v 1.328 2015/06/03 13:03:38 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"
+#define LUA_VERSION_RELEASE	"1"
 
 #define LUA_VERSION	"Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
 #define LUA_RELEASE	LUA_VERSION "." LUA_VERSION_RELEASE

@@ -35,9 +35,11 @@
 
 
 /*
-** pseudo-indices
+** Pseudo-indices
+** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
+** space after that to help overflow detection)
 */
-#define LUA_REGISTRYINDEX	LUAI_FIRSTPSEUDOIDX
+#define LUA_REGISTRYINDEX	(-LUAI_MAXSTACK - 1000)
 #define lua_upvalueindex(i)	(LUA_REGISTRYINDEX - (i))
 
 

@@ -356,8 +358,7 @@
 #define lua_isnone(L,n)		(lua_type(L, (n)) == LUA_TNONE)
 #define lua_isnoneornil(L, n)	(lua_type(L, (n)) <= 0)
 
-#define lua_pushliteral(L, s)	\
-	lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
+#define lua_pushliteral(L, s)	lua_pushstring(L, "" s)
 
 #define lua_pushglobaltable(L)  \
 	lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)

src/luac.c

@@ -1,5 +1,5 @@
 /*
-** $Id: luac.c,v 1.72 2015/01/06 03:09:13 lhf Exp $
+** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $
 ** Lua compiler (saves bytecodes to files; also lists bytecodes)
 ** See Copyright Notice in lua.h
 */

@@ -206,7 +206,7 @@
 }
 
 /*
-** $Id: print.c,v 1.76 2015/01/05 16:12:50 lhf Exp $
+** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $
 ** print bytecodes
 ** See Copyright Notice in lua.h
 */

@@ -226,7 +226,7 @@
 static void PrintString(const TString* ts)
 {
  const char* s=getstr(ts);
- size_t i,n=ts->len;
+ size_t i,n=tsslen(ts);
  printf("%c",'"');
  for (i=0; i<n; i++)
  {

src/luaconf.h

@@ -1,5 +1,5 @@
 /*
-** $Id: luaconf.h,v 1.238 2014/12/29 13:27:55 roberto Exp $
+** $Id: luaconf.h,v 1.251 2015/05/20 17:39:23 roberto Exp $
 ** Configuration file for Lua
 ** See Copyright Notice in lua.h
 */

@@ -96,10 +96,8 @@
 
 
 /*
-@@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines the type for
-** Lua integers.
-@@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines
-** the type for Lua floats.
+@@ LUA_INT_TYPE defines the type for Lua integers.
+@@ LUA_FLOAT_TYPE defines the type for Lua floats.
 ** Lua should work fine with any mix of these options (if supported
 ** by your C compiler). The usual configurations are 64-bit integers
 ** and 'double' (the default), 32-bit integers and 'float' (for

@@ -107,31 +105,46 @@
 ** compliant with C99, which may not have support for 'long long').
 */
 
+/* predefined options for LUA_INT_TYPE */
+#define LUA_INT_INT		1
+#define LUA_INT_LONG		2
+#define LUA_INT_LONGLONG	3
+
+/* predefined options for LUA_FLOAT_TYPE */
+#define LUA_FLOAT_FLOAT		1
+#define LUA_FLOAT_DOUBLE	2
+#define LUA_FLOAT_LONGDOUBLE	3
+
 #if defined(LUA_32BITS)		/* { */
 /*
 ** 32-bit integers and 'float'
 */
 #if LUAI_BITSINT >= 32  /* use 'int' if big enough */
-#define LUA_INT_INT
+#define LUA_INT_TYPE	LUA_INT_INT
 #else  /* otherwise use 'long' */
-#define LUA_INT_LONG
+#define LUA_INT_TYPE	LUA_INT_LONG
 #endif
-#define LUA_REAL_FLOAT
+#define LUA_FLOAT_TYPE	LUA_FLOAT_FLOAT
 
 #elif defined(LUA_C89_NUMBERS)	/* }{ */
 /*
 ** largest types available for C89 ('long' and 'double')
 */
-#define LUA_INT_LONG
-#define LUA_REAL_DOUBLE
+#define LUA_INT_TYPE	LUA_INT_LONG
+#define LUA_FLOAT_TYPE	LUA_FLOAT_DOUBLE
+
+#endif				/* } */
+
 
-#else				/* }{ */
 /*
 ** default configuration for 64-bit Lua ('long long' and 'double')
 */
-#define LUA_INT_LONGLONG
-#define LUA_REAL_DOUBLE
+#if !defined(LUA_INT_TYPE)
+#define LUA_INT_TYPE	LUA_INT_LONGLONG
+#endif
 
+#if !defined(LUA_FLOAT_TYPE)
+#define LUA_FLOAT_TYPE	LUA_FLOAT_DOUBLE
 #endif								/* } */
 
 /* }================================================================== */

@@ -155,7 +168,7 @@
 ** non-conventional directories.
 */
 #define LUA_VDIR	LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
-#if defined(_WIN32) 	/* { */
+#if defined(_WIN32)	/* { */
 /*
 ** In Windows, any exclamation mark ('!') in the path is replaced by the
 ** path of the directory of the executable file of the current process.

@@ -300,20 +313,15 @@
 */
 #define LUA_COMPAT_APIINTCASTS
 
-
-/*
-@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
-@@ a float mark ('.0').
-** This macro is not on by default even in compatibility mode,
-** because this is not really an incompatibility.
-*/
-/* #define LUA_COMPAT_FLOATSTRING */
-
 #endif				/* } */
 
 
 #if defined(LUA_COMPAT_5_1)	/* { */
 
+/* Incompatibilities from 5.2 -> 5.3 */
+#define LUA_COMPAT_MATHLIB
+#define LUA_COMPAT_APIINTCASTS
+
 /*
 @@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
 ** You can replace it with 'table.unpack'.

@@ -373,6 +381,15 @@
 
 #endif				/* } */
 
+
+/*
+@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
+@@ a float mark ('.0').
+** This macro is not on by default even in compatibility mode,
+** because this is not really an incompatibility.
+*/
+/* #define LUA_COMPAT_FLOATSTRING */
+
 /* }================================================================== */
 
 

@@ -380,30 +397,30 @@
 /*
 ** {==================================================================
 ** Configuration for Numbers.
-** Change these definitions if no predefined LUA_REAL_* / LUA_INT_*
+** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
 ** satisfy your needs.
 ** ===================================================================
 */
 
 /*
 @@ LUA_NUMBER is the floating-point type used by Lua.
-**
 @@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
 @@ over a floating number.
-**
+@@ l_mathlim(x) corrects limit name 'x' to the proper float type
+** by prefixing it with one of FLT/DBL/LDBL.
 @@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
 @@ LUA_NUMBER_FMT is the format for writing floats.
 @@ lua_number2str converts a float to a string.
-**
 @@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
-**
 @@ lua_str2number converts a decimal numeric string to a number.
 */
 
-#if defined(LUA_REAL_FLOAT)		/* { single float */
+#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT		/* { single float */
 
 #define LUA_NUMBER	float
 
+#define l_mathlim(n)		(FLT_##n)
+
 #define LUAI_UACNUMBER	double
 
 #define LUA_NUMBER_FRMLEN	""

@@ -414,10 +431,12 @@
 #define lua_str2number(s,p)	strtof((s), (p))
 
 
-#elif defined(LUA_REAL_LONGDOUBLE)	/* }{ long double */
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE	/* }{ long double */
 
 #define LUA_NUMBER	long double
 
+#define l_mathlim(n)		(LDBL_##n)
+
 #define LUAI_UACNUMBER	long double
 
 #define LUA_NUMBER_FRMLEN	"L"

@@ -427,10 +446,12 @@
 
 #define lua_str2number(s,p)	strtold((s), (p))
 
-#elif defined(LUA_REAL_DOUBLE)		/* }{ double */
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE	/* }{ double */
 
 #define LUA_NUMBER	double
 
+#define l_mathlim(n)		(DBL_##n)
+
 #define LUAI_UACNUMBER	double
 
 #define LUA_NUMBER_FRMLEN	""

@@ -440,9 +461,9 @@
 
 #define lua_str2number(s,p)	strtod((s), (p))
 
-#else					/* }{ */
+#else						/* }{ */
 
-#error "numeric real type not defined"
+#error "numeric float type not defined"
 
 #endif					/* } */
 

@@ -466,46 +487,6 @@
       (*(p) = (LUA_INTEGER)(n), 1))
 
 
-/*
-@@ The luai_num* macros define the primitive operations over numbers.
-** They should work for any size of floating numbers.
-*/
-
-/* the following operations need the math library */
-#if defined(lobject_c) || defined(lvm_c)
-#include <math.h>
-
-/* floor division (defined as 'floor(a/b)') */
-#define luai_numidiv(L,a,b)	((void)L, l_mathop(floor)(luai_numdiv(L,a,b)))
-
-/*
-** module: defined as 'a - floor(a/b)*b'; the previous definition gives
-** NaN when 'b' is huge, but the result should be 'a'. 'fmod' gives the
-** result of 'a - trunc(a/b)*b', and therefore must be corrected when
-** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a
-** non-integer negative result, which is equivalent to the test below
-*/
-#define luai_nummod(L,a,b,m)  \
-  { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
-
-/* exponentiation */
-#define luai_numpow(L,a,b)	((void)L, l_mathop(pow)(a,b))
-
-#endif
-
-/* these are quite standard operations */
-#if defined(LUA_CORE)
-#define luai_numadd(L,a,b)	((a)+(b))
-#define luai_numsub(L,a,b)	((a)-(b))
-#define luai_nummul(L,a,b)	((a)*(b))
-#define luai_numdiv(L,a,b)	((a)/(b))
-#define luai_numunm(L,a)	(-(a))
-#define luai_numeq(a,b)		((a)==(b))
-#define luai_numlt(a,b)		((a)<(b))
-#define luai_numle(a,b)		((a)<=(b))
-#define luai_numisnan(a)	(!luai_numeq((a), (a)))
-#endif
-
 
 /*
 @@ LUA_INTEGER is the integer type used by Lua.

@@ -538,7 +519,7 @@
 
 /* now the variable definitions */
 
-#if defined(LUA_INT_INT)		/* { int */
+#if LUA_INT_TYPE == LUA_INT_INT		/* { int */
 
 #define LUA_INTEGER		int
 #define LUA_INTEGER_FRMLEN	""

@@ -546,7 +527,7 @@
 #define LUA_MAXINTEGER		INT_MAX
 #define LUA_MININTEGER		INT_MIN
 
-#elif defined(LUA_INT_LONG)	/* }{ long */
+#elif LUA_INT_TYPE == LUA_INT_LONG	/* }{ long */
 
 #define LUA_INTEGER		long
 #define LUA_INTEGER_FRMLEN	"l"

@@ -554,7 +535,7 @@
 #define LUA_MAXINTEGER		LONG_MAX
 #define LUA_MININTEGER		LONG_MIN
 
-#elif defined(LUA_INT_LONGLONG)	/* }{ long long */
+#elif LUA_INT_TYPE == LUA_INT_LONGLONG	/* }{ long long */
 
 #if defined(LLONG_MAX)		/* { */
 /* use ISO C99 stuff */

@@ -592,13 +573,13 @@
 
 /*
 ** {==================================================================
-** Dependencies with C99
+** Dependencies with C99 and other C details
 ** ===================================================================
 */
 
 /*
 @@ lua_strx2number converts an hexadecimal numeric string to a number.
-** In C99, 'strtod' does both conversions. Otherwise, you can
+** In C99, 'strtod' does that conversion. Otherwise, you can
 ** leave 'lua_strx2number' undefined and Lua will provide its own
 ** implementation.
 */

@@ -608,12 +589,13 @@
 
 
 /*
-@@ LUA_USE_AFORMAT allows '%a'/'%A' specifiers in 'string.format'
-** Enable it if the C function 'printf' supports these specifiers.
-** (C99 demands it and Windows also supports it.)
+@@ lua_number2strx converts a float to an hexadecimal numeric string. 
+** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
+** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
+** provide its own implementation.
 */
-#if !defined(LUA_USE_C89) || defined(LUA_USE_WINDOWS)
-#define LUA_USE_AFORMAT
+#if !defined(LUA_USE_C89)
+#define lua_number2strx(L,b,f,n)	sprintf(b,f,n)
 #endif
 
 

@@ -642,12 +624,50 @@
 #if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
     __STDC_VERSION__ >= 199901L
 #include <stdint.h>
-#if defined (INTPTR_MAX)  /* even in C99 this type is optional */
+#if defined(INTPTR_MAX)  /* even in C99 this type is optional */
 #undef LUA_KCONTEXT
 #define LUA_KCONTEXT	intptr_t
 #endif
 #endif
 
+
+/*
+@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
+** Change that if you do not want to use C locales. (Code using this
+** macro must include header 'locale.h'.)
+*/
+#if !defined(lua_getlocaledecpoint)
+#define lua_getlocaledecpoint()		(localeconv()->decimal_point[0])
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Language Variations
+** =====================================================================
+*/
+
+/*
+@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
+** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
+** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
+** coercion from strings to numbers.
+*/
+/* #define LUA_NOCVTN2S */
+/* #define LUA_NOCVTS2N */
+
+
+/*
+@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
+** Define it as a help when debugging C code.
+*/
+#if defined(LUA_USE_APICHECK)
+#include <assert.h>
+#define luai_apicheck(l,e)	assert(e)
+#endif
+
 /* }================================================================== */
 
 

@@ -671,9 +691,6 @@
 #define LUAI_MAXSTACK		15000
 #endif
 
-/* reserve some space for error handling */
-#define LUAI_FIRSTPSEUDOIDX	(-LUAI_MAXSTACK - 1000)
-
 
 /*
 @@ LUA_EXTRASPACE defines the size of a raw memory area associated with

@@ -692,19 +709,17 @@
 
 
 /*
-@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is,
-** strings that are internalized. (Cannot be smaller than reserved words
-** or tags for metamethods, as these strings must be internalized;
-** #("function") = 8, #("__newindex") = 10.)
-*/
-#define LUAI_MAXSHORTLEN        40
-
-
-/*
 @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
-** CHANGE it if it uses too much C-stack space.
+** CHANGE it if it uses too much C-stack space. (For long double,
+** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
+** smaller buffer would force a memory allocation for each call to
+** 'string.format'.)
 */
-#define LUAL_BUFFERSIZE	((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
+#if defined(LUA_FLOAT_LONGDOUBLE)
+#define LUAL_BUFFERSIZE		8192
+#else
+#define LUAL_BUFFERSIZE   ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
+#endif
 
 /* }================================================================== */
 

src/lutf8lib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lutf8lib.c,v 1.13 2014/11/02 19:19:04 roberto Exp $
+** $Id: lutf8lib.c,v 1.15 2015/03/28 19:16:55 roberto Exp $
 ** Standard library for UTF-8 manipulation
 ** See Copyright Notice in lua.h
 */

@@ -11,6 +11,7 @@
 
 
 #include <assert.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 

@@ -37,7 +38,7 @@
 ** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid.
 */
 static const char *utf8_decode (const char *o, int *val) {
-  static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
+  static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
   const unsigned char *s = (const unsigned char *)o;
   unsigned int c = s[0];
   unsigned int res = 0;  /* final result */

@@ -106,9 +107,9 @@
   luaL_argcheck(L, posi >= 1, 2, "out of range");
   luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range");
   if (posi > pose) return 0;  /* empty interval; return no values */
-  n = (int)(pose -  posi + 1);
-  if (posi + n <= pose)  /* (lua_Integer -> int) overflow? */
+  if (pose - posi >= INT_MAX)  /* (lua_Integer -> int) overflow? */
     return luaL_error(L, "string slice too long");
+  n = (int)(pose -  posi) + 1;
   luaL_checkstack(L, n, "string slice too long");
   n = 0;
   se = s + pose;

@@ -234,7 +235,7 @@
 #define UTF8PATT	"[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
 
 
-static struct luaL_Reg funcs[] = {
+static const luaL_Reg funcs[] = {
   {"offset", byteoffset},
   {"codepoint", codepoint},
   {"char", utfchar},

@@ -248,7 +249,7 @@
 
 LUAMOD_API int luaopen_utf8 (lua_State *L) {
   luaL_newlib(L, funcs);
-  lua_pushliteral(L, UTF8PATT);
+  lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1);
   lua_setfield(L, -2, "charpattern");
   return 1;
 }

src/lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.232 2014/12/27 20:30:38 roberto Exp $
+** $Id: lvm.c,v 2.245 2015/06/09 15:53:35 roberto Exp $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */

@@ -9,8 +9,9 @@
 
 #include "lprefix.h"
 
-
+#include <float.h>
 #include <limits.h>
+#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

@@ -30,36 +31,38 @@
 #include "lvm.h"
 
 
-/*
-** You can define LUA_FLOORN2I if you want to convert floats to integers
-** by flooring them (instead of raising an error if they are not
-** integral values)
-*/
-#if !defined(LUA_FLOORN2I)
-#define LUA_FLOORN2I		0
-#endif
-
-
 /* limit for table tag-method chains (to avoid loops) */
 #define MAXTAGLOOP	2000
 
 
+
 /*
-** Similar to 'tonumber', but does not attempt to convert strings and
-** ensure correct precision (no extra bits). Used in comparisons.
+** 'l_intfitsf' checks whether a given integer can be converted to a
+** float without rounding. Used in comparisons. Left undefined if
+** all integers fit in a float precisely.
 */
-static int tofloat (const TValue *obj, lua_Number *n) {
-  if (ttisfloat(obj)) *n = fltvalue(obj);
-  else if (ttisinteger(obj)) {
-    volatile lua_Number x = cast_num(ivalue(obj));  /* avoid extra precision */
-    *n = x;
-  }
-  else {
-    *n = 0;  /* to avoid warnings */
-    return 0;
-  }
-  return 1;
-}
+#if !defined(l_intfitsf)
+
+/* number of bits in the mantissa of a float */
+#define NBM		(l_mathlim(MANT_DIG))
+
+/*
+** Check whether some integers may not fit in a float, that is, whether
+** (maxinteger >> NBM) > 0 (that implies (1 << NBM) <= maxinteger).
+** (The shifts are done in parts to avoid shifting by more than the size
+** of an integer. In a worst case, NBM == 113 for long double and
+** sizeof(integer) == 32.)
+*/
+#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \
+	>> (NBM - (3 * (NBM / 4))))  >  0
+
+#define l_intfitsf(i)  \
+  (-((lua_Integer)1 << NBM) <= (i) && (i) <= ((lua_Integer)1 << NBM))
+
+#endif
+
+#endif
+
 
 
 /*

@@ -73,7 +76,7 @@
     return 1;
   }
   else if (cvt2num(obj) &&  /* string convertible to number? */
-            luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
+            luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
     *n = nvalue(&v);  /* convert result of 'luaO_str2num' to a float */
     return 1;
   }

@@ -88,7 +91,7 @@
 ** mode == 1: takes the floor of the number
 ** mode == 2: takes the ceil of the number
 */
-static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
+int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
   TValue v;
  again:
   if (ttisfloat(obj)) {

@@ -106,7 +109,7 @@
     return 1;
   }
   else if (cvt2num(obj) &&
-            luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
+            luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
     obj = &v;
     goto again;  /* convert result from 'luaO_str2num' to an integer */
   }

@@ -115,14 +118,6 @@
 
 
 /*
-** try to convert a value to an integer
-*/
-int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
-  return tointeger_aux(obj, p, LUA_FLOORN2I);
-}
-
-
-/*
 ** 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

@@ -140,11 +135,11 @@
 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 ? 2 : 1))) {  /* not fit in integer? */
+  if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) {  /* not fit in integer? */
     lua_Number n;  /* try to convert to float */
     if (!tonumber(obj, &n)) /* cannot convert to float? */
       return 0;  /* not a number */
-    if (n > 0) {  /* if true, float is larger than max integer */
+    if (luai_numlt(0, n)) {  /* if true, float is larger than max integer */
       *p = LUA_MAXINTEGER;
       if (step < 0) *stopnow = 1;
     }

@@ -239,9 +234,9 @@
 */
 static int l_strcmp (const TString *ls, const TString *rs) {
   const char *l = getstr(ls);
-  size_t ll = ls->len;
+  size_t ll = tsslen(ls);
   const char *r = getstr(rs);
-  size_t lr = rs->len;
+  size_t lr = tsslen(rs);
   for (;;) {  /* for each segment */
     int temp = strcoll(l, r);
     if (temp != 0)  /* not equal? */

@@ -261,15 +256,102 @@
 
 
 /*
+** Check whether integer 'i' is less than float 'f'. If 'i' has an
+** exact representation as a float ('l_intfitsf'), compare numbers as
+** floats. Otherwise, if 'f' is outside the range for integers, result
+** is trivial. Otherwise, compare them as integers. (When 'i' has no
+** float representation, either 'f' is "far away" from 'i' or 'f' has
+** no precision left for a fractional part; either way, how 'f' is
+** truncated is irrelevant.) When 'f' is NaN, comparisons must result
+** in false.
+*/
+static int LTintfloat (lua_Integer i, lua_Number f) {
+#if defined(l_intfitsf)
+  if (!l_intfitsf(i)) {
+    if (f >= -cast_num(LUA_MININTEGER))  /* -minint == maxint + 1 */
+      return 1;  /* f >= maxint + 1 > i */
+    else if (f > cast_num(LUA_MININTEGER))  /* minint < f <= maxint ? */
+      return (i < cast(lua_Integer, f));  /* compare them as integers */
+    else  /* f <= minint <= i (or 'f' is NaN)  -->  not(i < f) */
+      return 0;
+  }
+#endif
+  return luai_numlt(cast_num(i), f);  /* compare them as floats */
+}
+
+
+/*
+** Check whether integer 'i' is less than or equal to float 'f'.
+** See comments on previous function.
+*/
+static int LEintfloat (lua_Integer i, lua_Number f) {
+#if defined(l_intfitsf)
+  if (!l_intfitsf(i)) {
+    if (f >= -cast_num(LUA_MININTEGER))  /* -minint == maxint + 1 */
+      return 1;  /* f >= maxint + 1 > i */
+    else if (f >= cast_num(LUA_MININTEGER))  /* minint <= f <= maxint ? */
+      return (i <= cast(lua_Integer, f));  /* compare them as integers */
+    else  /* f < minint <= i (or 'f' is NaN)  -->  not(i <= f) */
+      return 0;
+  }
+#endif
+  return luai_numle(cast_num(i), f);  /* compare them as floats */
+}
+
+
+/*
+** Return 'l < r', for numbers.
+*/
+static int LTnum (const TValue *l, const TValue *r) {
+  if (ttisinteger(l)) {
+    lua_Integer li = ivalue(l);
+    if (ttisinteger(r))
+      return li < ivalue(r);  /* both are integers */
+    else  /* 'l' is int and 'r' is float */
+      return LTintfloat(li, fltvalue(r));  /* l < r ? */
+  }
+  else {
+    lua_Number lf = fltvalue(l);  /* 'l' must be float */
+    if (ttisfloat(r))
+      return luai_numlt(lf, fltvalue(r));  /* both are float */
+    else if (luai_numisnan(lf))  /* 'r' is int and 'l' is float */
+      return 0;  /* NaN < i is always false */
+    else  /* without NaN, (l < r)  <-->  not(r <= l) */
+      return !LEintfloat(ivalue(r), lf);  /* not (r <= l) ? */
+  }
+}
+
+
+/*
+** Return 'l <= r', for numbers.
+*/
+static int LEnum (const TValue *l, const TValue *r) {
+  if (ttisinteger(l)) {
+    lua_Integer li = ivalue(l);
+    if (ttisinteger(r))
+      return li <= ivalue(r);  /* both are integers */
+    else  /* 'l' is int and 'r' is float */
+      return LEintfloat(li, fltvalue(r));  /* l <= r ? */
+  }
+  else {
+    lua_Number lf = fltvalue(l);  /* 'l' must be float */
+    if (ttisfloat(r))
+      return luai_numle(lf, fltvalue(r));  /* both are float */
+    else if (luai_numisnan(lf))  /* 'r' is int and 'l' is float */
+      return 0;  /*  NaN <= i is always false */
+    else  /* without NaN, (l <= r)  <-->  not(r < l) */
+      return !LTintfloat(ivalue(r), lf);  /* not (r < l) ? */
+  }
+}
+
+
+/*
 ** Main operation less than; return 'l < r'.
 */
 int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
   int res;
-  lua_Number nl, nr;
-  if (ttisinteger(l) && ttisinteger(r))  /* both operands are integers? */
-    return (ivalue(l) < ivalue(r));
-  else if (tofloat(l, &nl) && tofloat(r, &nr))  /* both are numbers? */
-    return luai_numlt(nl, nr);
+  if (ttisnumber(l) && ttisnumber(r))  /* both operands are numbers? */
+    return LTnum(l, r);
   else if (ttisstring(l) && ttisstring(r))  /* both are strings? */
     return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
   else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0)  /* no metamethod? */

@@ -279,27 +361,34 @@
 
 
 /*
-** Main operation less than or equal to; return 'l <= r'.
+** Main operation less than or equal to; return 'l <= r'. If it needs
+** a metamethod and there is no '__le', try '__lt', based on
+** l <= r iff !(r < l) (assuming a total order). If the metamethod
+** yields during this substitution, the continuation has to know
+** about it (to negate the result of r<l); bit CIST_LEQ in the call
+** status keeps that information.
 */
 int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
   int res;
-  lua_Number nl, nr;
-  if (ttisinteger(l) && ttisinteger(r))  /* both operands are integers? */
-    return (ivalue(l) <= ivalue(r));
-  else if (tofloat(l, &nl) && tofloat(r, &nr))  /* both are numbers? */
-    return luai_numle(nl, nr);
+  if (ttisnumber(l) && ttisnumber(r))  /* both operands are numbers? */
+    return LEnum(l, r);
   else if (ttisstring(l) && ttisstring(r))  /* both are strings? */
     return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
-  else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0)  /* first try 'le' */
+  else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0)  /* try 'le' */
     return res;
-  else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0)  /* else try 'lt' */
-    luaG_ordererror(L, l, r);
-  return !res;
+  else {  /* try 'lt': */
+    L->ci->callstatus |= CIST_LEQ;  /* mark it is doing 'lt' for 'le' */
+    res = luaT_callorderTM(L, r, l, TM_LT);
+    L->ci->callstatus ^= CIST_LEQ;  /* clear mark */
+    if (res < 0)
+      luaG_ordererror(L, l, r);
+    return !res;  /* result is negated */
+  }
 }
 
 
 /*
-** Main operation for equality of Lua values; return 't1 == t2'. 
+** Main operation for equality of Lua values; return 't1 == t2'.
 ** L == NULL means raw equality (no metamethods)
 */
 int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {

@@ -308,10 +397,8 @@
     if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER)
       return 0;  /* only numbers can be equal with different variants */
     else {  /* two numbers with different variants */
-      lua_Number n1, n2;  /* compare them as floats */
-      lua_assert(ttisnumber(t1) && ttisnumber(t2));
-      cast_void(tofloat(t1, &n1)); cast_void(tofloat(t2, &n2));
-      return luai_numeq(n1, n2);
+      lua_Integer i1, i2;  /* compare them as integers */
+      return (tointeger(t1, &i1) && tointeger(t2, &i2) && i1 == i2);
     }
   }
   /* values have same type and same variant */

@@ -354,6 +441,8 @@
 #define tostring(L,o)  \
 	(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
 
+#define isemptystr(o)	(ttisshrstring(o) && tsvalue(o)->shrlen == 0)
+
 /*
 ** Main operation for concatenation: concat 'total' values in the stack,
 ** from 'L->top - total' up to 'L->top - 1'.

@@ -365,19 +454,19 @@
     int n = 2;  /* number of elements handled in this pass (at least 2) */
     if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
       luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
-    else if (tsvalue(top-1)->len == 0)  /* second operand is empty? */
+    else if (isemptystr(top - 1))  /* second operand is empty? */
       cast_void(tostring(L, top - 2));  /* result is first operand */
-    else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
+    else if (isemptystr(top - 2)) {  /* first operand is an empty string? */
       setobjs2s(L, top - 2, top - 1);  /* result is second op. */
     }
     else {
       /* at least two non-empty string values; get as many as possible */
-      size_t tl = tsvalue(top-1)->len;
+      size_t tl = vslen(top - 1);
       char *buffer;
       int i;
       /* collect total length */
       for (i = 1; i < total && tostring(L, top-i-1); i++) {
-        size_t l = tsvalue(top-i-1)->len;
+        size_t l = vslen(top - i - 1);
         if (l >= (MAX_SIZE/sizeof(char)) - tl)
           luaG_runerror(L, "string length overflow");
         tl += l;

@@ -386,7 +475,7 @@
       tl = 0;
       n = i;
       do {  /* copy all strings to buffer */
-        size_t l = tsvalue(top-i)->len;
+        size_t l = vslen(top - i);
         memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
         tl += l;
       } while (--i > 0);

@@ -403,7 +492,7 @@
 */
 void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
   const TValue *tm;
-  switch (ttnov(rb)) {
+  switch (ttype(rb)) {
     case LUA_TTABLE: {
       Table *h = hvalue(rb);
       tm = fasttm(L, h->metatable, TM_LEN);

@@ -411,8 +500,12 @@
       setivalue(ra, luaH_getn(h));  /* else primitive len */
       return;
     }
-    case LUA_TSTRING: {
-      setivalue(ra, tsvalue(rb)->len);
+    case LUA_TSHRSTR: {
+      setivalue(ra, tsvalue(rb)->shrlen);
+      return;
+    }
+    case LUA_TLNGSTR: {
+      setivalue(ra, tsvalue(rb)->u.lnglen);
       return;
     }
     default: {  /* try metamethod */

@@ -448,7 +541,7 @@
 
 
 /*
-** Integer modulus; return 'm % n'. (Assume that C '%' with 
+** Integer modulus; return 'm % n'. (Assume that C '%' with
 ** negative operands follows C99 behavior. See previous comment
 ** about luaV_div.)
 */

@@ -553,11 +646,11 @@
     case OP_LE: case OP_LT: case OP_EQ: {
       int res = !l_isfalse(L->top - 1);
       L->top--;
-      /* metamethod should not be called when operand is K */
-      lua_assert(!ISK(GETARG_B(inst)));
-      if (op == OP_LE &&  /* "<=" using "<" instead? */
-          ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
-        res = !res;  /* invert result */
+      if (ci->callstatus & CIST_LEQ) {  /* "<=" using "<" instead? */
+        lua_assert(op == OP_LE);
+        ci->callstatus ^= CIST_LEQ;  /* clear mark */
+        res = !res;  /* negate result */
+      }
       lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
       if (res != GETARG_A(inst))  /* condition failed? */
         ci->u.l.savedpc++;  /* skip jump instruction */

@@ -607,7 +700,7 @@
 ** some macros for common tasks in 'luaV_execute'
 */
 
-#if !defined luai_runtimecheck
+#if !defined(luai_runtimecheck)
 #define luai_runtimecheck(L, c)		/* void */
 #endif
 

@@ -743,7 +836,7 @@
         Protect(luaV_gettable(L, rb, RKC(i), ra));
         vmbreak;
       }
-      vmcase(OP_ADD) { 
+      vmcase(OP_ADD) {
         TValue *rb = RKB(i);
         TValue *rc = RKC(i);
         lua_Number nb; lua_Number nc;

@@ -928,7 +1021,7 @@
         L->top = base + c + 1;  /* mark the end of concat operands */
         Protect(luaV_concat(L, c - b + 1));
         ra = RA(i);  /* 'luav_concat' may invoke TMs and move the stack */
-        rb = b + base;
+        rb = base + b;
         setobjs2s(L, ra, rb);
         checkGC(L, (ra >= rb ? ra + 1 : rb));
         L->top = ci->top;  /* restore top */

@@ -1031,9 +1124,8 @@
       }
       vmcase(OP_RETURN) {
         int b = GETARG_B(i);
-        if (b != 0) L->top = ra+b-1;
         if (cl->p->sizep > 0) luaF_close(L, base);
-        b = luaD_poscall(L, ra);
+        b = luaD_poscall(L, ra, (b != 0 ? b - 1 : L->top - ra));
         if (!(ci->callstatus & CIST_REENTRY))  /* 'ci' still the called one */
           return;  /* external invocation: return */
         else {  /* invocation via reentry: continue execution */

@@ -1051,7 +1143,7 @@
           lua_Integer limit = ivalue(ra + 1);
           if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
             ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
-            setivalue(ra, idx);  /* update internal index... */
+            chgivalue(ra, idx);  /* update internal index... */
             setivalue(ra + 3, idx);  /* ...and external index */
           }
         }

@@ -1062,7 +1154,7 @@
           if (luai_numlt(0, step) ? luai_numle(idx, limit)
                                   : luai_numle(limit, idx)) {
             ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
-            setfltvalue(ra, idx);  /* update internal index... */
+            chgfltvalue(ra, idx);  /* update internal index... */
             setfltvalue(ra + 3, idx);  /* ...and external index */
           }
         }

src/lvm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.h,v 2.34 2014/08/01 17:24:02 roberto Exp $
+** $Id: lvm.h,v 2.35 2015/02/20 14:27:53 roberto Exp $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */

@@ -27,11 +27,21 @@
 #endif
 
 
+/*
+** You can define LUA_FLOORN2I if you want to convert floats to integers
+** by flooring them (instead of raising an error if they are not
+** integral values)
+*/
+#if !defined(LUA_FLOORN2I)
+#define LUA_FLOORN2I		0
+#endif
+
+
 #define tonumber(o,n) \
 	(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
 
 #define tointeger(o,i) \
-	(ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger_(o,i))
+    (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))
 
 #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
 

@@ -42,7 +52,7 @@
 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_tointeger (const TValue *obj, lua_Integer *p, int mode);
 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,