Lua diffu-lua-5.5.0-beta-rc1


README

@@ -1,5 +1,5 @@
 
-This is Lua 5.5.0 (beta), released on 28 Jun 2025.
+This is Lua 5.5.0, released on 14 Nov 2025.
 
 For installation instructions, license details, and
 further information about Lua, see doc/readme.html.

doc/contents.html

@@ -86,6 +86,7 @@
 <LI><A HREF="manual.html#3.4.10">3.4.10 &ndash; Function Calls</A>
 <LI><A HREF="manual.html#3.4.11">3.4.11 &ndash; Function Definitions</A>
 <LI><A HREF="manual.html#3.4.12">3.4.12 &ndash; Lists of expressions, multiple results, and adjustment<A>
+</UL>
 <P>
 <LI><A HREF="manual.html#4">4 &ndash; The Application Program Interface</A>
 <UL>

@@ -148,7 +149,7 @@
 <TD>
 <H3><A NAME="functions">Lua functions</A></H3>
 <P>
-<A HREF="manual.html#6.1">basic</A><BR>
+<A HREF="manual.html#6.2">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>

@@ -177,7 +178,7 @@
 <A HREF="manual.html#pdf-xpcall">xpcall</A><BR>
 
 <P>
-<A HREF="manual.html#6.2">coroutine</A><BR>
+<A HREF="manual.html#6.3">coroutine</A><BR>
 <A HREF="manual.html#pdf-coroutine.close">coroutine.close</A><BR>
 <A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR>
 <A HREF="manual.html#pdf-coroutine.isyieldable">coroutine.isyieldable</A><BR>

@@ -188,7 +189,7 @@
 <A HREF="manual.html#pdf-coroutine.yield">coroutine.yield</A><BR>
 
 <P>
-<A HREF="manual.html#6.10">debug</A><BR>
+<A HREF="manual.html#6.11">debug</A><BR>
 <A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR>
 <A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR>
 <A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR>

@@ -207,7 +208,7 @@
 <A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR>
 
 <P>
-<A HREF="manual.html#6.8">io</A><BR>
+<A HREF="manual.html#6.9">io</A><BR>
 <A HREF="manual.html#pdf-io.close">io.close</A><BR>
 <A HREF="manual.html#pdf-io.flush">io.flush</A><BR>
 <A HREF="manual.html#pdf-io.input">io.input</A><BR>

@@ -235,7 +236,7 @@
 <TD>
 <H3>&nbsp;</H3>
 <P>
-<A HREF="manual.html#6.7">math</A><BR>
+<A HREF="manual.html#6.8">math</A><BR>
 <A HREF="manual.html#pdf-math.abs">math.abs</A><BR>
 <A HREF="manual.html#pdf-math.acos">math.acos</A><BR>
 <A HREF="manual.html#pdf-math.asin">math.asin</A><BR>

@@ -246,7 +247,9 @@
 <A HREF="manual.html#pdf-math.exp">math.exp</A><BR>
 <A HREF="manual.html#pdf-math.floor">math.floor</A><BR>
 <A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR>
+<A HREF="manual.html#pdf-math.frexp">math.frexp</A><BR>
 <A HREF="manual.html#pdf-math.huge">math.huge</A><BR>
+<A HREF="manual.html#pdf-math.ldexp">math.ldexp</A><BR>
 <A HREF="manual.html#pdf-math.log">math.log</A><BR>
 <A HREF="manual.html#pdf-math.max">math.max</A><BR>
 <A HREF="manual.html#pdf-math.maxinteger">math.maxinteger</A><BR>

@@ -265,7 +268,7 @@
 <A HREF="manual.html#pdf-math.ult">math.ult</A><BR>
 
 <P>
-<A HREF="manual.html#6.9">os</A><BR>
+<A HREF="manual.html#6.10">os</A><BR>
 <A HREF="manual.html#pdf-os.clock">os.clock</A><BR>
 <A HREF="manual.html#pdf-os.date">os.date</A><BR>
 <A HREF="manual.html#pdf-os.difftime">os.difftime</A><BR>

@@ -279,7 +282,7 @@
 <A HREF="manual.html#pdf-os.tmpname">os.tmpname</A><BR>
 
 <P>
-<A HREF="manual.html#6.3">package</A><BR>
+<A HREF="manual.html#6.4">package</A><BR>
 <A HREF="manual.html#pdf-package.config">package.config</A><BR>
 <A HREF="manual.html#pdf-package.cpath">package.cpath</A><BR>
 <A HREF="manual.html#pdf-package.loaded">package.loaded</A><BR>

@@ -290,7 +293,7 @@
 <A HREF="manual.html#pdf-package.searchpath">package.searchpath</A><BR>
 
 <P>
-<A HREF="manual.html#6.4">string</A><BR>
+<A HREF="manual.html#6.5">string</A><BR>
 <A HREF="manual.html#pdf-string.byte">string.byte</A><BR>
 <A HREF="manual.html#pdf-string.char">string.char</A><BR>
 <A HREF="manual.html#pdf-string.dump">string.dump</A><BR>

@@ -310,8 +313,9 @@
 <A HREF="manual.html#pdf-string.upper">string.upper</A><BR>
 
 <P>
-<A HREF="manual.html#6.6">table</A><BR>
+<A HREF="manual.html#6.7">table</A><BR>
 <A HREF="manual.html#pdf-table.concat">table.concat</A><BR>
+<A HREF="manual.html#pdf-table.create">table.create</A><BR>
 <A HREF="manual.html#pdf-table.insert">table.insert</A><BR>
 <A HREF="manual.html#pdf-table.move">table.move</A><BR>
 <A HREF="manual.html#pdf-table.pack">table.pack</A><BR>

@@ -320,7 +324,7 @@
 <A HREF="manual.html#pdf-table.unpack">table.unpack</A><BR>
 
 <P>
-<A HREF="manual.html#6.5">utf8</A><BR>
+<A HREF="manual.html#6.6">utf8</A><BR>
 <A HREF="manual.html#pdf-utf8.char">utf8.char</A><BR>
 <A HREF="manual.html#pdf-utf8.charpattern">utf8.charpattern</A><BR>
 <A HREF="manual.html#pdf-utf8.codepoint">utf8.codepoint</A><BR>

@@ -528,6 +532,7 @@
 <A HREF="manual.html#luaL_addsize">luaL_addsize</A><BR>
 <A HREF="manual.html#luaL_addstring">luaL_addstring</A><BR>
 <A HREF="manual.html#luaL_addvalue">luaL_addvalue</A><BR>
+<A HREF="manual.html#luaL_alloc">luaL_alloc</A><BR>
 <A HREF="manual.html#luaL_argcheck">luaL_argcheck</A><BR>
 <A HREF="manual.html#luaL_argerror">luaL_argerror</A><BR>
 <A HREF="manual.html#luaL_argexpected">luaL_argexpected</A><BR>

@@ -669,7 +674,7 @@
 
 <P CLASS="footer">
 Last update:
-Tue Jun 24 10:26:21 UTC 2025
+Sat Nov 15 00:51:05 UTC 2025
 </P>
 <!--
 Last change: revised for Lua 5.5.0

doc/manual.html

@@ -190,7 +190,8 @@
 including embedded zeros ('<code>\0</code>').
 Lua is also encoding-agnostic;
 it makes no assumptions about the contents of a string.
-The length of any string in Lua must fit in a Lua integer.
+The length of any string in Lua must fit in a Lua integer,
+and the string plus a small header must fit in <code>size_t</code>.
 
 
 <p>

@@ -314,7 +315,7 @@
 <pre>
      X = 1       -- Ok, global by default
      do
-       global Y  -- voids implicit initial declaration
+       global Y  -- voids the implicit initial declaration
        Y = 1     -- Ok, Y declared as global
        X = 1     -- ERROR, X not declared
      end

@@ -360,7 +361,7 @@
 <p>
 Notice that, in a declaration like <code>local x = x</code>,
 the new <code>x</code> being declared is not in scope yet,
-and so the <code>x</code> in the left-hand side refers to the outside variable.
+and so the <code>x</code> on the right-hand side refers to the outside variable.
 
 
 <p>

@@ -1895,7 +1896,8 @@
 	stat ::= <b>for</b> Name &lsquo;<b>=</b>&rsquo; exp &lsquo;<b>,</b>&rsquo; exp [&lsquo;<b>,</b>&rsquo; exp] <b>do</b> block <b>end</b>
 </pre><p>
 The given identifier (Name) defines the control variable,
-which is a new read-only variable local to the loop body (<em>block</em>).
+which is a new read-only (<code>const</code>) variable local to the loop body
+(<em>block</em>).
 
 
 <p>

@@ -1963,7 +1965,7 @@
 <p>
 The names <em>var_i</em> declare loop variables local to the loop body.
 The first of these variables is the <em>control variable</em>,
-which is a read-only variable.
+which is a read-only (<code>const</code>) variable.
 
 
 <p>

@@ -2015,15 +2017,21 @@
 
 <h3>3.3.7 &ndash; <a name="3.3.7">Variable Declarations</a></h3><p>
 Local and global variables can be declared anywhere inside a block.
-The declaration for locals can include an initialization:
+The declaration can include an initialization:
 
 <pre>
 	stat ::= <b>local</b> attnamelist [&lsquo;<b>=</b>&rsquo; explist]
-	stat ::= <b>global</b> attnamelist
+	stat ::= <b>global</b> attnamelist [&lsquo;<b>=</b>&rsquo; explist]
 </pre><p>
-If present, an initial assignment has the same semantics
+If there is no initialization,
+local variables are initialized with <b>nil</b>;
+global variables are left unchanged.
+Otherwise, the initialization gets the same adjustment
 of a multiple assignment (see <a href="#3.3.3">&sect;3.3.3</a>).
-Otherwise, all local variables are initialized with <b>nil</b>.
+Moreover, for global variables,
+the initialization will raise a runtime error
+if the variable is already defined,
+that is, it has a non-nil value.
 
 
 <p>

@@ -2084,7 +2092,8 @@
 
 <p>
 Note that, for global variables,
-the effect of any declaration is only syntactical:
+the effect of any declaration is only syntactical
+(except for the optional assignment):
 
 <pre>
      global X &lt;const&gt;, _G

@@ -2747,7 +2756,7 @@
 <h3>3.4.11 &ndash; <a name="3.4.11">Function Definitions</a></h3>
 
 <p>
-The syntax for function definition is
+The syntax for a function definition is
 
 <pre>
 	functiondef ::= <b>function</b> funcbody

@@ -2810,7 +2819,25 @@
 translates to
 
 <pre>
-     global f; f = function () <em>body</em> end
+     global f; global f = function () <em>body</em> end
+</pre><p>
+The second <b>global</b> makes the assignment an initialization,
+which will raise an error if that global is already defined.
+
+
+<p>
+The <em>colon</em> syntax
+is used to emulate <em>methods</em>,
+adding an implicit extra parameter <code>self</code> to the function.
+Thus, the statement
+
+<pre>
+     function t.a.b.c:f (<em>params</em>) <em>body</em> end
+</pre><p>
+is syntactic sugar for
+
+<pre>
+     t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end
 </pre>
 
 <p>

@@ -2826,11 +2853,29 @@
 
 
 <p>
+Results are returned using the <b>return</b> statement (see <a href="#3.3.4">&sect;3.3.4</a>).
+If control reaches the end of a function
+without encountering a <b>return</b> statement,
+then the function returns with no results.
+
+
+<p>
+
+There is a system-dependent limit on the number of values
+that a function may return.
+This limit is guaranteed to be at least 1000.
+
+
+
+<h4>Parameters</h4>
+
+<p>
 Parameters act as local variables that are
 initialized with the argument values:
 
 <pre>
-	parlist ::= namelist [&lsquo;<b>,</b>&rsquo; &lsquo;<b>...</b>&rsquo;] | &lsquo;<b>...</b>&rsquo;
+	parlist ::= namelist [&lsquo;<b>,</b>&rsquo; varargparam] | varargparam
+	varargparam ::= &lsquo;<b>...</b>&rsquo; [Name]
 </pre><p>
 When a Lua function is called,
 it adjusts its list of arguments to

@@ -2840,9 +2885,13 @@
 at the end of its parameter list.
 A variadic function does not adjust its argument list;
 instead, it collects all extra arguments and supplies them
-to the function through a <em>vararg expression</em>,
-which is also written as three dots.
-The value of this expression is a list of all actual extra arguments,
+to the function through a <em>vararg expression</em> and,
+if present, a <em>vararg table</em>.
+
+
+<p>
+A vararg expression is also written as three dots,
+and its value is a list of all actual extra arguments,
 similar to a function with multiple results (see <a href="#3.4.12">&sect;3.4.12</a>).
 
 

@@ -2873,33 +2922,31 @@
 </pre>
 
 <p>
-Results are returned using the <b>return</b> statement (see <a href="#3.3.4">&sect;3.3.4</a>).
-If control reaches the end of a function
-without encountering a <b>return</b> statement,
-then the function returns with no results.
+The presence of a varag table in a variadic function is indicated
+by a name after the three dots.
+When present,
+a vararg table behaves like a read-only local variable
+with the given name that is initialized with a table.
+In that table,
+the values at indices 1, 2, etc. are the extra arguments,
+and the value at index "<code>n</code>" is the number of extra arguments.
+In other words, the code behaves as if the function started with
+the following statement,
+assuming the standard behavior of <a href="#pdf-table.pack"><code>table.pack</code></a>:
 
+<pre>
+     local &lt;const&gt; name = table.pack(...)
+</pre>
 
 <p>
+As an optimization,
+if the vararg table is used only as a base in indexing expressions
+(the <code>t</code> in <code>t[exp]</code> or <code>t.id</code>) and it is not an upvalue,
+the code does not create an actual table and instead translates
+the indexing expressions into accesses to the internal vararg data.
 
-There is a system-dependent limit on the number of values
-that a function may return.
-This limit is guaranteed to be at least 1000.
-
-
-<p>
-The <em>colon</em> syntax
-is used to emulate <em>methods</em>,
-adding an implicit extra parameter <code>self</code> to the function.
-Thus, the statement
 
-<pre>
-     function t.a.b.c:f (<em>params</em>) <em>body</em> end
-</pre><p>
-is syntactic sugar for
 
-<pre>
-     t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end
-</pre>
 
 
 

@@ -2939,8 +2986,8 @@
 <li>A multiple assignment,
 for instance <code>a , b, c = e1, e2, e3</code> (see <a href="#3.3.3">&sect;3.3.3</a>).</li>
 
-<li>A local declaration,
-for instance <code>local a , b, c = e1, e2, e3</code> (see <a href="#3.3.7">&sect;3.3.7</a>).</li>
+<li>A local or global declaration,
+which is similar to a multiple assignment.</li>
 
 <li>The initial values in a generic <b>for</b> loop,
 for instance <code>for k in e1, e2, e3 do ... end</code> (see <a href="#3.3.5">&sect;3.3.5</a>).</li>

@@ -2951,8 +2998,7 @@
 must be <em>adjusted</em> to a specific length:
 the number of parameters in a call to a non-variadic function
 (see <a href="#3.4.11">&sect;3.4.11</a>),
-the number of variables in a multiple assignment or
-a local declaration,
+the number of variables in a multiple assignment or a declaration,
 and exactly four values for a generic <b>for</b> loop.
 The <em>adjustment</em> follows these rules:
 If there are more values than needed,

@@ -3422,7 +3468,16 @@
 For such errors, Lua does not call the message handler.
 </li>
 
-<li><b><a name="pdf-LUA_ERRERR"><code>LUA_ERRERR</code></a></b>:  error while running the message handler.</li>
+<li><b><a name="pdf-LUA_ERRERR"><code>LUA_ERRERR</code></a></b>: 
+stack overflow while running the message handler
+due to another stack overflow.
+More often than not,
+this error is the result of some other error while running
+a message handler.
+An error in a message handler will call the handler again,
+which will generate the error again, and so on,
+until this loop exhausts the stack and cause this error.
+</li>
 
 <li><b><a name="pdf-LUA_ERRSYNTAX"><code>LUA_ERRSYNTAX</code></a></b>:  syntax error during precompilation
 or format error in a binary chunk.</li>

@@ -3631,7 +3686,7 @@
                              size_t nsize);</pre>
 
 <p>
-The type of the memory-allocation function used by Lua states.
+The type of the memory-allocator function used by Lua states.
 The allocator function must provide a
 functionality similar to <code>realloc</code>,
 but not exactly the same.

@@ -3678,12 +3733,13 @@
 
 
 <p>
-Here is a simple implementation for the allocator function.
-It is used in the auxiliary library by <a href="#luaL_newstate"><code>luaL_newstate</code></a>.
+Here is a simple implementation for the allocator function,
+corresponding to the function <a href="#luaL_alloc"><code>luaL_alloc</code></a> from the
+auxiliary library.
 
 <pre>
-     static void *l_alloc (void *ud, void *ptr, size_t osize,
-                                                size_t nsize) {
+     void *luaL_alloc (void *ud, void *ptr, size_t osize,
+                                            size_t nsize) {
        (void)ud;  (void)osize;  /* not used */
        if (nsize == 0) {
          free(ptr);

@@ -4213,7 +4269,7 @@
 <pre>lua_Alloc lua_getallocf (lua_State *L, void **ud);</pre>
 
 <p>
-Returns the memory-allocation function of a given state.
+Returns the memory-allocator function of a given state.
 If <code>ud</code> is not <code>NULL</code>, Lua stores in <code>*ud</code> the
 opaque pointer given when the memory-allocator function was set.
 

@@ -4855,8 +4911,8 @@
 
 <hr><h3><a name="lua_numbertocstring"><code>lua_numbertocstring</code></a></h3><p>
 <span class="apii">[-0, +0, &ndash;]</span>
-<pre>unsigned (lua_numbertocstring) (lua_State *L, int idx,
-                                          char *buff);</pre>
+<pre>unsigned lua_numbertocstring (lua_State *L, int idx,
+                                        char *buff);</pre>
 
 <p>
 Converts the number at acceptable index <code>idx</code> to a string

@@ -5024,7 +5080,7 @@
 
 <hr><h3><a name="lua_pushexternalstring"><code>lua_pushexternalstring</code></a></h3><p>
 <span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>const char *(lua_pushexternalstring) (lua_State *L,
+<pre>const char *lua_pushexternalstring (lua_State *L,
                 const char *s, size_t len, lua_Alloc falloc, void *ud);</pre>
 
 <p>

@@ -5051,13 +5107,6 @@
 
 
 <p>
-Lua always internalizes strings with lengths up to 40 characters.
-So, for strings in that range,
-this function will immediately internalize the string
-and call <code>falloc</code> to free the buffer.
-
-
-<p>
 Even when using an external buffer,
 Lua still has to allocate a header for the string.
 In case of a memory-allocation error,

@@ -5068,7 +5117,7 @@
 
 
 <hr><h3><a name="lua_pushfstring"><code>lua_pushfstring</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
+<span class="apii">[-0, +1, <em>v</em>]</span>
 <pre>const char *lua_pushfstring (lua_State *L, const char *fmt, ...);</pre>
 
 <p>

@@ -5093,6 +5142,11 @@
 must form a valid conversion specifier.
 
 
+<p>
+Besides memory allocation errors,
+this function may raise an error if the resulting string is too large.
+
+
 
 
 

@@ -5140,7 +5194,7 @@
 
 
 <hr><h3><a name="lua_pushliteral"><code>lua_pushliteral</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
+<span class="apii">[-0, +1, <em>v</em>]</span>
 <pre>const char *lua_pushliteral (lua_State *L, const char *s);</pre>
 
 <p>

@@ -5153,7 +5207,7 @@
 
 
 <hr><h3><a name="lua_pushlstring"><code>lua_pushlstring</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
+<span class="apii">[-0, +1, <em>v</em>]</span>
 <pre>const char *lua_pushlstring (lua_State *L, const char *s, size_t len);</pre>
 
 <p>

@@ -5170,6 +5224,11 @@
 Returns a pointer to the internal copy of the string (see <a href="#4.1.3">&sect;4.1.3</a>).
 
 
+<p>
+Besides memory allocation errors,
+this function may raise an error if the string is too large.
+
+
 
 
 

@@ -6317,8 +6376,8 @@
 <li><b><code>namewhat</code></b>: 
 explains the <code>name</code> field.
 The value of <code>namewhat</code> can be
-<code>"global"</code>, <code>"local"</code>, <code>"method"</code>,
-<code>"field"</code>, <code>"upvalue"</code>, or <code>""</code> (the empty string),
+<code>"global"</code>, <code>"local"</code>, <code>"upvalue"</code>,
+<code>"field"</code>, <code>""</code> (the empty string), plus some other options,
 according to how the function was called.
 (Lua uses the empty string when no other option seems to apply.)
 </li>

@@ -7543,9 +7602,8 @@
 
 <p>
 Returns a value with a weak attempt for randomness.
-(It produces that value based on the current date and time
-and the address of an internal variable,
-in case the machine has Address Space Layout Randomization.)
+The parameter <code>L</code> can be <code>NULL</code>
+if there is no Lua state available.
 
 
 

@@ -7623,8 +7681,9 @@
 
 <p>
 Creates a new Lua state.
-It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with an
-allocator based on the ISO&nbsp;C allocation functions
+It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with <a href="#luaL_alloc"><code>luaL_alloc</code></a> as
+the allocator function and the result of <code>luaL_makeseed(NULL)</code>
+as the seed,
 and then sets a warning function and a panic function (see <a href="#4.4">&sect;4.4</a>)
 that print messages to the standard error output.
 

@@ -7924,6 +7983,17 @@
 
 
 
+<hr><h3><a name="luaL_alloc"><code>luaL_alloc</code></a></h3>
+<pre>void *luaL_alloc (void *ud, void *ptr, size_t osize, size_t nsize);</pre>
+
+<p>
+A standard allocator function for Lua (see <a href="#lua_Alloc"><code>lua_Alloc</code></a>),
+built on top of the C functions <code>realloc</code> and <code>free</code>.
+
+
+
+
+
 <hr><h3><a name="luaL_Stream"><code>luaL_Stream</code></a></h3>
 <pre>typedef struct luaL_Stream {
   FILE *f;

@@ -8341,7 +8411,7 @@
 
 
 <p>
-Lua rounds these values before storing them;
+Lua stores these values in a compressed format,
 so, the value returned as the previous value may not be
 exactly the last value set.
 </li>

@@ -8359,10 +8429,10 @@
 
 <p>
 <hr><h3><a name="pdf-dofile"><code>dofile ([filename])</code></a></h3>
-Opens the named file and executes its content as a Lua chunk.
+Opens the named file and executes its content as a Lua chunk,
+returning all values returned by the chunk.
 When called without arguments,
 <code>dofile</code> executes the content of the standard input (<code>stdin</code>).
-Returns all values returned by the chunk.
 In case of errors, <code>dofile</code> propagates the error
 to its caller.
 (That is, <code>dofile</code> does not run in protected mode.)

@@ -8560,13 +8630,13 @@
 
 <p>
 If <code>t</code> has a metamethod <code>__pairs</code>,
-calls it with <code>t</code> as argument and returns the first three
+calls it with <code>t</code> as argument and returns the first four
 results from the call.
 
 
 <p>
 Otherwise,
-returns three values: the <a href="#pdf-next"><code>next</code></a> function, the table <code>t</code>, and <b>nil</b>,
+returns the <a href="#pdf-next"><code>next</code></a> function, the table <code>t</code>, plus two <b>nil</b> values,
 so that the construction
 
 <pre>

@@ -8862,7 +8932,7 @@
 (either the original error that stopped the coroutine or
 errors in closing methods),
 this function returns <b>false</b> plus the error object;
-otherwise ir returns <b>true</b>.
+otherwise it returns <b>true</b>.
 
 
 

@@ -10630,6 +10700,21 @@
 
 
 <p>
+<hr><h3><a name="pdf-math.frexp"><code>math.frexp (x)</code></a></h3>
+
+
+<p>
+Returns two numbers <code>m</code> and <code>e</code> such that <em>x = m2<sup>e</sup></em>,
+where <code>e</code> is an integer.
+When <code>x</code> is zero, NaN, +inf, or -inf,
+<code>m</code> is equal to <code>x</code>;
+otherwise, the absolute value of <code>m</code>
+is in the range  <em>[0.5, 1)</em> .
+
+
+
+
+<p>
 <hr><h3><a name="pdf-math.huge"><code>math.huge</code></a></h3>
 
 

@@ -10641,6 +10726,16 @@
 
 
 <p>
+<hr><h3><a name="pdf-math.ldexp"><code>math.ldexp(m, e)</code></a></h3>
+
+
+<p>
+Returns <em>m2<sup>e</sup></em>, where <code>e</code> is an integer.
+
+
+
+
+<p>
 <hr><h3><a name="pdf-math.log"><code>math.log (x [, base])</code></a></h3>
 
 

@@ -10726,7 +10821,7 @@
 <p>
 When called without arguments,
 returns a pseudo-random float with uniform distribution
-in the range  <em>[0,1)</em>.  
+in the range  <em>[0, 1)</em>.  
 When called with two integers <code>m</code> and <code>n</code>,
 <code>math.random</code> returns a pseudo-random integer
 with uniform distribution in the range <em>[m, n]</em>.

@@ -12360,7 +12455,9 @@
 
 	funcbody ::= &lsquo;<b>(</b>&rsquo; [parlist] &lsquo;<b>)</b>&rsquo; block <b>end</b>
 
-	parlist ::= namelist [&lsquo;<b>,</b>&rsquo; &lsquo;<b>...</b>&rsquo;] | &lsquo;<b>...</b>&rsquo;
+	parlist ::= namelist [&lsquo;<b>,</b>&rsquo; varargparam] | varargparam
+
+	varargparam ::= &lsquo;<b>...</b>&rsquo; [Name]
 
 	tableconstructor ::= &lsquo;<b>{</b>&rsquo; [fieldlist] &lsquo;<b>}</b>&rsquo;
 

@@ -12388,7 +12485,7 @@
 
 <P CLASS="footer">
 Last update:
-Sat Jun 28 10:06:59 UTC 2025
+Sat Nov 15 00:41:28 UTC 2025
 </P>
 <!--
 Last change: revised for Lua 5.5.0

doc/readme.html

@@ -86,8 +86,8 @@
 You need to build it before using it.
 Building Lua should be straightforward
 because
-Lua is implemented in pure ANSI C and compiles unmodified in all known
-platforms that have an ANSI C compiler.
+Lua is implemented in pure ISO C and compiles unmodified in all known
+platforms that have an ISO C compiler.
 Lua also compiles unmodified as C++.
 The instructions given below for building Lua are for Unix-like platforms,
 such as Linux and macOS.

@@ -323,7 +323,7 @@
 
 <P CLASS="footer">
 Last update:
-Thu Jun 26 13:06:11 UTC 2025
+Tue Sep  2 21:25:09 UTC 2025
 </P>
 <!--
 Last change: revised for Lua 5.5.0

src/Makefile

@@ -127,7 +127,7 @@
 	$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX -DLUA_USE_READLINE" SYSLIBS="-lreadline"
 
 mingw:
-	$(MAKE) "LUA_A=lua54.dll" "LUA_T=lua.exe" \
+	$(MAKE) "LUA_A=lua55.dll" "LUA_T=lua.exe" \
 	"AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
 	"SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
 	$(MAKE) "LUAC_T=luac.exe" luac.exe

src/lapi.c

@@ -440,7 +440,13 @@
     case LUA_VSHRSTR: return cast(lua_Unsigned, tsvalue(o)->shrlen);
     case LUA_VLNGSTR: return cast(lua_Unsigned, tsvalue(o)->u.lnglen);
     case LUA_VUSERDATA: return cast(lua_Unsigned, uvalue(o)->len);
-    case LUA_VTABLE: return luaH_getn(hvalue(o));
+    case LUA_VTABLE: {
+      lua_Unsigned res;
+      lua_lock(L);
+      res = luaH_getn(L, hvalue(o));
+      lua_unlock(L);
+      return res;
+    }
     default: return 0;
   }
 }

@@ -478,7 +484,7 @@
 
 /*
 ** Returns a pointer to the internal representation of an object.
-** Note that ANSI C does not allow the conversion of a pointer to
+** Note that ISO C does not allow the conversion of a pointer to
 ** function to a 'void*', so the conversion here goes through
 ** a 'size_t'. (As the returned pointer is only informative, this
 ** conversion should not be a problem.)

@@ -679,7 +685,7 @@
 
 /*
 ** The following function assumes that the registry cannot be a weak
-** table, so that en mergency collection while using the global table
+** table; so, an emergency collection while using the global table
 ** cannot collect it.
 */
 static void getGlobalTable (lua_State *L, TValue *gt) {

src/lauxlib.c

@@ -742,7 +742,7 @@
 
 static const char *getF (lua_State *L, void *ud, size_t *size) {
   LoadF *lf = (LoadF *)ud;
-  (void)L;  /* not used */
+  UNUSED(L);
   if (lf->n > 0) {  /* are there pre-read characters to be read? */
     *size = lf->n;  /* return them (chars already in buffer) */
     lf->n = 0;  /* no more pre-read characters */

@@ -856,7 +856,7 @@
 
 static const char *getS (lua_State *L, void *ud, size_t *size) {
   LoadS *ls = (LoadS *)ud;
-  (void)L;  /* not used */
+  UNUSED(L);
   if (ls->size == 0) return NULL;
   *size = ls->size;
   ls->size = 0;

@@ -1046,8 +1046,8 @@
 }
 
 
-static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
-  (void)ud; (void)osize;  /* not used */
+void *luaL_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
+  UNUSED(ud); UNUSED(osize);
   if (nsize == 0) {
     free(ptr);
     return NULL;

@@ -1172,13 +1172,17 @@
 
 
 LUALIB_API unsigned int luaL_makeseed (lua_State *L) {
-  (void)L;  /* unused */
+  UNUSED(L);
   return luai_makeseed();
 }
 
 
-LUALIB_API lua_State *luaL_newstate (void) {
-  lua_State *L = lua_newstate(l_alloc, NULL, luai_makeseed());
+/*
+** Use the name with parentheses so that headers can redefine it
+** as a macro.
+*/
+LUALIB_API lua_State *(luaL_newstate) (void) {
+  lua_State *L = lua_newstate(luaL_alloc, NULL, luaL_makeseed(NULL));
   if (l_likely(L)) {
     lua_atpanic(L, &panic);
     lua_setwarnf(L, warnfoff, L);  /* default is warnings off */

src/lauxlib.h

@@ -81,6 +81,9 @@
 LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
 LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
 
+LUALIB_API void *luaL_alloc (void *ud, void *ptr, size_t osize,
+                                                  size_t nsize);
+
 
 /* predefined references */
 #define LUA_NOREF       (-2)

src/lbaselib.c

@@ -279,21 +279,22 @@
 
 static int pairscont (lua_State *L, int status, lua_KContext k) {
   (void)L; (void)status; (void)k;  /* unused */
-  return 3;
+  return 4;  /* __pairs did all the work, just return its results */
 }
 
 static int luaB_pairs (lua_State *L) {
   luaL_checkany(L, 1);
   if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) {  /* no metamethod? */
-    lua_pushcfunction(L, luaB_next);  /* will return generator, */
-    lua_pushvalue(L, 1);  /* state, */
-    lua_pushnil(L);  /* and initial value */
+    lua_pushcfunction(L, luaB_next);  /* will return generator and */
+    lua_pushvalue(L, 1);  /* state */
+    lua_pushnil(L);  /* initial value */
+    lua_pushnil(L);  /* to-be-closed object */
   }
   else {
     lua_pushvalue(L, 1);  /* argument 'self' to metamethod */
-    lua_callk(L, 1, 3, 0, pairscont);  /* get 3 values from metamethod */
+    lua_callk(L, 1, 4, 0, pairscont);  /* get 4 values from metamethod */
   }
-  return 3;
+  return 4;
 }
 
 

src/lcode.c

@@ -45,6 +45,7 @@
   va_list argp;
   pushvfstring(ls->L, argp, fmt, msg);
   ls->t.token = 0;  /* remove "near <token>" from final message */
+  ls->linenumber = ls->lastline;  /* back to line of last used token */
   luaX_syntaxerror(ls, msg);
 }
 

@@ -565,20 +566,20 @@
   TValue val;
   Proto *f = fs->f;
   int tag = luaH_get(fs->kcache, key, &val);  /* query scanner table */
-  int k;
   if (!tagisempty(tag)) {  /* is there an index there? */
-    k = cast_int(ivalue(&val));
+    int k = cast_int(ivalue(&val));
     /* collisions can happen only for float keys */
     lua_assert(ttisfloat(key) || luaV_rawequalobj(&f->k[k], v));
     return k;  /* reuse index */
   }
-  /* constant not found; create a new entry */
-  k = addk(fs, f, v);
-  /* cache it for reuse; numerical value does not need GC barrier;
-     table is not a metatable, so it does not need to invalidate cache */
-  setivalue(&val, k);
-  luaH_set(fs->ls->L, fs->kcache, key, &val);
-  return k;
+  else {  /* constant not found; create a new entry */
+    int k = addk(fs, f, v);
+    /* cache it for reuse; numerical value does not need GC barrier;
+       table is not a metatable, so it does not need to invalidate cache */
+    setivalue(&val, k);
+    luaH_set(fs->ls->L, fs->kcache, key, &val);
+    return k;
+  }
 }
 
 

@@ -604,13 +605,14 @@
 /*
 ** Add a float to list of constants and return its index. Floats
 ** with integral values need a different key, to avoid collision
-** with actual integers. To that, we add to the number its smaller
+** with actual integers. To that end, we add to the number its smaller
 ** power-of-two fraction that is still significant in its scale.
-** For doubles, that would be 1/2^52.
+** (For doubles, the fraction would be 2^-52).
 ** This method is not bulletproof: different numbers may generate the
 ** same key (e.g., very large numbers will overflow to 'inf') and for
-** floats larger than 2^53 the result is still an integer. At worst,
-** this only wastes an entry with a duplicate.
+** floats larger than 2^53 the result is still an integer. For those
+** cases, just generate a new entry. At worst, this only wastes an entry
+** with a duplicate.
 */
 static int luaK_numberK (FuncState *fs, lua_Number r) {
   TValue o, kv;

@@ -625,7 +627,7 @@
     const lua_Number k =  r * (1 + q);  /* key */
     lua_Integer ik;
     setfltvalue(&kv, k);  /* key as a TValue */
-    if (!luaV_flttointeger(k, &ik, F2Ieq)) {  /* not an integral value? */
+    if (!luaV_flttointeger(k, &ik, F2Ieq)) {  /* not an integer value? */
       int n = k2proto(fs, &kv, &o);  /* use key */
       if (luaV_rawequalobj(&fs->f->k[n], &o))  /* correct value? */
         return n;

@@ -705,6 +707,22 @@
 
 
 /*
+** Get the value of 'var' in a register and generate an opcode to check
+** whether that register is nil. 'k' is the index of the variable name
+** in the list of constants. If its value cannot be encoded in Bx, a 0
+** will use '?' for the name.
+*/
+void luaK_codecheckglobal (FuncState *fs, expdesc *var, int k, int line) {
+  luaK_exp2anyreg(fs, var);
+  luaK_fixline(fs, line);
+  k = (k >= MAXARG_Bx) ? 0 : k + 1;
+  luaK_codeABx(fs, OP_ERRNNIL, var->u.info, k);
+  luaK_fixline(fs, line);
+  freeexp(fs, var);
+}
+
+
+/*
 ** Convert a constant in 'v' into an expression description 'e'
 */
 static void const2exp (TValue *v, expdesc *e) {

@@ -784,6 +802,15 @@
   }
 }
 
+/*
+** Change a vararg parameter into a regular local variable
+*/
+void luaK_vapar2local (FuncState *fs, expdesc *var) {
+  fs->f->flag |= PF_VATAB;  /* function will need a vararg table */
+  /* now a vararg parameter is equivalent to a regular local variable */
+  var->k = VLOCAL;
+}
+
 
 /*
 ** Ensure that expression 'e' is not a variable (nor a <const>).

@@ -795,6 +822,9 @@
       const2exp(const2val(fs, e), e);
       break;
     }
+    case VVARGVAR: {
+      luaK_vapar2local(fs, e);  /* turn it into a local variable */
+    }  /* FALLTHROUGH */
     case VLOCAL: {  /* already in a register */
       int temp = e->u.var.ridx;
       e->u.info = temp;  /* (can't do a direct assignment; values overlap) */

@@ -829,6 +859,12 @@
       e->k = VRELOC;
       break;
     }
+    case VVARGIND: {
+      freeregs(fs, e->u.ind.t, e->u.ind.idx);
+      e->u.info = luaK_codeABC(fs, OP_GETVARG, 0, e->u.ind.t, e->u.ind.idx);
+      e->k = VRELOC;
+      break;
+    }
     case VVARARG: case VCALL: {
       luaK_setoneret(fs, e);
       break;

@@ -991,11 +1027,11 @@
 
 
 /*
-** Ensures final expression result is either in a register
-** or in an upvalue.
+** Ensures final expression result is either in a register,
+** in an upvalue, or it is the vararg parameter.
 */
 void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
-  if (e->k != VUPVAL || hasjumps(e))
+  if ((e->k != VUPVAL && e->k != VVARGVAR) || hasjumps(e))
     luaK_exp2anyreg(fs, e);
 }
 

@@ -1090,6 +1126,10 @@
       codeABRK(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, ex);
       break;
     }
+    case VVARGIND: {
+      fs->f->flag |= PF_VATAB;  /* function will need a vararg table */
+      /* now, assignment is to a regular table */
+    }  /* FALLTHROUGH */
     case VINDEXED: {
       codeABRK(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, ex);
       break;

@@ -1162,7 +1202,7 @@
 /*
 ** Emit code to go through if 'e' is false, jump otherwise.
 */
-void luaK_goiffalse (FuncState *fs, expdesc *e) {
+static void luaK_goiffalse (FuncState *fs, expdesc *e) {
   int pc;  /* pc of new jump */
   luaK_dischargevars(fs, e);
   switch (e->k) {

@@ -1223,7 +1263,7 @@
 ** Check whether expression 'e' is a short literal string
 */
 static int isKstr (FuncState *fs, expdesc *e) {
-  return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B &&
+  return (e->k == VK && !hasjumps(e) && e->u.info <= MAXINDEXRK &&
           ttisshrstring(&fs->f->k[e->u.info]));
 }
 

@@ -1301,6 +1341,13 @@
 }
 
 
+/* auxiliary function to define indexing expressions */
+static void fillidxk (expdesc *t, int idx, expkind k) {
+  t->u.ind.idx = cast_byte(idx);
+  t->k = k;
+}
+
+
 /*
 ** Create expression 't[k]'. 't' must have its final result already in a
 ** register or upvalue. Upvalues can only be indexed by literal strings.

@@ -1312,31 +1359,30 @@
   if (k->k == VKSTR)
     keystr = str2K(fs, k);
   lua_assert(!hasjumps(t) &&
-             (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL));
+             (t->k == VLOCAL || t->k == VVARGVAR ||
+              t->k == VNONRELOC || t->k == VUPVAL));
   if (t->k == VUPVAL && !isKstr(fs, k))  /* upvalue indexed by non 'Kstr'? */
     luaK_exp2anyreg(fs, t);  /* put it in a register */
   if (t->k == VUPVAL) {
     lu_byte temp = cast_byte(t->u.info);  /* upvalue index */
     t->u.ind.t = temp;  /* (can't do a direct assignment; values overlap) */
     lua_assert(isKstr(fs, k));
-    t->u.ind.idx = cast_short(k->u.info);  /* literal short string */
-    t->k = VINDEXUP;
+    fillidxk(t, k->u.info, VINDEXUP);  /* literal short string */
+  }
+  else if (t->k == VVARGVAR) {  /* indexing the vararg parameter? */
+    lua_assert(t->u.ind.t == fs->f->numparams);
+    t->u.ind.t = cast_byte(t->u.var.ridx);
+    fillidxk(t, luaK_exp2anyreg(fs, k), VVARGIND);  /* register */
   }
   else {
     /* register index of the table */
     t->u.ind.t = cast_byte((t->k == VLOCAL) ? t->u.var.ridx: t->u.info);
-    if (isKstr(fs, k)) {
-      t->u.ind.idx = cast_short(k->u.info);  /* literal short string */
-      t->k = VINDEXSTR;
-    }
-    else if (isCint(k)) {  /* int. constant in proper range? */
-      t->u.ind.idx = cast_short(k->u.ival);
-      t->k = VINDEXI;
-    }
-    else {
-      t->u.ind.idx = cast_short(luaK_exp2anyreg(fs, k));  /* register */
-      t->k = VINDEXED;
-    }
+    if (isKstr(fs, k))
+      fillidxk(t, k->u.info, VINDEXSTR);  /* literal short string */
+    else if (isCint(k))  /* int. constant in proper range? */
+      fillidxk(t, cast_int(k->u.ival), VINDEXI);
+    else
+      fillidxk(t, luaK_exp2anyreg(fs, k), VINDEXED);  /* register */
   }
   t->u.ind.keystr = keystr;  /* string index in 'k' */
   t->u.ind.ro = 0;  /* by default, not read-only */

@@ -1900,9 +1946,14 @@
           SETARG_C(*pc, p->numparams + 1);  /* signal that it is vararg */
         break;
       }
-      case OP_JMP: {
+      case OP_GETVARG: {
+        if (p->flag & PF_VATAB)  /* function has a vararg table? */
+          SET_OPCODE(*pc, OP_GETTABLE);  /* must get vararg there */
+        break;
+      }
+      case OP_JMP: {  /* to optimize jumps to jumps */
         int target = finaltarget(p->code, i);
-        fixjump(fs, i, target);
+        fixjump(fs, i, target);  /* jump directly to final target */
         break;
       }
       default: break;

src/lcode.h

@@ -68,9 +68,12 @@
 LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v);
 LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
 LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
+LUAI_FUNC void luaK_codecheckglobal (FuncState *fs, expdesc *var, int k,
+                                                    int line);
 LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
 LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
 LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n);
+LUAI_FUNC void luaK_vapar2local (FuncState *fs, expdesc *var);
 LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
 LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);

@@ -79,7 +82,6 @@
 LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
 LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
 LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
 LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
 LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);

src/lctype.c

@@ -18,7 +18,7 @@
 
 
 #if defined (LUA_UCID)		/* accept UniCode IDentifiers? */
-/* consider all non-ascii codepoints to be alphabetic */
+/* consider all non-ASCII codepoints to be alphabetic */
 #define NONA		0x01
 #else
 #define NONA		0x00	/* default */

src/ldebug.c

@@ -814,6 +814,14 @@
 }
 
 
+l_noret luaG_errnnil (lua_State *L, LClosure *cl, int k) {
+  const char *globalname = "?";  /* default name if k == 0 */
+  if (k > 0)
+    kname(cl->p, k - 1, &globalname);
+  luaG_runerror(L, "global '%s' already defined", globalname);
+}
+
+
 /* add src:line information to 'msg' */
 const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
                                         int line) {

src/ldebug.h

@@ -53,6 +53,7 @@
                                                  const TValue *p2);
 LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
                                                  const TValue *p2);
+LUAI_FUNC l_noret luaG_errnnil (lua_State *L, LClosure *cl, int k);
 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);

src/ldo.c

@@ -57,10 +57,18 @@
 ** =======================================================
 */
 
+/* chained list of long jump buffers */
+typedef struct lua_longjmp {
+  struct lua_longjmp *previous;
+  jmp_buf b;
+  volatile TStatus status;  /* error code */
+} lua_longjmp;
+
+
 /*
 ** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
 ** default, Lua handles errors with exceptions when compiling as
-** C++ code, with _longjmp/_setjmp when asked to use them, and with
+** C++ code, with _longjmp/_setjmp when available (POSIX), and with
 ** longjmp/setjmp otherwise.
 */
 #if !defined(LUAI_THROW)				/* { */

@@ -69,38 +77,38 @@
 
 /* C++ exceptions */
 #define LUAI_THROW(L,c)		throw(c)
-#define LUAI_TRY(L,c,f,ud) \
-    try { (f)(L, ud); } catch(...) { if ((c)->status == 0) (c)->status = -1; }
-#define luai_jmpbuf		int  /* dummy field */
+
+static void LUAI_TRY (lua_State *L, lua_longjmp *c, Pfunc f, void *ud) {
+  try {
+    f(L, ud);  /* call function protected */
+  }
+  catch (lua_longjmp *c1) { /* Lua error */
+    if (c1 != c)  /* not the correct level? */
+      throw;  /* rethrow to upper level */
+  }
+  catch (...) {  /* non-Lua exception */
+    c->status = -1;  /* create some error code */
+  }
+}
+
 
 #elif defined(LUA_USE_POSIX)				/* }{ */
 
-/* in POSIX, try _longjmp/_setjmp (more efficient) */
+/* in POSIX, use _longjmp/_setjmp (more efficient) */
 #define LUAI_THROW(L,c)		_longjmp((c)->b, 1)
 #define LUAI_TRY(L,c,f,ud)	if (_setjmp((c)->b) == 0) ((f)(L, ud))
-#define luai_jmpbuf		jmp_buf
 
 #else							/* }{ */
 
 /* ISO C handling with long jumps */
 #define LUAI_THROW(L,c)		longjmp((c)->b, 1)
 #define LUAI_TRY(L,c,f,ud)	if (setjmp((c)->b) == 0) ((f)(L, ud))
-#define luai_jmpbuf		jmp_buf
 
 #endif							/* } */
 
 #endif							/* } */
 
 
-
-/* chain list of long jump buffers */
-struct lua_longjmp {
-  struct lua_longjmp *previous;
-  luai_jmpbuf b;
-  volatile TStatus status;  /* error code */
-};
-
-
 void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) {
   if (errcode == LUA_ERRMEM) {  /* memory error? */
     setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */

@@ -151,7 +159,7 @@
 
 TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
   l_uint32 oldnCcalls = L->nCcalls;
-  struct lua_longjmp lj;
+  lua_longjmp lj;
   lj.status = LUA_OK;
   lj.previous = L->errorJmp;  /* chain new error handler */
   L->errorJmp = &lj;

@@ -174,6 +182,20 @@
 #define STACKERRSPACE	200
 
 
+/*
+** LUAI_MAXSTACK limits the size of the Lua stack.
+** It must fit into INT_MAX/2.
+*/
+
+#if !defined(LUAI_MAXSTACK)
+#if 1000000 < (INT_MAX / 2)
+#define LUAI_MAXSTACK           1000000
+#else
+#define LUAI_MAXSTACK           (INT_MAX / 2u)
+#endif
+#endif
+
+
 /* maximum stack size that respects size_t */
 #define MAXSTACK_BYSIZET  ((MAX_SIZET / sizeof(StackValue)) - STACKERRSPACE)
 

@@ -189,7 +211,7 @@
 #define ERRORSTACKSIZE	(MAXSTACK + STACKERRSPACE)
 
 
-/* raise an error while running the message handler */
+/* raise a stack error while running the message handler */
 l_noret luaD_errerr (lua_State *L) {
   TString *msg = luaS_newliteral(L, "error in error handling");
   setsvalue2s(L, L->top.p, msg);

@@ -325,7 +347,7 @@
        a stack error; cannot grow further than that. */
     lua_assert(stacksize(L) == ERRORSTACKSIZE);
     if (raiseerror)
-      luaD_errerr(L);  /* error inside message handler */
+      luaD_errerr(L);  /* stack error inside message handler */
     return 0;  /* if not 'raiseerror', just signal it */
   }
   else if (n < MAXSTACK) {  /* avoids arithmetic overflows */

src/ldump.c

@@ -132,27 +132,31 @@
 
 
 /*
-** Dump a String. First dump its "size": size==0 means NULL;
-** size==1 is followed by an index and means "reuse saved string with
-** that index"; size>=2 is followed by the string contents with real
-** size==size-2 and means that string, which will be saved with
-** the next available index.
+** Dump a String. First dump its "size":
+** size==0 is followed by an index and means "reuse saved string with
+** that index"; index==0 means NULL.
+** size>=1 is followed by the string contents with real size==size-1 and
+** means that string, which will be saved with the next available index.
+** The real size does not include the ending '\0' (which is not dumped),
+** so adding 1 to it cannot overflow a size_t.
 */
 static void dumpString (DumpState *D, TString *ts) {
-  if (ts == NULL)
-    dumpSize(D, 0);
+  if (ts == NULL) {
+    dumpVarint(D, 0);  /* will "reuse" NULL */
+    dumpVarint(D, 0);  /* special index for NULL */
+  }
   else {
     TValue idx;
     int tag = luaH_getstr(D->h, ts, &idx);
     if (!tagisempty(tag)) {  /* string already saved? */
-      dumpVarint(D, 1);  /* reuse a saved string */
+      dumpVarint(D, 0);  /* reuse a saved string */
       dumpVarint(D, l_castS2U(ivalue(&idx)));  /* index of saved string */
     }
     else {  /* must write and save the string */
       TValue key, value;  /* to save the string in the hash */
       size_t size;
       const char *s = getlstr(ts, size);
-      dumpSize(D, size + 2);
+      dumpSize(D, size + 1);
       dumpVector(D, s, size + 1);  /* include ending '\0' */
       D->nstr++;  /* one more saved string */
       setsvalue(D->L, &key, ts);  /* the string is the key */

src/lfunc.c

@@ -196,8 +196,7 @@
 */
 void luaF_closeupval (lua_State *L, StkId level) {
   UpVal *uv;
-  StkId upl;  /* stack index pointed by 'uv' */
-  while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) {
+  while ((uv = L->openupval) != NULL && uplevel(uv) >= level) {
     TValue *slot = &uv->u.value;  /* new position for value */
     lua_assert(uplevel(uv) < L->top.p);
     luaF_unlinkupval(uv);  /* remove upvalue from 'openupval' list */

src/lgc.c

@@ -594,10 +594,10 @@
 */
 static int getmode (global_State *g, Table *h) {
   const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
-  if (mode == NULL || !ttisshrstring(mode))
-    return 0;  /* ignore non-(short)string modes */
+  if (mode == NULL || !ttisstring(mode))
+    return 0;  /* ignore non-string modes */
   else {
-    const char *smode = getshrstr(tsvalue(mode));
+    const char *smode = getstr(tsvalue(mode));
     const char *weakkey = strchr(smode, 'k');
     const char *weakvalue = strchr(smode, 'v');
     return ((weakkey != NULL) << 1) | (weakvalue != NULL);

@@ -624,7 +624,7 @@
         linkgclist(h, g->allweak);  /* must clear collected entries */
       break;
   }
-  return 1 + 2*sizenode(h) + h->asize;
+  return cast(l_mem, 1 + 2*sizenode(h) + h->asize);
 }
 
 

src/liolib.c

@@ -114,7 +114,7 @@
 
 #if !defined(l_fseek)		/* { */
 
-#if defined(LUA_USE_POSIX)	/* { */
+#if defined(LUA_USE_POSIX) || defined(LUA_USE_OFF_T)	/* { */
 
 #include <sys/types.h>
 

src/ljumptab.h

@@ -21,7 +21,7 @@
 #if 0
 ** you can update the following list with this command:
 **
-**  sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p'  lopcodes.h
+**  sed -n '/^OP_/!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p'  lopcodes.h
 **
 #endif
 

@@ -57,8 +57,8 @@
 &&L_OP_BANDK,
 &&L_OP_BORK,
 &&L_OP_BXORK,
-&&L_OP_SHRI,
 &&L_OP_SHLI,
+&&L_OP_SHRI,
 &&L_OP_ADD,
 &&L_OP_SUB,
 &&L_OP_MUL,

@@ -106,6 +106,8 @@
 &&L_OP_SETLIST,
 &&L_OP_CLOSURE,
 &&L_OP_VARARG,
+&&L_OP_GETVARG,
+&&L_OP_ERRNNIL,
 &&L_OP_VARARGPREP,
 &&L_OP_EXTRAARG
 

src/llimits.h

@@ -20,8 +20,8 @@
 /*
 ** 'l_mem' is a signed integer big enough to count the total memory
 ** used by Lua.  (It is signed due to the use of debt in several
-** computations.)  Usually, 'ptrdiff_t' should work, but we use 'long'
-** for 16-bit machines.
+** computations.) 'lu_mem' is a corresponding unsigned type.  Usually,
+** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines.
 */
 #if defined(LUAI_MEM)		/* { external definitions? */
 typedef LUAI_MEM l_mem;

@@ -60,13 +60,6 @@
 			  : cast_sizet(LUA_MAXINTEGER))
 
 /*
-** floor of the log2 of the maximum signed value for integral type 't'.
-** (That is, maximum 'n' such that '2^n' fits in the given signed type.)
-*/
-#define log2maxs(t)	(l_numbits(t) - 2)
-
-
-/*
 ** test whether an unsigned value is a power of 2 (or zero)
 */
 #define ispow2(x)	(((x) & ((x) - 1)) == 0)

@@ -287,6 +280,55 @@
 #endif
 
 
+
+/*
+** lua_numbertointeger converts a float number with an integral value
+** to an integer, or returns 0 if the float is not within the range of
+** a lua_Integer.  (The range comparisons are tricky because of
+** rounding. The tests here assume a two-complement representation,
+** where MININTEGER always has an exact representation as a float;
+** MAXINTEGER may not have one, and therefore its conversion to float
+** may have an ill-defined value.)
+*/
+#define lua_numbertointeger(n,p) \
+  ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
+   (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
+      (*(p) = (LUA_INTEGER)(n), 1))
+
+
+
+/*
+** LUAI_FUNC is a mark for all extern functions that are not to be
+** exported to outside modules.
+** LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables,
+** none of which to be exported to outside modules (LUAI_DDEF for
+** definitions and LUAI_DDEC for declarations).
+** Elf and MACH/gcc (versions 3.2 and later) mark them as "hidden" to
+** optimize access when Lua is compiled as a shared library. Not all elf
+** targets support this attribute. Unfortunately, gcc does not offer
+** a way to check whether the target offers that support, and those
+** without support give a warning about it. To avoid these warnings,
+** change to the default definition.
+*/
+#if !defined(LUAI_FUNC)
+
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+    (defined(__ELF__) || defined(__MACH__))
+#define LUAI_FUNC	__attribute__((visibility("internal"))) extern
+#else
+#define LUAI_FUNC	extern
+#endif
+
+#define LUAI_DDEC(dec)	LUAI_FUNC dec
+#define LUAI_DDEF	/* empty */
+
+#endif
+
+
+/* Give these macros simpler names for internal use */
+#define l_likely(x)	luai_likely(x)
+#define l_unlikely(x)	luai_unlikely(x)
+
 /*
 ** {==================================================================
 ** "Abstraction Layer" for basic report of messages and errors

src/lmathlib.c

@@ -38,31 +38,37 @@
   return 1;
 }
 
+
 static int math_sin (lua_State *L) {
   lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
   return 1;
 }
 
+
 static int math_cos (lua_State *L) {
   lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
   return 1;
 }
 
+
 static int math_tan (lua_State *L) {
   lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
   return 1;
 }
 
+
 static int math_asin (lua_State *L) {
   lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
   return 1;
 }
 
+
 static int math_acos (lua_State *L) {
   lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
   return 1;
 }
 
+
 static int math_atan (lua_State *L) {
   lua_Number y = luaL_checknumber(L, 1);
   lua_Number x = luaL_optnumber(L, 2, 1);

@@ -167,6 +173,7 @@
   return 1;
 }
 
+
 static int math_log (lua_State *L) {
   lua_Number x = luaL_checknumber(L, 1);
   lua_Number res;

@@ -188,22 +195,42 @@
   return 1;
 }
 
+
 static int math_exp (lua_State *L) {
   lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
   return 1;
 }
 
+
 static int math_deg (lua_State *L) {
   lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
   return 1;
 }
 
+
 static int math_rad (lua_State *L) {
   lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
   return 1;
 }
 
 
+static int math_frexp (lua_State *L) {
+  lua_Number x = luaL_checknumber(L, 1);
+  int ep;
+  lua_pushnumber(L, l_mathop(frexp)(x, &ep));
+  lua_pushinteger(L, ep);
+  return 2;
+}
+
+
+static int math_ldexp (lua_State *L) {
+  lua_Number x = luaL_checknumber(L, 1);
+  int ep = (int)luaL_checkinteger(L, 2);
+  lua_pushnumber(L, l_mathop(ldexp)(x, ep));
+  return 1;
+}
+
+
 static int math_min (lua_State *L) {
   int n = lua_gettop(L);  /* number of arguments */
   int imin = 1;  /* index of current minimum value */

@@ -251,7 +278,7 @@
 */
 
 /*
-** This code uses lots of shifts. ANSI C does not allow shifts greater
+** This code uses lots of shifts. ISO C does not allow shifts greater
 ** than or equal to the width of the type being shifted, so some shifts
 ** are written in convoluted ways to match that restriction. For
 ** preprocessor tests, it assumes a width of 32 bits, so the maximum

@@ -666,20 +693,6 @@
   return 1;
 }
 
-static int math_frexp (lua_State *L) {
-  int e;
-  lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
-  lua_pushinteger(L, e);
-  return 2;
-}
-
-static int math_ldexp (lua_State *L) {
-  lua_Number x = luaL_checknumber(L, 1);
-  int ep = (int)luaL_checkinteger(L, 2);
-  lua_pushnumber(L, l_mathop(ldexp)(x, ep));
-  return 1;
-}
-
 static int math_log10 (lua_State *L) {
   lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
   return 1;

@@ -702,7 +715,9 @@
   {"tointeger", math_toint},
   {"floor", math_floor},
   {"fmod",   math_fmod},
+  {"frexp", math_frexp},
   {"ult",   math_ult},
+  {"ldexp", math_ldexp},
   {"log",   math_log},
   {"max",   math_max},
   {"min",   math_min},

@@ -718,8 +733,6 @@
   {"sinh",   math_sinh},
   {"tanh",   math_tanh},
   {"pow",   math_pow},
-  {"frexp", math_frexp},
-  {"ldexp", math_ldexp},
   {"log10", math_log10},
 #endif
   /* placeholders */

src/loadlib.c

@@ -307,6 +307,16 @@
 
 
 /*
+** External strings created by DLLs may need the DLL code to be
+** deallocated. This implies that a DLL can only be unloaded after all
+** its strings were deallocated. To ensure that, we create a 'library
+** string' to represent each DLL, and when this string is deallocated
+** it closes its corresponding DLL.
+** (The string itself is irrelevant; its userdata is the DLL pointer.)
+*/
+
+
+/*
 ** return registry.CLIBS[path]
 */
 static void *checkclib (lua_State *L, const char *path) {

@@ -320,34 +330,41 @@
 
 
 /*
-** registry.CLIBS[path] = plib        -- for queries
-** registry.CLIBS[#CLIBS + 1] = plib  -- also keep a list of all libraries
+** Deallocate function for library strings.
+** Unload the DLL associated with the string being deallocated.
 */
-static void addtoclib (lua_State *L, const char *path, void *plib) {
-  lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
-  lua_pushlightuserdata(L, plib);
-  lua_pushvalue(L, -1);
-  lua_setfield(L, -3, path);  /* CLIBS[path] = plib */
-  lua_rawseti(L, -2, luaL_len(L, -2) + 1);  /* CLIBS[#CLIBS + 1] = plib */
-  lua_pop(L, 1);  /* pop CLIBS table */
+static void *freelib (void *ud, void *ptr, size_t osize, size_t nsize) {
+  /* string itself is irrelevant and static */
+  (void)ptr; (void)osize; (void)nsize;
+  lsys_unloadlib(ud);  /* unload library represented by the string */
+  return NULL;
 }
 
 
 /*
-** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
-** handles in list CLIBS
+** Create a library string that, when deallocated, will unload 'plib'
 */
-static int gctm (lua_State *L) {
-  lua_Integer n = luaL_len(L, 1);
-  for (; n >= 1; n--) {  /* for each handle, in reverse order */
-    lua_rawgeti(L, 1, n);  /* get handle CLIBS[n] */
-    lsys_unloadlib(lua_touserdata(L, -1));
-    lua_pop(L, 1);  /* pop handle */
-  }
-  return 0;
+static void createlibstr (lua_State *L, void *plib) {
+  /* common content for all library strings */
+  static const char dummy[] = "01234567890";
+  lua_pushexternalstring(L, dummy, sizeof(dummy) - 1, freelib, plib);
 }
 
 
+/*
+** registry.CLIBS[path] = plib          -- for queries.
+** Also create a reference to strlib, so that the library string will
+** only be collected when registry.CLIBS is collected.
+*/
+static void addtoclib (lua_State *L, const char *path, void *plib) {
+  lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
+  lua_pushlightuserdata(L, plib);
+  lua_setfield(L, -2, path);  /* CLIBS[path] = plib */
+  createlibstr(L, plib);
+  luaL_ref(L, -2);  /* keep library string in CLIBS */
+  lua_pop(L, 1);  /* pop CLIBS table */
+}
+
 
 /* error codes for 'lookforfunc' */
 #define ERRLIB		1

@@ -361,8 +378,8 @@
 ** Then, if 'sym' is '*', return true (as library has been loaded).
 ** Otherwise, look for symbol 'sym' in the library and push a
 ** C function with that symbol.
-** Return 0 and 'true' or a function in the stack; in case of
-** errors, return an error code and an error message in the stack.
+** Return 0 with 'true' or a function in the stack; in case of
+** errors, return an error code with an error message in the stack.
 */
 static int lookforfunc (lua_State *L, const char *path, const char *sym) {
   void *reg = checkclib(L, path);  /* check loaded C libraries */

@@ -704,21 +721,9 @@
 }
 
 
-/*
-** create table CLIBS to keep track of loaded C libraries,
-** setting a finalizer to close all libraries when closing state.
-*/
-static void createclibstable (lua_State *L) {
-  luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);  /* create CLIBS table */
-  lua_createtable(L, 0, 1);  /* create metatable for CLIBS */
-  lua_pushcfunction(L, gctm);
-  lua_setfield(L, -2, "__gc");  /* set finalizer for CLIBS table */
-  lua_setmetatable(L, -2);
-}
-
-
 LUAMOD_API int luaopen_package (lua_State *L) {
-  createclibstable(L);
+  luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);  /* create CLIBS table */
+  lua_pop(L, 1);  /* will not use it now */
   luaL_newlib(L, pk_funcs);  /* create 'package' table */
   createsearcherstable(L);
   /* set paths */

src/lobject.c

@@ -31,7 +31,8 @@
 
 
 /*
-** Computes ceil(log2(x))
+** Computes ceil(log2(x)), which is the smallest integer n such that
+** x <= (1 << n).
 */
 lu_byte luaO_ceillog2 (unsigned int x) {
   static const lu_byte log_2[256] = {  /* log_2[i - 1] = ceil(log2(i)) */

@@ -86,7 +87,7 @@
 ** overflow, so we check which order is best.
 */
 l_mem luaO_applyparam (lu_byte p, l_mem x) {
-  unsigned int m = p & 0xF;  /* mantissa */
+  int m = p & 0xF;  /* mantissa */
   int e = (p >> 4);  /* exponent */
   if (e > 0) {  /* normalized? */
     e--;  /* correct exponent */

@@ -385,7 +386,7 @@
 int luaO_utf8esc (char *buff, l_uint32 x) {
   int n = 1;  /* number of bytes put in buffer (backwards) */
   lua_assert(x <= 0x7FFFFFFFu);
-  if (x < 0x80)  /* ascii? */
+  if (x < 0x80)  /* ASCII? */
     buff[UTF8BUFFSZ - 1] = cast_char(x);
   else {  /* need continuation bytes */
     unsigned int mfb = 0x3f;  /* maximum that fits in first byte */

src/lobject.h

@@ -418,6 +418,7 @@
 
 
 #define strisshr(ts)	((ts)->shrlen >= 0)
+#define isextstr(ts)	(ttislngstring(ts) && tsvalue(ts)->shrlen != LSTRREG)
 
 
 /*

@@ -582,8 +583,10 @@
 /*
 ** Flags in Prototypes
 */
-#define PF_ISVARARG	1
-#define PF_FIXED	2  /* prototype has parts in fixed memory */
+#define PF_ISVARARG	1  /* function is vararg */
+#define PF_VAVAR	2  /* function has vararg parameter */
+#define PF_VATAB	4  /* function has vararg table */
+#define PF_FIXED	8  /* prototype has parts in fixed memory */
 
 
 /*

src/lopcodes.c

@@ -53,8 +53,8 @@
  ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_BANDK */
  ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_BORK */
  ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_BXORK */
- ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_SHRI */
  ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_SHLI */
+ ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_SHRI */
  ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_ADD */
  ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_SUB */
  ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_MUL */

@@ -102,6 +102,8 @@
  ,opmode(0, 0, 1, 0, 0, ivABC)		/* OP_SETLIST */
  ,opmode(0, 0, 0, 0, 1, iABx)		/* OP_CLOSURE */
  ,opmode(0, 1, 0, 0, 1, iABC)		/* OP_VARARG */
+ ,opmode(0, 0, 0, 0, 1, iABC)		/* OP_GETVARG */
+ ,opmode(0, 0, 0, 0, 0, iABx)		/* OP_ERRNNIL */
  ,opmode(0, 0, 1, 0, 1, iABC)		/* OP_VARARGPREP */
  ,opmode(0, 0, 0, 0, 0, iAx)		/* OP_EXTRAARG */
 };

src/lopcodes.h

@@ -272,8 +272,8 @@
 OP_BORK,/*	A B C	R[A] := R[B] | K[C]:integer			*/
 OP_BXORK,/*	A B C	R[A] := R[B] ~ K[C]:integer			*/
 
-OP_SHRI,/*	A B sC	R[A] := R[B] >> sC				*/
 OP_SHLI,/*	A B sC	R[A] := sC << R[B]				*/
+OP_SHRI,/*	A B sC	R[A] := R[B] >> sC				*/
 
 OP_ADD,/*	A B C	R[A] := R[B] + R[C]				*/
 OP_SUB,/*	A B C	R[A] := R[B] - R[C]				*/

@@ -338,7 +338,11 @@
 
 OP_VARARG,/*	A C	R[A], R[A+1], ..., R[A+C-2] = vararg		*/
 
-OP_VARARGPREP,/*A	(adjust vararg parameters)			*/
+OP_GETVARG, /* A B C	R[A] := R[B][R[C]], R[B] is vararg parameter    */
+
+OP_ERRNNIL,/*	A Bx	raise error if R[A] ~= nil (K[Bx] is global name)*/
+
+OP_VARARGPREP,/* 	(adjust vararg parameters)			*/
 
 OP_EXTRAARG/*	Ax	extra (larger) argument for previous opcode	*/
 } OpCode;

src/lopnames.h

@@ -45,8 +45,8 @@
   "BANDK",
   "BORK",
   "BXORK",
-  "SHRI",
   "SHLI",
+  "SHRI",
   "ADD",
   "SUB",
   "MUL",

@@ -94,6 +94,8 @@
   "SETLIST",
   "CLOSURE",
   "VARARG",
+  "GETVARG",
+  "ERRNNIL",
   "VARARGPREP",
   "EXTRAARG",
   NULL

src/loslib.c

@@ -34,7 +34,7 @@
 #if defined(LUA_USE_WINDOWS)
 #define LUA_STRFTIMEOPTIONS  "aAbBcdHIjmMpSUwWxXyYzZ%" \
     "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"  /* two-char options */
-#elif defined(LUA_USE_C89)  /* ANSI C 89 (only 1-char options) */
+#elif defined(LUA_USE_C89)  /* C89 (only 1-char options) */
 #define LUA_STRFTIMEOPTIONS  "aAbBcdHIjmMpSUwWxXyYZ%"
 #else  /* C99 specification */
 #define LUA_STRFTIMEOPTIONS  "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \

src/lparser.c

@@ -30,7 +30,7 @@
 
 
 
-/* maximum number of variable declarationss per function (must be
+/* maximum number of variable declarations per function (must be
    smaller than 250, due to the bytecode format) */
 #define MAXVARS		200
 

@@ -197,7 +197,7 @@
   Dyndata *dyd = ls->dyd;
   Vardesc *var;
   luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
-             dyd->actvar.size, Vardesc, SHRT_MAX, "variable declarationss");
+             dyd->actvar.size, Vardesc, SHRT_MAX, "variable declarations");
   var = &dyd->actvar.arr[dyd->actvar.n++];
   var->vd.kind = kind;  /* default */
   var->vd.name = name;

@@ -279,7 +279,9 @@
 
 
 /*
-** Raises an error if variable described by 'e' is read only
+** Raises an error if variable described by 'e' is read only; moreover,
+** if 'e' is t[exp] where t is the vararg parameter, change it to index
+** a real table. (Virtual vararg tables cannot be changed.)
 */
 static void check_readonly (LexState *ls, expdesc *e) {
   FuncState *fs = ls->fs;

@@ -289,7 +291,7 @@
       varname = ls->dyd->actvar.arr[e->u.info].vd.name;
       break;
     }
-    case VLOCAL: {
+    case VLOCAL: case VVARGVAR: {
       Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx);
       if (vardesc->vd.kind != VDKREG)  /* not a regular variable? */
         varname = vardesc->vd.name;

@@ -301,6 +303,10 @@
         varname = up->name;
       break;
     }
+    case VVARGIND: {
+      fs->f->flag |= PF_VATAB;  /* function will need a vararg table */
+      e->k = VINDEXED;
+    }  /* FALLTHROUGH */
     case VINDEXUP: case VINDEXSTR: case VINDEXED: {  /* global variable */
       if (e->u.ind.ro)  /* read-only? */
         varname = tsvalue(&fs->f->k[e->u.ind.keystr]);

@@ -426,8 +432,11 @@
     else if (eqstr(n, vd->vd.name)) {  /* found? */
       if (vd->vd.kind == RDKCTC)  /* compile-time constant? */
         init_exp(var, VCONST, fs->firstlocal + i);
-      else  /* local variable */
+      else {  /* local variable */
         init_var(fs, var, i);
+        if (vd->vd.kind == RDKVAVAR)  /* vararg parameter? */
+          var->k = VVARGVAR;
+      }
       return cast_int(var->k);
     }
   }

@@ -467,8 +476,13 @@
 static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
   int v = searchvar(fs, n, var);  /* look up variables at current level */
   if (v >= 0) {  /* found? */
-    if (v == VLOCAL && !base)
-      markupval(fs, var->u.var.vidx);  /* local will be used as an upval */
+    if (!base) {
+      if (var->k == VVARGVAR)  /* vararg parameter? */
+        luaK_vapar2local(fs, var);  /* change it to a regular local */
+      if (var->k == VLOCAL)
+        markupval(fs, var->u.var.vidx);  /* will be used as an upvalue */
+    }
+    /* else nothing else to be done */
   }
   else {  /* not found at current level; try upvalues */
     int idx = searchupvalue(fs, n);  /* try existing upvalues */

@@ -485,6 +499,20 @@
 }
 
 
+static void buildglobal (LexState *ls, TString *varname, expdesc *var) {
+  FuncState *fs = ls->fs;
+  expdesc key;
+  init_exp(var, VGLOBAL, -1);  /* global by default */
+  singlevaraux(fs, ls->envn, var, 1);  /* get environment variable */
+  if (var->k == VGLOBAL)
+    luaK_semerror(ls, "_ENV is global when accessing variable '%s'",
+                      getstr(varname));
+  luaK_exp2anyregup(fs, var);  /* _ENV could be a constant */
+  codestring(&key, varname);  /* key is variable name */
+  luaK_indexed(fs, var, &key);  /* 'var' represents _ENV[varname] */
+}
+
+
 /*
 ** Find a variable with the given name 'n', handling global variables
 ** too.

@@ -494,18 +522,11 @@
   init_exp(var, VGLOBAL, -1);  /* global by default */
   singlevaraux(fs, varname, var, 1);
   if (var->k == VGLOBAL) {  /* global name? */
-    expdesc key;
     int info = var->u.info;
     /* global by default in the scope of a global declaration? */
     if (info == -2)
       luaK_semerror(ls, "variable '%s' not declared", getstr(varname));
-    singlevaraux(fs, ls->envn, var, 1);  /* get environment variable */
-    if (var->k == VGLOBAL)
-      luaK_semerror(ls, "_ENV is global when accessing variable '%s'",
-                        getstr(varname));
-    luaK_exp2anyregup(fs, var);  /* but could be a constant */
-    codestring(&key, varname);  /* key is variable name */
-    luaK_indexed(fs, var, &key);  /* env[varname] */
+    buildglobal(ls, varname, var);
     if (info != -1 && ls->dyd->actvar.arr[info].vd.kind == GDKCONST)
       var->u.ind.ro = 1;  /* mark variable as read-only */
     else  /* anyway must be a global */

@@ -526,6 +547,7 @@
 static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
   FuncState *fs = ls->fs;
   int needed = nvars - nexps;  /* extra values needed */
+  luaK_checkstack(fs, needed);
   if (hasmultret(e->k)) {  /* last expression has multiple returns? */
     int extra = needed + 1;  /* discount last expression itself */
     if (extra < 0)

@@ -665,7 +687,7 @@
 
 
 /*
-** Traverse the pending goto's of the finishing block checking whether
+** Traverse the pending gotos of the finishing block checking whether
 ** each match some label of that block. Those that do not match are
 ** "exported" to the outer block, to be solved there. In particular,
 ** its 'nactvar' is updated with the level of the inner block,

@@ -898,6 +920,19 @@
 } ConsControl;
 
 
+/*
+** Maximum number of elements in a constructor, to control the following:
+** * counter overflows;
+** * overflows in 'extra' for OP_NEWTABLE and OP_SETLIST;
+** * overflows when adding multiple returns in OP_SETLIST.
+*/
+#define MAX_CNST	(INT_MAX/2)
+#if MAX_CNST/(MAXARG_vC + 1) > MAXARG_Ax
+#undef MAX_CNST
+#define MAX_CNST	(MAXARG_Ax * (MAXARG_vC + 1))
+#endif
+
+
 static void recfield (LexState *ls, ConsControl *cc) {
   /* recfield -> (NAME | '['exp']') = exp */
   FuncState *fs = ls->fs;

@@ -918,7 +953,7 @@
 
 
 static void closelistfield (FuncState *fs, ConsControl *cc) {
-  if (cc->v.k == VVOID) return;  /* there is no list item */
+  lua_assert(cc->tostore > 0);
   luaK_exp2nextreg(fs, &cc->v);
   cc->v.k = VVOID;
   if (cc->tostore >= cc->maxtostore) {

@@ -1006,10 +1041,12 @@
   checknext(ls, '{' /*}*/);
   cc.maxtostore = maxtostore(fs);
   do {
-    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
     if (ls->t.token == /*{*/ '}') break;
-    closelistfield(fs, &cc);
+    if (cc.v.k != VVOID)  /* is there a previous list item? */
+      closelistfield(fs, &cc);  /* close it */
     field(ls, &cc);
+    luaY_checklimit(fs, cc.tostore + cc.na + cc.nh, MAX_CNST,
+                    "items in a constructor");
   } while (testnext(ls, ',') || testnext(ls, ';'));
   check_match(ls, /*{*/ '}', '{' /*}*/, line);
   lastlistfield(fs, &cc);

@@ -1019,9 +1056,10 @@
 /* }====================================================================== */
 
 
-static void setvararg (FuncState *fs, int nparams) {
-  fs->f->flag |= PF_ISVARARG;
-  luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0);
+static void setvararg (FuncState *fs, int kind) {
+  lua_assert(kind & PF_ISVARARG);
+  fs->f->flag |= cast_byte(kind);
+  luaK_codeABC(fs, OP_VARARGPREP, 0, 0, 0);
 }
 
 

@@ -1030,7 +1068,7 @@
   FuncState *fs = ls->fs;
   Proto *f = fs->f;
   int nparams = 0;
-  int isvararg = 0;
+  int varargk = 0;
   if (ls->t.token != ')') {  /* is 'parlist' not empty? */
     do {
       switch (ls->t.token) {

@@ -1040,19 +1078,27 @@
           break;
         }
         case TK_DOTS: {
-          luaX_next(ls);
-          isvararg = 1;
+          varargk |= PF_ISVARARG;
+          luaX_next(ls);  /* skip '...' */
+          if (ls->t.token == TK_NAME) {
+            new_varkind(ls, str_checkname(ls), RDKVAVAR);
+            varargk |= PF_VAVAR;
+          }
           break;
         }
         default: luaX_syntaxerror(ls, "<name> or '...' expected");
       }
-    } while (!isvararg && testnext(ls, ','));
+    } while (!varargk && testnext(ls, ','));
   }
   adjustlocalvars(ls, nparams);
   f->numparams = cast_byte(fs->nactvar);
-  if (isvararg)
-    setvararg(fs, f->numparams);  /* declared vararg */
-  luaK_reserveregs(fs, fs->nactvar);  /* reserve registers for parameters */
+  if (varargk != 0) {
+    setvararg(fs, varargk);  /* declared vararg */
+    if (varargk & PF_VAVAR)
+      adjustlocalvars(ls, 1);  /* vararg parameter */
+  }
+  /* reserve registers for parameters (plus vararg parameter, if present) */
+  luaK_reserveregs(fs, fs->nactvar);
 }
 
 

@@ -1435,6 +1481,15 @@
   }
 }
 
+
+/* Create code to store the "top" register in 'var' */
+static void storevartop (FuncState *fs, expdesc *var) {
+  expdesc e;
+  init_exp(&e, VNONRELOC, fs->freereg - 1);
+  luaK_storevar(fs, var, &e);  /* will also free the top register */
+}
+
+
 /*
 ** Parse and compile a multiple assignment. The first "variable"
 ** (a 'suffixedexp') was already read by the caller.

@@ -1468,8 +1523,7 @@
       return;  /* avoid default */
     }
   }
-  init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
-  luaK_storevar(ls->fs, &lh->v, &e);
+  storevartop(ls->fs, &lh->v);  /* default assignment */
 }
 
 

@@ -1812,7 +1866,7 @@
   switch (kind) {
     case RDKTOCLOSE:
       luaK_semerror(ls, "global variables cannot be to-be-closed");
-      break;  /* to avoid warnings */
+      return kind;  /* to avoid warnings */
     case RDKCONST:
       return GDKCONST;  /* adjust kind for global variable */
     default:

@@ -1821,25 +1875,74 @@
 }
 
 
+static void checkglobal (LexState *ls, TString *varname, int line) {
+  FuncState *fs = ls->fs;
+  expdesc var;
+  int k;
+  buildglobal(ls, varname, &var);  /* create global variable in 'var' */
+  k = var.u.ind.keystr;  /* index of global name in 'k' */
+  luaK_codecheckglobal(fs, &var, k, line);
+}
+
+
+/*
+** Recursively traverse list of globals to be initalized. When
+** going, generate table description for the global. In the end,
+** after all indices have been generated, read list of initializing
+** expressions. When returning, generate the assignment of the value on
+** the stack to the corresponding table description. 'n' is the variable
+** being handled, range [0, nvars - 1].
+*/
+static void initglobal (LexState *ls, int nvars, int firstidx, int n,
+                        int line) {
+  if (n == nvars) {  /* traversed all variables? */
+    expdesc e;
+    int nexps = explist(ls, &e);  /* read list of expressions */
+    adjust_assign(ls, nvars, nexps, &e);
+  }
+  else {  /* handle variable 'n' */
+    FuncState *fs = ls->fs;
+    expdesc var;
+    TString *varname = getlocalvardesc(fs, firstidx + n)->vd.name;
+    buildglobal(ls, varname, &var);  /* create global variable in 'var' */
+    enterlevel(ls);  /* control recursion depth */
+    initglobal(ls, nvars, firstidx, n + 1, line);
+    leavelevel(ls);
+    checkglobal(ls, varname, line);
+    storevartop(fs, &var);
+  }
+}
+
+
+static void globalnames (LexState *ls, lu_byte defkind) {
+  FuncState *fs = ls->fs;
+  int nvars = 0;
+  int lastidx;  /* index of last registered variable */
+  do {  /* for each name */
+    TString *vname = str_checkname(ls);
+    lu_byte kind = getglobalattribute(ls, defkind);
+    lastidx = new_varkind(ls, vname, kind);
+    nvars++;
+  } while (testnext(ls, ','));
+  if (testnext(ls, '='))  /* initialization? */
+    initglobal(ls, nvars, lastidx - nvars + 1, 0, ls->linenumber);
+  fs->nactvar = cast_short(fs->nactvar + nvars);  /* activate declaration */
+}
+
+
 static void globalstat (LexState *ls) {
   /* globalstat -> (GLOBAL) attrib '*'
      globalstat -> (GLOBAL) attrib NAME attrib {',' NAME attrib} */
   FuncState *fs = ls->fs;
   /* get prefixed attribute (if any); default is regular global variable */
   lu_byte defkind = getglobalattribute(ls, GDKREG);
-  if (testnext(ls, '*')) {
+  if (!testnext(ls, '*'))
+    globalnames(ls, defkind);
+  else {
     /* use NULL as name to represent '*' entries */
     new_varkind(ls, NULL, defkind);
     fs->nactvar++;  /* activate declaration */
   }
-  else {
-    do {  /* list of names */
-      TString *vname = str_checkname(ls);
-      lu_byte kind = getglobalattribute(ls, defkind);
-      new_varkind(ls, vname, kind);
-      fs->nactvar++;  /* activate declaration */
-    } while (testnext(ls, ','));
-  }
 }
 
 

@@ -1850,8 +1953,9 @@
   TString *fname = str_checkname(ls);
   new_varkind(ls, fname, GDKREG);  /* declare global variable */
   fs->nactvar++;  /* enter its scope */
-  buildvar(ls, fname, &var);
+  buildglobal(ls, fname, &var);
   body(ls, &b, 0, ls->linenumber);  /* compile and return closure in 'b' */
+  checkglobal(ls, fname, line);
   luaK_storevar(fs, &var, &b);
   luaK_fixline(fs, line);  /* definition "happens" in the first line */
 }

@@ -2049,7 +2153,7 @@
   BlockCnt bl;
   Upvaldesc *env;
   open_func(ls, fs, &bl);
-  setvararg(fs, 0);  /* main function is always declared vararg */
+  setvararg(fs, PF_ISVARARG);  /* main function is always vararg */
   env = allocupvalue(fs);  /* ...set environment upvalue */
   env->instack = 1;
   env->idx = 0;

src/lparser.h

@@ -37,6 +37,8 @@
                  info = result register */
   VLOCAL,  /* local variable; var.ridx = register index;
               var.vidx = relative index in 'actvar.arr'  */
+  VVARGVAR,  /* vararg parameter; var.ridx = register index;
+              var.vidx = relative index in 'actvar.arr'  */
   VGLOBAL,  /* global variable;
                info = relative index in 'actvar.arr' (or -1 for
                       implicit declaration) */

@@ -49,6 +51,8 @@
                 ind.ro = true if it represents a read-only global;
                 ind.keystr = if key is a string, index in 'k' of that string;
                              -1 if key is not a string */
+  VVARGIND,  /* indexed vararg parameter;
+                ind.* as in VINDEXED */
   VINDEXUP,  /* indexed upvalue;
                 ind.idx = key's K index;
                 ind.* as in VINDEXED */

@@ -97,10 +101,11 @@
 /* kinds of variables */
 #define VDKREG		0   /* regular local */
 #define RDKCONST	1   /* local constant */
-#define RDKTOCLOSE	2   /* to-be-closed */
-#define RDKCTC		3   /* local compile-time constant */
-#define GDKREG		4   /* regular global */
-#define GDKCONST	5   /* global constant */
+#define RDKVAVAR	2   /* vararg parameter */
+#define RDKTOCLOSE	3   /* to-be-closed */
+#define RDKCTC		4   /* local compile-time constant */
+#define GDKREG		5   /* regular global */
+#define GDKCONST	6   /* global constant */
 
 /* variables that live in registers */
 #define varinreg(v)	((v)->vd.kind <= RDKTOCLOSE)

src/lstate.h

@@ -85,7 +85,7 @@
 ** they must be visited again at the end of the cycle), but they are
 ** marked black because assignments to them must activate barriers (to
 ** move them back to TOUCHED1).
-** - Open upvales are kept gray to avoid barriers, but they stay out
+** - Open upvalues are kept gray to avoid barriers, but they stay out
 ** of gray lists. (They don't even have a 'gclist' field.)
 */
 

@@ -232,7 +232,7 @@
 /* call is running a C function (still in first 16 bits) */
 #define CIST_C		(1u << (CIST_RECST + 3))
 /* call is on a fresh "luaV_execute" frame */
-#define CIST_FRESH	cast(l_uint32, CIST_C << 1)
+#define CIST_FRESH	(cast(l_uint32, CIST_C) << 1)
 /* function is closing tbc variables */
 #define CIST_CLSRET	(CIST_FRESH << 1)
 /* function has tbc variables to close */

@@ -249,10 +249,6 @@
 #define CIST_HOOKYIELD	(CIST_TAIL << 1)
 /* function "called" a finalizer */
 #define CIST_FIN	(CIST_HOOKYIELD << 1)
-#if defined(LUA_COMPAT_LT_LE)
-/* using __lt for __le */
-#define CIST_LEQ	(CIST_FIN << 1)
-#endif
 
 
 #define get_nresults(cs)  (cast_int((cs) & CIST_NRESULTS) - 1)

@@ -430,9 +426,9 @@
 
 /*
 ** macro to convert a Lua object into a GCObject
-** (The access to 'tt' tries to ensure that 'v' is actually a Lua object.)
 */
-#define obj2gco(v)	check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc))
+#define obj2gco(v)  \
+	check_exp(novariant((v)->tt) >= LUA_TSTRING, &(cast_u(v)->gc))
 
 
 /* actual number of total memory allocated */

src/lstring.c

@@ -39,18 +39,18 @@
 
 
 /*
-** equality for long strings
+** generic equality for strings
 */
-int luaS_eqlngstr (TString *a, TString *b) {
-  size_t len = a->u.lnglen;
-  lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR);
-  return (a == b) ||  /* same instance or... */
-    ((len == b->u.lnglen) &&  /* equal length and ... */
-     (memcmp(getlngstr(a), getlngstr(b), len) == 0));  /* equal contents */
+int luaS_eqstr (TString *a, TString *b) {
+  size_t len1, len2;
+  const char *s1 = getlstr(a, len1);
+  const char *s2 = getlstr(b, len2);
+  return ((len1 == len2) &&  /* equal length and ... */
+          (memcmp(s1, s2, len1) == 0));  /* equal contents */
 }
 
 
-unsigned luaS_hash (const char *str, size_t l, unsigned seed) {
+static unsigned luaS_hash (const char *str, size_t l, unsigned seed) {
   unsigned int h = seed ^ cast_uint(l);
   for (; l > 0; l--)
     h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1]));

@@ -315,28 +315,9 @@
 }
 
 
-static void f_pintern (lua_State *L, void *ud) {
-  struct NewExt *ne = cast(struct NewExt *, ud);
-  ne->ts = internshrstr(L, ne->s, ne->len);
-}
-
-
 TString *luaS_newextlstr (lua_State *L,
 	          const char *s, size_t len, lua_Alloc falloc, void *ud) {
   struct NewExt ne;
-  if (len <= LUAI_MAXSHORTLEN) {  /* short string? */
-    ne.s = s; ne.len = len;
-    if (!falloc)
-      f_pintern(L, &ne);  /* just internalize string */
-    else {
-      TStatus status = luaD_rawrunprotected(L, f_pintern, &ne);
-      (*falloc)(ud, cast_voidp(s), len + 1, 0);  /* free external string */
-      if (status != LUA_OK)  /* memory error? */
-        luaM_error(L);  /* re-raise memory error */
-    }
-    return ne.ts;
-  }
-  /* "normal" case: long strings */
   if (!falloc) {
     ne.kind = LSTRFIX;
     f_newext(L, &ne);  /* just create header */

@@ -357,3 +338,16 @@
 }
 
 
+/*
+** Normalize an external string: If it is short, internalize it.
+*/
+TString *luaS_normstr (lua_State *L, TString *ts) {
+  size_t len = ts->u.lnglen;
+  if (len > LUAI_MAXSHORTLEN)
+    return ts;  /* long string; keep the original */
+  else {
+    const char *str = getlngstr(ts);
+    return internshrstr(L, str, len);
+  }
+}
+

src/lstring.h

@@ -54,9 +54,8 @@
 #define eqshrstr(a,b)	check_exp((a)->tt == LUA_VSHRSTR, (a) == (b))
 
 
-LUAI_FUNC unsigned luaS_hash (const char *str, size_t l, unsigned seed);
 LUAI_FUNC unsigned luaS_hashlongstr (TString *ts);
-LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
+LUAI_FUNC int luaS_eqstr (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);

@@ -69,5 +68,6 @@
 LUAI_FUNC TString *luaS_newextlstr (lua_State *L,
 		const char *s, size_t len, lua_Alloc falloc, void *ud);
 LUAI_FUNC size_t luaS_sizelngstr (size_t len, int kind);
+LUAI_FUNC TString *luaS_normstr (lua_State *L, TString *ts);
 
 #endif

src/lstrlib.c

@@ -132,27 +132,31 @@
 }
 
 
+/*
+** MAX_SIZE is limited both by size_t and lua_Integer.
+** When x <= MAX_SIZE, x can be safely cast to size_t or lua_Integer.
+*/
 static int str_rep (lua_State *L) {
-  size_t l, lsep;
-  const char *s = luaL_checklstring(L, 1, &l);
+  size_t len, lsep;
+  const char *s = luaL_checklstring(L, 1, &len);
   lua_Integer n = luaL_checkinteger(L, 2);
   const char *sep = luaL_optlstring(L, 3, "", &lsep);
   if (n <= 0)
     lua_pushliteral(L, "");
-  else if (l_unlikely(l + lsep < l || l + lsep > MAX_SIZE / cast_sizet(n)))
+  else if (l_unlikely(len > MAX_SIZE - lsep ||
+               cast_st2S(len + lsep) > cast_st2S(MAX_SIZE) / n))
     return luaL_error(L, "resulting string too large");
   else {
-    size_t totallen = ((size_t)n * (l + lsep)) - lsep;
+    size_t totallen = (cast_sizet(n) * (len + lsep)) - lsep;
     luaL_Buffer b;
     char *p = luaL_buffinitsize(L, &b, totallen);
     while (n-- > 1) {  /* first n-1 copies (followed by separator) */
-      memcpy(p, s, l * sizeof(char)); p += l;
+      memcpy(p, s, len * sizeof(char)); p += len;
       if (lsep > 0) {  /* empty 'memcpy' is not that cheap */
-        memcpy(p, sep, lsep * sizeof(char));
-        p += lsep;
+        memcpy(p, sep, lsep * sizeof(char)); p += lsep;
       }
     }
-    memcpy(p, s, l * sizeof(char));  /* last copy (not followed by separator) */
+    memcpy(p, s, len * sizeof(char));  /* last copy without separator */
     luaL_pushresultsize(&b, totallen);
   }
   return 1;

@@ -265,11 +269,18 @@
 }
 
 
-static void trymt (lua_State *L, const char *mtname) {
+/*
+** To be here, either the first operand was a string or the first
+** operand didn't have a corresponding metamethod. (Otherwise, that
+** other metamethod would have been called.) So, if this metamethod
+** doesn't work, the only other option would be for the second
+** operand to have a different metamethod.
+*/
+static void trymt (lua_State *L, const char *mtkey, const char *opname) {
   lua_settop(L, 2);  /* back to the original arguments */
   if (l_unlikely(lua_type(L, 2) == LUA_TSTRING ||
-                 !luaL_getmetafield(L, 2, mtname)))
-    luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2,
+                 !luaL_getmetafield(L, 2, mtkey)))
+    luaL_error(L, "attempt to %s a '%s' with a '%s'", opname,
                   luaL_typename(L, -2), luaL_typename(L, -1));
   lua_insert(L, -3);  /* put metamethod before arguments */
   lua_call(L, 2, 1);  /* call metamethod */

@@ -280,7 +291,7 @@
   if (tonum(L, 1) && tonum(L, 2))
     lua_arith(L, op);  /* result will be on the top */
   else
-    trymt(L, mtname);
+    trymt(L, mtname, mtname + 2);
   return 1;
 }
 

@@ -1811,8 +1822,8 @@
         lua_Unsigned len = (lua_Unsigned)unpackint(L, data + pos,
                                           h.islittle, cast_int(size), 0);
         luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short");
-        lua_pushlstring(L, data + pos + size, len);
-        pos += len;  /* skip string */
+        lua_pushlstring(L, data + pos + size, cast_sizet(len));
+        pos += cast_sizet(len);  /* skip string */
         break;
       }
       case Kzstr: {

src/ltable.c

@@ -156,7 +156,7 @@
 ** The main computation should be just
 **     n = frexp(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
+** In a two-complement representation, INT_MAX may not have 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

@@ -234,41 +234,51 @@
 ** Check whether key 'k1' is equal to the key in node 'n2'. This
 ** equality is raw, so there are no metamethods. Floats with integer
 ** values have been normalized, so integers cannot be equal to
-** floats. It is assumed that 'eqshrstr' is simply pointer equality, so
-** that short strings are handled in the default case.
-** A true 'deadok' means to accept dead keys as equal to their original
-** values. All dead keys are compared in the default case, by pointer
-** identity. (Only collectable objects can produce dead keys.) Note that
-** dead long strings are also compared by identity.
-** Once a key is dead, its corresponding value may be collected, and
-** then another value can be created with the same address. If this
-** other value is given to 'next', 'equalkey' will signal a false
-** positive. In a regular traversal, this situation should never happen,
-** as all keys given to 'next' came from the table itself, and therefore
-** could not have been collected. Outside a regular traversal, we
-** have garbage in, garbage out. What is relevant is that this false
-** positive does not break anything.  (In particular, 'next' will return
-** some other valid item on the table or nil.)
+** floats. It is assumed that 'eqshrstr' is simply pointer equality,
+** so that short strings are handled in the default case.  The flag
+** 'deadok' means to accept dead keys as equal to their original values.
+** (Only collectable objects can produce dead keys.) Note that dead
+** long strings are also compared by identity.  Once a key is dead,
+** its corresponding value may be collected, and then another value
+** can be created with the same address. If this other value is given
+** to 'next', 'equalkey' will signal a false positive. In a regular
+** traversal, this situation should never happen, as all keys given to
+** 'next' came from the table itself, and therefore could not have been
+** collected. Outside a regular traversal, we have garbage in, garbage
+** out. What is relevant is that this false positive does not break
+** anything.  (In particular, 'next' will return some other valid item
+** on the table or nil.)
 */
 static int equalkey (const TValue *k1, const Node *n2, int deadok) {
-  if ((rawtt(k1) != keytt(n2)) &&  /* not the same variants? */
-       !(deadok && keyisdead(n2) && iscollectable(k1)))
-   return 0;  /* cannot be same key */
-  switch (keytt(n2)) {
-    case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE:
-      return 1;
-    case LUA_VNUMINT:
-      return (ivalue(k1) == keyival(n2));
-    case LUA_VNUMFLT:
-      return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2)));
-    case LUA_VLIGHTUSERDATA:
-      return pvalue(k1) == pvalueraw(keyval(n2));
-    case LUA_VLCF:
-      return fvalue(k1) == fvalueraw(keyval(n2));
-    case ctb(LUA_VLNGSTR):
-      return luaS_eqlngstr(tsvalue(k1), keystrval(n2));
-    default:
+  if (rawtt(k1) != keytt(n2)) {  /* not the same variants? */
+    if (keyisshrstr(n2) && ttislngstring(k1)) {
+      /* an external string can be equal to a short-string key */
+      return luaS_eqstr(tsvalue(k1), keystrval(n2));
+    }
+    else if (deadok && keyisdead(n2) && iscollectable(k1)) {
+      /* a collectable value can be equal to a dead key */
       return gcvalue(k1) == gcvalueraw(keyval(n2));
+   }
+   else
+     return 0;  /* otherwise, different variants cannot be equal */
+  }
+  else {  /* equal variants */
+    switch (keytt(n2)) {
+      case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE:
+        return 1;
+      case LUA_VNUMINT:
+        return (ivalue(k1) == keyival(n2));
+      case LUA_VNUMFLT:
+        return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2)));
+      case LUA_VLIGHTUSERDATA:
+        return pvalue(k1) == pvalueraw(keyval(n2));
+      case LUA_VLCF:
+        return fvalue(k1) == fvalueraw(keyval(n2));
+      case ctb(LUA_VLNGSTR):
+        return luaS_eqstr(tsvalue(k1), keystrval(n2));
+      default:
+        return gcvalue(k1) == gcvalueraw(keyval(n2));
+    }
   }
 }
 

@@ -1158,6 +1168,14 @@
       else if (l_unlikely(luai_numisnan(f)))
         luaG_runerror(L, "table index is NaN");
     }
+    else if (isextstr(key)) {  /* external string? */
+      /* If string is short, must internalize it to be used as table key */
+      TString *ts = luaS_normstr(L, tsvalue(key));
+      setsvalue2s(L, L->top.p++, ts);  /* anchor 'ts' (EXTRA_STACK) */
+      luaH_newkey(L, t, s2v(L->top.p - 1), value);
+      L->top.p--;
+      return;
+    }
     luaH_newkey(L, t, key, value);
   }
   else if (hres > 0) {  /* regular Node? */

@@ -1202,24 +1220,36 @@
 
 /*
 ** Try to find a boundary in the hash part of table 't'. From the
-** caller, we know that 'j' is zero or present and that 'j + 1' is
-** present. We want to find a larger key that is absent from the
-** table, so that we can do a binary search between the two keys to
-** find a boundary. We keep doubling 'j' until we get an absent index.
-** If the doubling would overflow, we try LUA_MAXINTEGER. If it is
-** absent, we are ready for the binary search. ('j', being max integer,
-** is larger or equal to 'i', but it cannot be equal because it is
-** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a
-** boundary. ('j + 1' cannot be a present integer key because it is
-** not a valid integer in Lua.)
-*/
-static lua_Unsigned hash_search (Table *t, lua_Unsigned j) {
-  lua_Unsigned i;
-  if (j == 0) j++;  /* the caller ensures 'j + 1' is present */
-  do {
+** caller, we know that 'asize + 1' is present. We want to find a larger
+** key that is absent from the table, so that we can do a binary search
+** between the two keys to find a boundary. We keep doubling 'j' until
+** we get an absent index.  If the doubling would overflow, we try
+** LUA_MAXINTEGER. If it is absent, we are ready for the binary search.
+** ('j', being max integer, is larger or equal to 'i', but it cannot be
+** equal because it is absent while 'i' is present.) Otherwise, 'j' is a
+** boundary. ('j + 1' cannot be a present integer key because it is not
+** a valid integer in Lua.)
+** About 'rnd': If we used a fixed algorithm, a bad actor could fill
+** a table with only the keys that would be probed, in such a way that
+** a small table could result in a huge length. To avoid that, we use
+** the state's seed as a source of randomness. For the first probe,
+** we "randomly double" 'i' by adding to it a random number roughly its
+** width.
+*/
+static lua_Unsigned hash_search (lua_State *L, Table *t, unsigned asize) {
+  lua_Unsigned i = asize + 1;  /* caller ensures t[i] is present */
+  unsigned rnd = G(L)->seed;
+  int n = (asize > 0) ? luaO_ceillog2(asize) : 0;  /* width of 'asize' */
+  unsigned mask = (1u << n) - 1;  /* 11...111 with the width of 'asize' */
+  unsigned incr = (rnd & mask) + 1;  /* first increment (at least 1) */
+  lua_Unsigned j = (incr <= l_castS2U(LUA_MAXINTEGER) - i) ? i + incr : i + 1;
+  rnd >>= n;  /* used 'n' bits from 'rnd' */
+  while (!hashkeyisempty(t, j)) {  /* repeat until an absent t[j] */
     i = j;  /* 'i' is a present index */
-    if (j <= l_castS2U(LUA_MAXINTEGER) / 2)
-      j *= 2;
+    if (j <= l_castS2U(LUA_MAXINTEGER)/2 - 1) {
+      j = j*2 + (rnd & 1);  /* try again with 2j or 2j+1 */
+      rnd >>= 1;
+    }
     else {
       j = LUA_MAXINTEGER;
       if (hashkeyisempty(t, j))  /* t[j] not present? */

@@ -1227,7 +1257,7 @@
       else  /* weird case */
         return j;  /* well, max integer is a boundary... */
     }
-  } while (!hashkeyisempty(t, j));  /* repeat until an absent t[j] */
+  }
   /* i < j  &&  t[i] present  &&  t[j] absent */
   while (j - i > 1u) {  /* do a binary search between them */
     lua_Unsigned m = (i + j) / 2;

@@ -1268,7 +1298,7 @@
 ** If there is no array part, or its last element is non empty, the
 ** border may be in the hash part.
 */
-lua_Unsigned luaH_getn (Table *t) {
+lua_Unsigned luaH_getn (lua_State *L, Table *t) {
   unsigned asize = t->asize;
   if (asize > 0) {  /* is there an array part? */
     const unsigned maxvicinity = 4;

@@ -1309,7 +1339,7 @@
   if (isdummy(t) || hashkeyisempty(t, asize + 1))
     return asize;  /* 'asize + 1' is empty */
   else  /* 'asize + 1' is also non empty */
-    return hash_search(t, asize);
+    return hash_search(L, t, asize);
 }
 
 

src/ltable.h

@@ -173,7 +173,7 @@
 LUAI_FUNC lu_mem luaH_size (Table *t);
 LUAI_FUNC void luaH_free (lua_State *L, Table *t);
 LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
-LUAI_FUNC lua_Unsigned luaH_getn (Table *t);
+LUAI_FUNC lua_Unsigned luaH_getn (lua_State *L, Table *t);
 
 
 #if defined(LUA_DEBUG)

src/ltm.c

@@ -196,28 +196,12 @@
 
 /*
 ** Calls an order tag method.
-** For lessequal, LUA_COMPAT_LT_LE keeps compatibility with old
-** behavior: if 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 luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
                       TMS event) {
   int tag = callbinTM(L, p1, p2, L->top.p, event);  /* try original event */
   if (tag >= 0)  /* found tag method? */
     return !tagisfalse(tag);
-#if defined(LUA_COMPAT_LT_LE)
-  else if (event == TM_LE) {
-    /* try '!(p2 < p1)' for '(p1 <= p2)' */
-    L->ci->callstatus |= CIST_LEQ;  /* mark it is doing 'lt' for 'le' */
-    tag = callbinTM(L, p2, p1, L->top.p, TM_LT);
-    L->ci->callstatus ^= CIST_LEQ;  /* clear mark */
-    if (tag >= 0)  /* found tag method? */
-      return tagisfalse(tag);
-  }
-#endif
   luaG_ordererror(L, p1, p2);  /* no metamethod found */
   return 0;  /* to avoid warnings */
 }

@@ -240,11 +224,38 @@
 }
 
 
-void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci,
-                         const Proto *p) {
+/*
+** Create a vararg table at the top of the stack, with 'n' elements
+** starting at 'f'.
+*/
+static void createvarargtab (lua_State *L, StkId f, int n) {
   int i;
-  int actual = cast_int(L->top.p - ci->func.p) - 1;  /* number of arguments */
-  int nextra = actual - nfixparams;  /* number of extra arguments */
+  TValue key, value;
+  Table *t = luaH_new(L);
+  sethvalue(L, s2v(L->top.p), t);
+  L->top.p++;
+  luaH_resize(L, t, cast_uint(n), 1);
+  setsvalue(L, &key, luaS_new(L, "n"));  /* key is "n" */
+  setivalue(&value, n);  /* value is n */
+  /* No need to anchor the key: Due to the resize, the next operation
+     cannot trigger a garbage collection */
+  luaH_set(L, t, &key, &value);  /* t.n = n */
+  for (i = 0; i < n; i++)
+    luaH_setint(L, t, i + 1, s2v(f + i));
+}
+
+
+/*
+** initial stack:  func arg1 ... argn extra1 ...
+**                 ^ ci->func                    ^ L->top
+** final stack: func nil ... nil extra1 ... func arg1 ... argn
+**                                          ^ ci->func         ^ L->top
+*/
+void luaT_adjustvarargs (lua_State *L, CallInfo *ci, const Proto *p) {
+  int i;
+  int totalargs = cast_int(L->top.p - ci->func.p) - 1;
+  int nfixparams = p->numparams;
+  int nextra = totalargs - nfixparams;  /* number of extra arguments */
   ci->u.l.nextraargs = nextra;
   luaD_checkstack(L, p->maxstacksize + 1);
   /* copy function to the top of the stack */

@@ -254,12 +265,40 @@
     setobjs2s(L, L->top.p++, ci->func.p + i);
     setnilvalue(s2v(ci->func.p + i));  /* erase original parameter (for GC) */
   }
-  ci->func.p += actual + 1;
-  ci->top.p += actual + 1;
+  if (p->flag & PF_VAVAR) {  /* is there a vararg parameter? */
+    if (p->flag & PF_VATAB)  /* does it need a vararg table? */
+      createvarargtab(L, ci->func.p + nfixparams + 1, nextra);
+    else  /* no table; set parameter to nil */
+      setnilvalue(s2v(L->top.p));
+  }
+  ci->func.p += totalargs + 1;
+  ci->top.p += totalargs + 1;
   lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p);
 }
 
 
+void luaT_getvararg (CallInfo *ci, StkId ra, TValue *rc) {
+  int nextra = ci->u.l.nextraargs;
+  lua_Integer n;
+  if (tointegerns(rc, &n)) {  /* integral value? */
+    if (l_castS2U(n) - 1 < cast_uint(nextra)) {
+      StkId slot = ci->func.p - nextra + cast_int(n) - 1;
+      setobjs2s(((lua_State*)NULL), ra, slot);
+      return;
+    }
+  }
+  else if (ttisstring(rc)) {  /* string value? */
+    size_t len;
+    const char *s = getlstr(tsvalue(rc), len);
+    if (len == 1 && s[0] == 'n') {  /* key is "n"? */
+      setivalue(s2v(ra), nextra);
+      return;
+    }
+  }
+  setnilvalue(s2v(ra));  /* else produce nil */
+}
+
+
 void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) {
   int i;
   int nextra = ci->u.l.nextraargs;

src/ltm.h

@@ -95,8 +95,9 @@
 LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
                                  int inv, int isfloat, TMS event);
 
-LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams,
-                                   struct CallInfo *ci, const Proto *p);
+LUAI_FUNC void luaT_adjustvarargs (lua_State *L, struct CallInfo *ci,
+                                                 const Proto *p);
+LUAI_FUNC void luaT_getvararg (CallInfo *ci, StkId ra, TValue *rc);
 LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci,
                                               StkId where, int wanted);
 

src/lua.c

@@ -303,7 +303,8 @@
       case '-':  /* '--' */
         if (argv[i][2] != '\0')  /* extra characters after '--'? */
           return has_error;  /* invalid option */
-        *first = i + 1;
+        /* if there is a script name, it comes after '--' */
+        *first = (argv[i + 1] != NULL) ? i + 1 : 0;
         return args;
       case '\0':  /* '-' */
         return args;  /* script "name" is '-' */

@@ -437,13 +438,24 @@
 **   the standard input.
 ** * lua_saveline defines how to "save" a read line in a "history".
 ** * lua_freeline defines how to free a line read by lua_readline.
-**
-** If lua_readline is defined, all of them should be defined.
 */
 
 #if !defined(lua_readline)	/* { */
+/* Otherwise, all previously listed functions should be defined. */
 
-/* Code to use the readline library, either statically or dynamically linked */
+#if defined(LUA_USE_READLINE)	/* { */
+/* Lua will be linked with '-lreadline' */
+
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#define lua_initreadline(L)	((void)L, rl_readline_name="lua")
+#define lua_readline(buff,prompt)	((void)buff, readline(prompt))
+#define lua_saveline(line)	add_history(line)
+#define lua_freeline(line)	free(line)
+
+#else		/* }{ */
+/* use dynamically loaded readline (or nothing) */
 
 /* pointer to 'readline' function (if any) */
 typedef char *(*l_readlineT) (const char *prompt);

@@ -479,22 +491,9 @@
 }
 
 
-#if defined(LUA_USE_READLINE)	/* { */
-
-/* assume Lua will be linked with '-lreadline' */
-#include <readline/readline.h>
-#include <readline/history.h>
-
-static void lua_initreadline(lua_State *L) {
-  UNUSED(L);
-  rl_readline_name = "lua";
-  l_readline = cast(l_readlineT, readline);
-  l_addhist = cast(l_addhistT, add_history);
-}
-
-#elif defined(LUA_USE_DLOPEN) && defined(LUA_READLINELIB)	/* }{ */
-
+#if defined(LUA_USE_DLOPEN) && defined(LUA_READLINELIB)		/* { */
 /* try to load 'readline' dynamically */
+
 #include <dlfcn.h>
 
 static void lua_initreadline (lua_State *L) {

@@ -507,15 +506,20 @@
       *name = "lua";
     l_readline = cast(l_readlineT, cast_func(dlsym(lib, "readline")));
     l_addhist = cast(l_addhistT, cast_func(dlsym(lib, "add_history")));
+    if (l_readline == NULL)
+      lua_warning(L, "unable to load 'readline'", 0);
   }
 }
 
-#else	/* }{ */
+#else		/* }{ */
+/* no dlopen or LUA_READLINELIB undefined */
 
-/* no readline; leave function pointers as NULL */
-#define lua_initreadline(L)	cast(void, L)
+/* Leave pointers with NULL */
+#define lua_initreadline(L)	((void)L)
 
-#endif	/* } */
+#endif		/* } */
+
+#endif				/* } */
 
 #endif				/* } */
 

src/lua.h

@@ -37,10 +37,10 @@
 
 /*
 ** Pseudo-indices
-** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
-** space after that to help overflow detection)
+** (The stack size is limited to INT_MAX/2; we keep some free empty
+** space after that to help overflow detection.)
 */
-#define LUA_REGISTRYINDEX	(-LUAI_MAXSTACK - 1000)
+#define LUA_REGISTRYINDEX	(-(INT_MAX/2 + 1000))
 #define lua_upvalueindex(i)	(LUA_REGISTRYINDEX - (i))
 
 

@@ -432,13 +432,6 @@
 ** compatibility macros
 ** ===============================================================
 */
-#if defined(LUA_COMPAT_APIINTCASTS)
-
-#define lua_pushunsigned(L,n)	lua_pushinteger(L, (lua_Integer)(n))
-#define lua_tounsignedx(L,i,is)	((lua_Unsigned)lua_tointegerx(L,i,is))
-#define lua_tounsigned(L,i)	lua_tounsignedx(L,(i),NULL)
-
-#endif
 
 #define lua_newuserdata(L,s)	lua_newuserdatauv(L,s,1)
 #define lua_getuservalue(L,idx)	lua_getiuservalue(L,idx,1)

src/luac.c

@@ -478,10 +478,10 @@
 	printf("%d %d %d",a,b,c);
 	printf(COMMENT); PrintConstant(f,c);
 	break;
-   case OP_SHRI:
+   case OP_SHLI:
 	printf("%d %d %d",a,b,sc);
 	break;
-   case OP_SHLI:
+   case OP_SHRI:
 	printf("%d %d %d",a,b,sc);
 	break;
    case OP_ADD:

@@ -645,6 +645,13 @@
 	printf(COMMENT);
 	if (c==0) printf("all out"); else printf("%d out",c-1);
 	break;
+   case OP_GETVARG:
+	printf("%d %d %d",a,b,c);
+	break;
+   case OP_ERRNNIL:
+	printf("%d %d",a,bx);
+	printf(COMMENT); PrintConstant(f,bx);
+	break;
    case OP_VARARGPREP:
 	printf("%d",a);
 	break;

@@ -662,7 +669,6 @@
  }
 }
 
-
 #define SS(x)	((x==1)?"":"s")
 #define S(x)	(int)(x),SS(x)
 

src/luaconf.h

@@ -59,7 +59,7 @@
 
 
 /*
-** When Posix DLL ('LUA_USE_DLOPEN') is enabled, the Lua stand-alone
+** When POSIX DLL ('LUA_USE_DLOPEN') is enabled, the Lua stand-alone
 ** application will try to dynamically link a 'readline' facility
 ** for its REPL.  In that case, LUA_READLINELIB is the name of the
 ** library it will look for those facilities.  If lua.c cannot open

@@ -76,7 +76,7 @@
 
 #if defined(LUA_USE_MACOSX)
 #define LUA_USE_POSIX
-#define LUA_USE_DLOPEN		/* MacOS does not need -ldl */
+#define LUA_USE_DLOPEN		/* macOS does not need -ldl */
 #define LUA_READLINELIB		"libedit.dylib"
 #endif
 

@@ -88,7 +88,7 @@
 
 
 #if defined(LUA_USE_C89) && defined(LUA_USE_POSIX)
-#error "Posix is not compatible with C89"
+#error "POSIX is not compatible with C89"
 #endif
 
 

@@ -138,7 +138,7 @@
 /*
 @@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats.
 */
-#define LUA_32BITS	0
+/* #define LUA_32BITS */
 
 
 /*

@@ -153,7 +153,7 @@
 #endif
 
 
-#if LUA_32BITS		/* { */
+#if defined(LUA_32BITS)	/* { */
 /*
 ** 32-bit integers and 'float'
 */

@@ -319,32 +319,13 @@
 ** More often than not the libs go together with the core.
 */
 #define LUALIB_API	LUA_API
-#define LUAMOD_API	LUA_API
-
 
-/*
-@@ LUAI_FUNC is a mark for all extern functions that are not to be
-** exported to outside modules.
-@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables,
-** none of which to be exported to outside modules (LUAI_DDEF for
-** definitions and LUAI_DDEC for declarations).
-** CHANGE them if you need to mark them in some special way. Elf/gcc
-** (versions 3.2 and later) mark them as "hidden" to optimize access
-** when Lua is compiled as a shared library. Not all elf targets support
-** this attribute. Unfortunately, gcc does not offer a way to check
-** whether the target offers that support, and those without support
-** give a warning about it. To avoid these warnings, change to the
-** default definition.
-*/
-#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
-    defined(__ELF__)		/* { */
-#define LUAI_FUNC	__attribute__((visibility("internal"))) extern
-#else				/* }{ */
-#define LUAI_FUNC	extern
-#endif				/* } */
-
-#define LUAI_DDEC(dec)	LUAI_FUNC dec
-#define LUAI_DDEF	/* empty */
+#if defined(__cplusplus)
+/* Lua uses the "C name" when calling open functions */
+#define LUAMOD_API	extern "C"
+#else
+#define LUAMOD_API	LUA_API
+#endif
 
 /* }================================================================== */
 

@@ -362,35 +343,12 @@
 
 
 /*
-@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3.
-** You can define it to get all options, or change specific options
-** to fit your specific needs.
-*/
-#if defined(LUA_COMPAT_5_3)	/* { */
-
-/*
 @@ LUA_COMPAT_MATHLIB controls the presence of several deprecated
 ** functions in the mathematical library.
 ** (These functions were already officially removed in 5.3;
 ** nevertheless they are still available here.)
 */
-#define LUA_COMPAT_MATHLIB
-
-/*
-@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
-** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
-** luaL_checkint, luaL_checklong, etc.)
-** (These macros were also officially removed in 5.3, but they are still
-** available here.)
-*/
-#define LUA_COMPAT_APIINTCASTS
-
-
-/*
-@@ LUA_COMPAT_LT_LE controls the emulation of the '__le' metamethod
-** using '__lt'.
-*/
-#define LUA_COMPAT_LT_LE
+/* #define LUA_COMPAT_MATHLIB */
 
 
 /*

@@ -407,8 +365,6 @@
 #define lua_equal(L,idx1,idx2)		lua_compare(L,(idx1),(idx2),LUA_OPEQ)
 #define lua_lessthan(L,idx1,idx2)	lua_compare(L,(idx1),(idx2),LUA_OPLT)
 
-#endif				/* } */
-
 /* }================================================================== */
 
 

@@ -440,26 +396,11 @@
 */
 
 
-/* The following definitions are good for most cases here */
+/* The following definition is good for most cases here */
 
 #define l_floor(x)		(l_mathop(floor)(x))
 
 
-/*
-@@ lua_numbertointeger converts a float number with an integral value
-** to an integer, or returns 0 if float is not within the range of
-** a lua_Integer.  (The range comparisons are tricky because of
-** rounding. The tests here assume a two-complement representation,
-** where MININTEGER always has an exact representation as a float;
-** MAXINTEGER may not have one, and therefore its conversion to float
-** may have an ill-defined value.)
-*/
-#define lua_numbertointeger(n,p) \
-  ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
-   (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
-      (*(p) = (LUA_INTEGER)(n), 1))
-
-
 /* now the variable definitions */
 
 #if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT		/* { single float */

@@ -719,13 +660,6 @@
 #endif
 
 
-#if defined(LUA_CORE) || defined(LUA_LIB)
-/* shorter names for Lua's own use */
-#define l_likely(x)	luai_likely(x)
-#define l_unlikely(x)	luai_unlikely(x)
-#endif
-
-
 
 /* }================================================================== */
 

@@ -764,20 +698,6 @@
 */
 
 /*
-@@ LUAI_MAXSTACK limits the size of the Lua stack.
-** CHANGE it if you need a different limit. This limit is arbitrary;
-** its only purpose is to stop Lua from consuming unlimited stack
-** space and to reserve some numbers for pseudo-indices.
-** (It must fit into max(int)/2.)
-*/
-#if 1000000 < (INT_MAX / 2)
-#define LUAI_MAXSTACK		1000000
-#else
-#define LUAI_MAXSTACK		(INT_MAX / 2u)
-#endif
-
-
-/*
 @@ LUA_EXTRASPACE defines the size of a raw memory area associated with
 ** a Lua state with very fast access.
 ** CHANGE it if you need a different size.

@@ -821,7 +741,5 @@
 
 
 
-
-
 #endif
 

src/lundump.c

@@ -109,7 +109,7 @@
 
 
 static size_t loadSize (LoadState *S) {
-  return loadVarint(S, MAX_SIZE);
+  return cast_sizet(loadVarint(S, MAX_SIZE));
 }
 
 

@@ -147,20 +147,20 @@
   TString *ts;
   TValue sv;
   size_t size = loadSize(S);
-  if (size == 0) {  /* no string? */
-    lua_assert(*sl == NULL);  /* must be prefilled */
-    return;
-  }
-  else if (size == 1) {  /* previously saved string? */
+  if (size == 0) {  /* previously saved string? */
     lua_Unsigned idx = loadVarint(S, LUA_MAXUNSIGNED);  /* get its index */
     TValue stv;
+    if (idx == 0) {  /* no string? */
+      lua_assert(*sl == NULL);  /* must be prefilled */
+      return;
+    }
     if (novariant(luaH_getint(S->h, l_castU2S(idx), &stv)) != LUA_TSTRING)
       error(S, "invalid string index");
     *sl = ts = tsvalue(&stv);  /* get its value */
     luaC_objbarrier(L, p, ts);
     return;  /* do not save it again */
   }
-  else if ((size -= 2) <= LUAI_MAXSHORTLEN) {  /* short string? */
+  else if ((size -= 1) <= LUAI_MAXSHORTLEN) {  /* short string? */
     char buff[LUAI_MAXSHORTLEN + 1];  /* extra space for '\0' */
     loadVector(S, buff, size + 1);  /* load string into buffer */
     *sl = ts = luaS_newlstr(L, buff, size);  /* create string */

@@ -327,7 +327,8 @@
   f->linedefined = loadInt(S);
   f->lastlinedefined = loadInt(S);
   f->numparams = loadByte(S);
-  f->flag = loadByte(S) & PF_ISVARARG;  /* get only the meaningful flags */
+  /* get only the meaningful flags */
+  f->flag = cast_byte(loadByte(S) & ~PF_FIXED);
   if (S->fixed)
     f->flag |= PF_FIXED;  /* signal that code is fixed */
   f->maxstacksize = loadByte(S);

src/lutf8lib.c

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

@@ -47,7 +46,7 @@
 ** Decode one UTF-8 sequence, returning NULL if byte sequence is
 ** invalid.  The array 'limits' stores the minimum value for each
 ** sequence length, to check for overlong representations. Its first
-** entry forces an error for non-ascii bytes with no continuation
+** entry forces an error for non-ASCII bytes with no continuation
 ** bytes (count == 0).
 */
 static const char *utf8_decode (const char *s, l_uint32 *val, int strict) {

@@ -55,7 +54,7 @@
         {~(l_uint32)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u};
   unsigned int c = (unsigned char)s[0];
   l_uint32 res = 0;  /* final result */
-  if (c < 0x80)  /* ascii? */
+  if (c < 0x80)  /* ASCII? */
     res = c;
   else {
     int count = 0;  /* to count number of continuation bytes */

@@ -215,9 +214,10 @@
   }
   lua_pushinteger(L, posi + 1);  /* initial position */
   if ((s[posi] & 0x80) != 0) {  /* multi-byte character? */
-    do {
-      posi++;
-    } while (iscontp(s + posi + 1));  /* skip to final byte */
+    if (iscont(s[posi]))
+      return luaL_error(L, "initial position is a continuation byte");
+    while (iscontp(s + posi + 1))
+      posi++;  /* skip to last continuation byte */
   }
   /* else one-byte character: final position is the initial one */
   lua_pushinteger(L, posi + 1);  /* 'posi' now is the final position */

src/lvm.c

@@ -373,6 +373,14 @@
 
 
 /*
+** Function to be used for 0-terminated string order comparison
+*/
+#if !defined(l_strcoll)
+#define l_strcoll	strcoll
+#endif
+
+
+/*
 ** Compare two strings 'ts1' x 'ts2', returning an integer less-equal-
 ** -greater than zero if 'ts1' is less-equal-greater than 'ts2'.
 ** The code is a little tricky because it allows '\0' in the strings

@@ -386,7 +394,7 @@
   size_t rl2;
   const char *s2 = getlstr(ts2, rl2);
   for (;;) {  /* for each segment */
-    int temp = strcoll(s1, s2);
+    int temp = l_strcoll(s1, s2);
     if (temp != 0)  /* not equal? */
       return temp;  /* done */
     else {  /* strings are equal up to a '\0' */

@@ -573,52 +581,74 @@
 */
 int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
   const TValue *tm;
-  if (ttypetag(t1) != ttypetag(t2)) {  /* not the same variant? */
-    if (ttype(t1) != ttype(t2) || ttype(t1) != LUA_TNUMBER)
-      return 0;  /* only numbers can be equal with different variants */
-    else {  /* two numbers with different variants */
-      /* One of them is an integer. If the other does not have an
-         integer value, they cannot be equal; otherwise, compare their
-         integer values. */
-      lua_Integer i1, i2;
-      return (luaV_tointegerns(t1, &i1, F2Ieq) &&
-              luaV_tointegerns(t2, &i2, F2Ieq) &&
-              i1 == i2);
+  if (ttype(t1) != ttype(t2))  /* not the same type? */
+    return 0;
+  else if (ttypetag(t1) != ttypetag(t2)) {
+    switch (ttypetag(t1)) {
+      case LUA_VNUMINT: {  /* integer == float? */
+        /* integer and float can only be equal if float has an integer
+           value equal to the integer */
+        lua_Integer i2;
+        return (luaV_flttointeger(fltvalue(t2), &i2, F2Ieq) &&
+                ivalue(t1) == i2);
+      }
+      case LUA_VNUMFLT: {  /* float == integer? */
+        lua_Integer i1;  /* see comment in previous case */
+        return (luaV_flttointeger(fltvalue(t1), &i1, F2Ieq) &&
+                i1 == ivalue(t2));
+      }
+      case LUA_VSHRSTR: case LUA_VLNGSTR: {
+        /* compare two strings with different variants: they can be
+           equal when one string is a short string and the other is
+           an external string  */
+        return luaS_eqstr(tsvalue(t1), tsvalue(t2));
+      }
+      default:
+        /* only numbers (integer/float) and strings (long/short) can have
+           equal values with different variants */
+        return 0;
     }
   }
-  /* values have same type and same variant */
-  switch (ttypetag(t1)) {
-    case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: return 1;
-    case LUA_VNUMINT: return (ivalue(t1) == ivalue(t2));
-    case LUA_VNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2));
-    case LUA_VLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
-    case LUA_VLCF: return fvalue(t1) == fvalue(t2);
-    case LUA_VSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2));
-    case LUA_VLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2));
-    case LUA_VUSERDATA: {
-      if (uvalue(t1) == uvalue(t2)) return 1;
-      else if (L == NULL) return 0;
-      tm = fasttm(L, uvalue(t1)->metatable, TM_EQ);
-      if (tm == NULL)
-        tm = fasttm(L, uvalue(t2)->metatable, TM_EQ);
-      break;  /* will try TM */
+  else {  /* equal variants */
+    switch (ttypetag(t1)) {
+      case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE:
+        return 1;
+      case LUA_VNUMINT:
+        return (ivalue(t1) == ivalue(t2));
+      case LUA_VNUMFLT:
+        return (fltvalue(t1) == fltvalue(t2));
+      case LUA_VLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
+      case LUA_VSHRSTR:
+        return eqshrstr(tsvalue(t1), tsvalue(t2));
+      case LUA_VLNGSTR:
+        return luaS_eqstr(tsvalue(t1), tsvalue(t2));
+      case LUA_VUSERDATA: {
+        if (uvalue(t1) == uvalue(t2)) return 1;
+        else if (L == NULL) return 0;
+        tm = fasttm(L, uvalue(t1)->metatable, TM_EQ);
+        if (tm == NULL)
+          tm = fasttm(L, uvalue(t2)->metatable, TM_EQ);
+        break;  /* will try TM */
+      }
+      case LUA_VTABLE: {
+        if (hvalue(t1) == hvalue(t2)) return 1;
+        else if (L == NULL) return 0;
+        tm = fasttm(L, hvalue(t1)->metatable, TM_EQ);
+        if (tm == NULL)
+          tm = fasttm(L, hvalue(t2)->metatable, TM_EQ);
+        break;  /* will try TM */
+      }
+      case LUA_VLCF:
+        return (fvalue(t1) == fvalue(t2));
+      default:  /* functions and threads */
+        return (gcvalue(t1) == gcvalue(t2));
     }
-    case LUA_VTABLE: {
-      if (hvalue(t1) == hvalue(t2)) return 1;
-      else if (L == NULL) return 0;
-      tm = fasttm(L, hvalue(t1)->metatable, TM_EQ);
-      if (tm == NULL)
-        tm = fasttm(L, hvalue(t2)->metatable, TM_EQ);
-      break;  /* will try TM */
+    if (tm == NULL)  /* no TM? */
+      return 0;  /* objects are different */
+    else {
+      int tag = luaT_callTMres(L, tm, t1, t2, L->top.p);  /* call TM */
+      return !tagisfalse(tag);
     }
-    default:
-      return gcvalue(t1) == gcvalue(t2);
-  }
-  if (tm == NULL)  /* no TM? */
-    return 0;  /* objects are different */
-  else {
-    int tag = luaT_callTMres(L, tm, t1, t2, L->top.p);  /* call TM */
-    return !tagisfalse(tag);
   }
 }
 

@@ -627,6 +657,11 @@
 #define tostring(L,o)  \
 	(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
 
+/*
+** Check whether object is a short empty string to optimize concatenation.
+** (External strings can be empty too; they will be concatenated like
+** non-empty ones.)
+*/
 #define isemptystr(o)	(ttisshrstring(o) && tsvalue(o)->shrlen == 0)
 
 /* copy strings in stack from top - n up to top - 1 to buffer */

@@ -661,8 +696,8 @@
       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 = tsslen(tsvalue(s2v(top - 1)));
+      /* at least two string values; get as many as possible */
+      size_t tl = tsslen(tsvalue(s2v(top - 1)));  /* total length */
       TString *ts;
       /* collect total length and number of strings */
       for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {

@@ -700,7 +735,7 @@
       Table *h = hvalue(rb);
       tm = fasttm(L, h->metatable, TM_LEN);
       if (tm) break;  /* metamethod? break switch to call it */
-      setivalue(s2v(ra), l_castU2S(luaH_getn(h)));  /* else primitive len */
+      setivalue(s2v(ra), l_castU2S(luaH_getn(L, h)));  /* else primitive len */
       return;
     }
     case LUA_VSHRSTR: {

@@ -839,12 +874,6 @@
     case OP_EQ: {  /* note that 'OP_EQI'/'OP_EQK' cannot yield */
       int res = !l_isfalse(s2v(L->top.p - 1));
       L->top.p--;
-#if defined(LUA_COMPAT_LT_LE)
-      if (ci->callstatus & CIST_LEQ) {  /* "<=" using "<" instead? */
-        ci->callstatus ^= CIST_LEQ;  /* clear mark */
-        res = !res;  /* negate result */
-      }
-#endif
       lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
       if (res != GETARG_k(inst))  /* condition failed? */
         ci->u.l.savedpc++;  /* skip jump instruction */

@@ -888,6 +917,10 @@
 /*
 ** {==================================================================
 ** Macros for arithmetic/bitwise/comparison opcodes in 'luaV_execute'
+**
+** All these macros are to be used exclusively inside the main
+** iterpreter loop (function luaV_execute) and may access directly
+** the local variables of that function (L, i, pc, ci, etc.).
 ** ===================================================================
 */
 

@@ -909,17 +942,17 @@
 ** operation, 'fop' is the float operation.
 */
 #define op_arithI(L,iop,fop) {  \
-  StkId ra = RA(i); \
+  TValue *ra = vRA(i); \
   TValue *v1 = vRB(i);  \
   int imm = GETARG_sC(i);  \
   if (ttisinteger(v1)) {  \
     lua_Integer iv1 = ivalue(v1);  \
-    pc++; setivalue(s2v(ra), iop(L, iv1, imm));  \
+    pc++; setivalue(ra, iop(L, iv1, imm));  \
   }  \
   else if (ttisfloat(v1)) {  \
     lua_Number nb = fltvalue(v1);  \
     lua_Number fimm = cast_num(imm);  \
-    pc++; setfltvalue(s2v(ra), fop(L, nb, fimm)); \
+    pc++; setfltvalue(ra, fop(L, nb, fimm)); \
   }}
 
 

@@ -930,6 +963,7 @@
 #define op_arithf_aux(L,v1,v2,fop) {  \
   lua_Number n1; lua_Number n2;  \
   if (tonumberns(v1, n1) && tonumberns(v2, n2)) {  \
+    StkId ra = RA(i);  \
     pc++; setfltvalue(s2v(ra), fop(L, n1, n2));  \
   }}
 

@@ -938,7 +972,6 @@
 ** Arithmetic operations over floats and others with register operands.
 */
 #define op_arithf(L,fop) {  \
-  StkId ra = RA(i); \
   TValue *v1 = vRB(i);  \
   TValue *v2 = vRC(i);  \
   op_arithf_aux(L, v1, v2, fop); }

@@ -948,7 +981,6 @@
 ** Arithmetic operations with K operands for floats.
 */
 #define op_arithfK(L,fop) {  \
-  StkId ra = RA(i); \
   TValue *v1 = vRB(i);  \
   TValue *v2 = KC(i); lua_assert(ttisnumber(v2));  \
   op_arithf_aux(L, v1, v2, fop); }

@@ -958,8 +990,8 @@
 ** Arithmetic operations over integers and floats.
 */
 #define op_arith_aux(L,v1,v2,iop,fop) {  \
-  StkId ra = RA(i); \
   if (ttisinteger(v1) && ttisinteger(v2)) {  \
+    StkId ra = RA(i); \
     lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2);  \
     pc++; setivalue(s2v(ra), iop(L, i1, i2));  \
   }  \

@@ -988,12 +1020,12 @@
 ** Bitwise operations with constant operand.
 */
 #define op_bitwiseK(L,op) {  \
-  StkId ra = RA(i); \
   TValue *v1 = vRB(i);  \
   TValue *v2 = KC(i);  \
   lua_Integer i1;  \
   lua_Integer i2 = ivalue(v2);  \
   if (tointegerns(v1, &i1)) {  \
+    StkId ra = RA(i); \
     pc++; setivalue(s2v(ra), op(i1, i2));  \
   }}
 

@@ -1002,11 +1034,11 @@
 ** Bitwise operations with register operands.
 */
 #define op_bitwise(L,op) {  \
-  StkId ra = RA(i); \
   TValue *v1 = vRB(i);  \
   TValue *v2 = vRC(i);  \
   lua_Integer i1; lua_Integer i2;  \
   if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) {  \
+    StkId ra = RA(i); \
     pc++; setivalue(s2v(ra), op(i1, i2));  \
   }}
 

@@ -1017,18 +1049,18 @@
 ** integers.
 */
 #define op_order(L,opi,opn,other) {  \
-  StkId ra = RA(i); \
+  TValue *ra = vRA(i); \
   int cond;  \
   TValue *rb = vRB(i);  \
-  if (ttisinteger(s2v(ra)) && ttisinteger(rb)) {  \
-    lua_Integer ia = ivalue(s2v(ra));  \
+  if (ttisinteger(ra) && ttisinteger(rb)) {  \
+    lua_Integer ia = ivalue(ra);  \
     lua_Integer ib = ivalue(rb);  \
     cond = opi(ia, ib);  \
   }  \
-  else if (ttisnumber(s2v(ra)) && ttisnumber(rb))  \
-    cond = opn(s2v(ra), rb);  \
+  else if (ttisnumber(ra) && ttisnumber(rb))  \
+    cond = opn(ra, rb);  \
   else  \
-    Protect(cond = other(L, s2v(ra), rb));  \
+    Protect(cond = other(L, ra, rb));  \
   docondjump(); }
 
 

@@ -1037,19 +1069,19 @@
 ** always small enough to have an exact representation as a float.)
 */
 #define op_orderI(L,opi,opf,inv,tm) {  \
-  StkId ra = RA(i); \
+  TValue *ra = vRA(i); \
   int cond;  \
   int im = GETARG_sB(i);  \
-  if (ttisinteger(s2v(ra)))  \
-    cond = opi(ivalue(s2v(ra)), im);  \
-  else if (ttisfloat(s2v(ra))) {  \
-    lua_Number fa = fltvalue(s2v(ra));  \
+  if (ttisinteger(ra))  \
+    cond = opi(ivalue(ra), im);  \
+  else if (ttisfloat(ra)) {  \
+    lua_Number fa = fltvalue(ra);  \
     lua_Number fim = cast_num(im);  \
     cond = opf(fa, fim);  \
   }  \
   else {  \
     int isf = GETARG_C(i);  \
-    Protect(cond = luaT_callorderiTM(L, s2v(ra), im, inv, isf, tm));  \
+    Protect(cond = luaT_callorderiTM(L, ra, im, inv, isf, tm));  \
   }  \
   docondjump(); }
 

@@ -1068,6 +1100,7 @@
 
 
 #define RA(i)	(base+GETARG_A(i))
+#define vRA(i)	s2v(RA(i))
 #define RB(i)	(base+GETARG_B(i))
 #define vRB(i)	s2v(RB(i))
 #define KB(i)	(k+GETARG_B(i))

@@ -1108,14 +1141,14 @@
 /*
 ** Correct global 'pc'.
 */
-#define savepc(L)	(ci->u.l.savedpc = pc)
+#define savepc(ci)	(ci->u.l.savedpc = pc)
 
 
 /*
 ** Whenever code can raise errors, the global 'pc' and the global
 ** 'top' must be correct to report occasional errors.
 */
-#define savestate(L,ci)		(savepc(L), L->top.p = ci->top.p)
+#define savestate(L,ci)		(savepc(ci), L->top.p = ci->top.p)
 
 
 /*

@@ -1125,7 +1158,7 @@
 #define Protect(exp)  (savestate(L,ci), (exp), updatetrap(ci))
 
 /* special version that does not change the top */
-#define ProtectNT(exp)  (savepc(L), (exp), updatetrap(ci))
+#define ProtectNT(exp)  (savepc(ci), (exp), updatetrap(ci))
 
 /*
 ** Protect code that can only raise errors. (That is, it cannot change

@@ -1143,7 +1176,7 @@
 
 /* 'c' is the limit of live values in the stack */
 #define checkGC(L,c)  \
-	{ luaC_condGC(L, (savepc(L), L->top.p = (c)), \
+	{ luaC_condGC(L, (savepc(ci), L->top.p = (c)), \
                          updatetrap(ci)); \
            luai_threadyield(L); }
 

@@ -1450,23 +1483,23 @@
         op_bitwiseK(L, l_bxor);
         vmbreak;
       }
-      vmcase(OP_SHRI) {
+      vmcase(OP_SHLI) {
         StkId ra = RA(i);
         TValue *rb = vRB(i);
         int ic = GETARG_sC(i);
         lua_Integer ib;
         if (tointegerns(rb, &ib)) {
-          pc++; setivalue(s2v(ra), luaV_shiftl(ib, -ic));
+          pc++; setivalue(s2v(ra), luaV_shiftl(ic, ib));
         }
         vmbreak;
       }
-      vmcase(OP_SHLI) {
+      vmcase(OP_SHRI) {
         StkId ra = RA(i);
         TValue *rb = vRB(i);
         int ic = GETARG_sC(i);
         lua_Integer ib;
         if (tointegerns(rb, &ib)) {
-          pc++; setivalue(s2v(ra), luaV_shiftl(ic, ib));
+          pc++; setivalue(s2v(ra), luaV_shiftl(ib, -ic));
         }
         vmbreak;
       }

@@ -1512,14 +1545,14 @@
         op_bitwise(L, l_bxor);
         vmbreak;
       }
-      vmcase(OP_SHR) {
-        op_bitwise(L, luaV_shiftr);
-        vmbreak;
-      }
       vmcase(OP_SHL) {
         op_bitwise(L, luaV_shiftl);
         vmbreak;
       }
+      vmcase(OP_SHR) {
+        op_bitwise(L, luaV_shiftr);
+        vmbreak;
+      }
       vmcase(OP_MMBIN) {
         StkId ra = RA(i);
         Instruction pi = *(pc - 2);  /* original arith. expression */

@@ -1692,7 +1725,7 @@
         if (b != 0)  /* fixed number of arguments? */
           L->top.p = ra + b;  /* top signals number of arguments */
         /* else previous instruction set top */
-        savepc(L);  /* in case of errors */
+        savepc(ci);  /* in case of errors */
         if ((newci = luaD_precall(L, ra, nresults)) == NULL)
           updatetrap(ci);  /* C call; nothing else to be done */
         else {  /* Lua call: run function in this same C frame */

@@ -1868,7 +1901,7 @@
       vmcase(OP_SETLIST) {
         StkId ra = RA(i);
         unsigned n = cast_uint(GETARG_vB(i));
-        unsigned int last = cast_uint(GETARG_vC(i));
+        unsigned last = cast_uint(GETARG_vC(i));
         Table *h = hvalue(s2v(ra));
         if (n == 0)
           n = cast_uint(L->top.p - ra) - 1;  /* get up to the top */

@@ -1906,8 +1939,20 @@
         Protect(luaT_getvarargs(L, ci, ra, n));
         vmbreak;
       }
+      vmcase(OP_GETVARG) {
+        StkId ra = RA(i);
+        TValue *rc = vRC(i);
+        luaT_getvararg(ci, ra, rc);
+        vmbreak;
+      }
+      vmcase(OP_ERRNNIL) {
+        TValue *ra = vRA(i);
+        if (!ttisnil(ra))
+          halfProtect(luaG_errnnil(L, cl, GETARG_Bx(i)));
+        vmbreak;
+      }
       vmcase(OP_VARARGPREP) {
-        ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p));
+        ProtectNT(luaT_adjustvarargs(L, ci, cl->p));
         if (l_unlikely(trap)) {  /* previous "Protect" updated trap */
           luaD_hookcall(L, ci);
           L->oldpc = 1;  /* next opcode will be seen as a "new" line */