Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
lua: update to 5.4.4
Baptiste Daroussin committed 3 years ago
commit 1791ee3474e7d18f48aafc6593b8a76f04dd7eea
parent fcc0b5b
50 files changed +1719 -1050
modified external/lua/Makefile
@@ -46,7 +46,7 @@ TO_MAN= lua.1 luac.1

# Lua version and release.
V= 5.4
-
R= $V.2
+
R= $V.4

# Targets start here.
all:	$(PLAT)
modified external/lua/README
@@ -1,5 +1,5 @@

-
This is Lua 5.4.2, released on 13 Nov 2020.
+
This is Lua 5.4.4, released on 13 Jan 2022.

For installation instructions, license details, and
further information about Lua, see doc/readme.html.
modified external/lua/doc/contents.html
@@ -32,7 +32,7 @@ For a complete introduction to Lua programming, see the book

<P>
<SMALL>
-
Copyright &copy; 2020 Lua.org, PUC-Rio.
+
Copyright &copy; 2020&ndash;2022 Lua.org, PUC-Rio.
Freely available under the terms of the
<A HREF="http://www.lua.org/license.html">Lua license</A>.
</SMALL>
@@ -396,6 +396,7 @@ Freely available under the terms of the
<A HREF="manual.html#lua_callk">lua_callk</A><BR>
<A HREF="manual.html#lua_checkstack">lua_checkstack</A><BR>
<A HREF="manual.html#lua_close">lua_close</A><BR>
+
<A HREF="manual.html#lua_closeslot">lua_closeslot</A><BR>
<A HREF="manual.html#lua_compare">lua_compare</A><BR>
<A HREF="manual.html#lua_concat">lua_concat</A><BR>
<A HREF="manual.html#lua_copy">lua_copy</A><BR>
@@ -663,10 +664,10 @@ Freely available under the terms of the

<P CLASS="footer">
Last update:
-
Tue Nov 10 20:58:52 UTC 2020
+
Thu Jan 13 11:32:22 UTC 2022
</P>
<!--
-
Last change: revised for Lua 5.4.2
+
Last change: revised for Lua 5.4.4
-->

</BODY>
modified external/lua/doc/manual.html
@@ -19,7 +19,7 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes

<P>
<SMALL>
-
Copyright &copy; 2020 Lua.org, PUC-Rio.
+
Copyright &copy; 2020&ndash;2022 Lua.org, PUC-Rio.
Freely available under the terms of the
<a href="http://www.lua.org/license.html">Lua license</a>.
</SMALL>
@@ -143,6 +143,11 @@ The type <em>boolean</em> has two values, <b>false</b> and <b>true</b>.
Both <b>nil</b> and <b>false</b> make a condition false;
they are collectively called <em>false values</em>.
Any other value makes a condition true.
+
Despite its name,
+
<b>false</b> is frequently used as an alternative to <b>nil</b>,
+
with the key difference that <b>false</b> behaves
+
like a regular value in a table,
+
while a <b>nil</b> in a table represents an absent key.


<p>
@@ -434,7 +439,7 @@ under certain events.
You can change several aspects of the behavior
of a value by setting specific fields in its metatable.
For instance, when a non-numeric value is the operand of an addition,
-
Lua checks for a function in the field "<code>__add</code>" of the value's metatable.
+
Lua checks for a function in the field <code>__add</code> of the value's metatable.
If it finds one,
Lua calls this function to perform the addition.

@@ -901,7 +906,7 @@ For an object (table or userdata) to be finalized when collected,
you must <em>mark</em> it for finalization.

You mark an object for finalization when you set its metatable
-
and the metatable has a field indexed by the string "<code>__gc</code>".
+
and the metatable has a <code>__gc</code> metamethod.
Note that if you set a metatable without a <code>__gc</code> field
and later create that field in the metatable,
the object will not be marked for finalization.
@@ -956,11 +961,8 @@ these marks have no effect.


<p>
-
Finalizers cannot yield.
-
Except for that, they can do anything,
-
such as raise errors, create new objects,
-
or even run the garbage collector.
-
However, because they can run in unpredictable times,
+
Finalizers cannot yield nor run the garbage collector.
+
Because they can run in unpredictable times,
it is good practice to restrict each finalizer
to the minimum necessary to properly release
its associated resource.
@@ -1631,8 +1633,10 @@ before the adjustment


<p>
-
The assignment statement first evaluates all its expressions
-
and only then the assignments are performed.
+
If a variable is both assigned and read
+
inside a multiple assignment,
+
Lua ensures all reads get the value of the variable
+
before the assignment.
Thus the code

<pre>
@@ -1657,6 +1661,14 @@ cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</c


<p>
+
Note that this guarantee covers only accesses
+
syntactically inside the assignment statement.
+
If a function or a metamethod called during the assignment
+
changes the value of a variable,
+
Lua gives no guarantees about the order of that access.
+

+

+
<p>
An assignment to a global name <code>x = val</code>
is equivalent to the assignment
<code>_ENV.x = val</code> (see <a href="#2.2">&sect;2.2</a>).
@@ -1992,16 +2004,8 @@ they are closed in the reverse order that they were declared.
If there is any error while running a closing method,
that error is handled like an error in the regular code
where the variable was defined.
-
However, Lua may call the method one more time.
-

-

-
<p>
After an error,
the other pending closing methods will still be called.
-
Errors in these methods
-
interrupt the respective method and generate a warning,
-
but are otherwise ignored;
-
the error reported is only the original one.


<p>
@@ -2419,16 +2423,21 @@ character is one byte.)
<p>
The length operator applied on a table
returns a border in that table.
-
A <em>border</em> in a table <code>t</code> is any natural number
+
A <em>border</em> in a table <code>t</code> is any non-negative integer
that satisfies the following condition:

<pre>
-
     (border == 0 or t[border] ~= nil) and t[border + 1] == nil
+
     (border == 0 or t[border] ~= nil) and
+
     (t[border + 1] == nil or border == math.maxinteger)
</pre><p>
In words,
-
a border is any (natural) index present in the table
-
that is followed by an absent index
-
(or zero, when index 1 is absent).
+
a border is any positive integer index present in the table
+
that is followed by an absent index,
+
plus two limit cases:
+
zero, when index 1 is absent;
+
and the maximum value for an integer, when that index is present.
+
Note that keys that are not positive integers
+
do not interfere with borders.


<p>
@@ -2439,12 +2448,9 @@ The table <code>{10, 20, 30, nil, 50}</code> has two borders (3 and 5),
and therefore it is not a sequence.
(The <b>nil</b> at index 4 is called a <em>hole</em>.)
The table <code>{nil, 20, 30, nil, nil, 60, nil}</code>
-
has three borders (0, 3, and 6) and three holes
-
(at indices 1, 4, and 5),
+
has three borders (0, 3, and 6),
so it is not a sequence, too.
The table <code>{}</code> is a sequence with border 0.
-
Note that non-natural keys do not interfere
-
with whether a table is a sequence.


<p>
@@ -2462,7 +2468,7 @@ the memory addresses of its non-numeric keys.)
<p>
The computation of the length of a table
has a guaranteed worst time of <em>O(log n)</em>,
-
where <em>n</em> is the largest natural key in the table.
+
where <em>n</em> is the largest integer key in the table.


<p>
@@ -3763,6 +3769,29 @@ will probably need to close states as soon as they are not needed.



+
<hr><h3><a name="lua_closeslot"><code>lua_closeslot</code></a></h3><p>
+
<span class="apii">[-0, +0, <em>e</em>]</span>
+
<pre>void lua_closeslot (lua_State *L, int index);</pre>
+

+
<p>
+
Close the to-be-closed slot at the given index and set its value to <b>nil</b>.
+
The index must be the last index previously marked to be closed
+
(see <a href="#lua_toclose"><code>lua_toclose</code></a>) that is still active (that is, not closed yet).
+

+

+
<p>
+
A <code>__close</code> metamethod cannot yield
+
when called through this function.
+

+

+
<p>
+
(Exceptionally, this function was introduced in release 5.4.3.
+
It is not present in previous 5.4 releases.)
+

+

+

+

+

<hr><h3><a name="lua_compare"><code>lua_compare</code></a></h3><p>
<span class="apii">[-0, +0, <em>e</em>]</span>
<pre>int lua_compare (lua_State *L, int index1, int index2, int op);</pre>
@@ -3959,6 +3988,10 @@ For more details about these options,
see <a href="#pdf-collectgarbage"><code>collectgarbage</code></a>.


+
<p>
+
This function should not be called by a finalizer.
+

+




@@ -4657,11 +4690,7 @@ except that it allows the called function to yield (see <a href="#4.5">&sect;4.5

<p>
Pops <code>n</code> elements from the stack.
-

-

-
<p>
-
This function can run arbitrary code when removing an index
-
marked as to-be-closed from the stack.
+
It is implemented as a macro over <a href="#lua_settop"><code>lua_settop</code></a>.



@@ -5140,10 +5169,12 @@ and then pops the top element.
Resets a thread, cleaning its call stack and closing all pending
to-be-closed variables.
Returns a status code:
-
<a href="#pdf-LUA_OK"><code>LUA_OK</code></a> for no errors in closing methods,
+
<a href="#pdf-LUA_OK"><code>LUA_OK</code></a> for no errors in the thread
+
(either the original error that stopped the thread or
+
errors in closing methods),
or an error status otherwise.
In case of error,
-
leaves the error object on the top of the stack,
+
leaves the error object on the top of the stack.



@@ -5466,28 +5497,24 @@ otherwise, returns <code>NULL</code>.

<p>
Marks the given index in the stack as a
-
to-be-closed "variable" (see <a href="#3.3.8">&sect;3.3.8</a>).
+
to-be-closed slot (see <a href="#3.3.8">&sect;3.3.8</a>).
Like a to-be-closed variable in Lua,
-
the value at that index in the stack will be closed
+
the value at that slot in the stack will be closed
when it goes out of scope.
Here, in the context of a C function,
to go out of scope means that the running function returns to Lua,
-
there is an error,
-
or the index is removed from the stack through
-
<a href="#lua_settop"><code>lua_settop</code></a> or <a href="#lua_pop"><code>lua_pop</code></a>.
-
An index marked as to-be-closed should not be removed from the stack
-
by any other function in the API except <a href="#lua_settop"><code>lua_settop</code></a> or <a href="#lua_pop"><code>lua_pop</code></a>.
+
or there is an error,
+
or the slot is removed from the stack through
+
<a href="#lua_settop"><code>lua_settop</code></a> or <a href="#lua_pop"><code>lua_pop</code></a>,
+
or there is a call to <a href="#lua_closeslot"><code>lua_closeslot</code></a>.
+
A slot marked as to-be-closed should not be removed from the stack
+
by any other function in the API except <a href="#lua_settop"><code>lua_settop</code></a> or <a href="#lua_pop"><code>lua_pop</code></a>,
+
unless previously deactivated by <a href="#lua_closeslot"><code>lua_closeslot</code></a>.


<p>
This function should not be called for an index
-
that is equal to or below an active to-be-closed index.
-

-

-
<p>
-
In the case of an out-of-memory error,
-
the value in the given index is immediately closed,
-
as if it was already marked.
+
that is equal to or below an active to-be-closed slot.


<p>
@@ -5495,7 +5522,7 @@ Note that, both in case of errors and of a regular return,
by the time the <code>__close</code> metamethod runs,
the C&nbsp;stack was already unwound,
so that any automatic C&nbsp;variable declared in the calling function
-
will be out of scope.
+
(e.g., a buffer) will be out of scope.



@@ -5919,7 +5946,10 @@ information about a function or an activation record.
<a href="#lua_getstack"><code>lua_getstack</code></a> fills only the private part
of this structure, for later use.
To fill the other fields of <a href="#lua_Debug"><code>lua_Debug</code></a> with useful information,
-
you must call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
+
you must call <a href="#lua_getinfo"><code>lua_getinfo</code></a> with an appropriate parameter.
+
(Specifically, to get a field,
+
you must add the letter between parentheses in the field's comment
+
to the parameter <code>what</code> of <a href="#lua_getinfo"><code>lua_getinfo</code></a>.)


<p>
@@ -6096,11 +6126,25 @@ you can write the following code:
<p>
Each character in the string <code>what</code>
selects some fields of the structure <code>ar</code> to be filled or
-
a value to be pushed on the stack:
+
a value to be pushed on the stack.
+
(These characters are also documented in the declaration of
+
the structure <a href="#lua_Debug"><code>lua_Debug</code></a>,
+
between parentheses in the comments following each field.)

<ul>

-
<li><b>'<code>n</code>': </b> fills in the field <code>name</code> and <code>namewhat</code>;
+
<li><b>'<code>f</code>': </b>
+
pushes onto the stack the function that is
+
running at the given level;
+
</li>
+

+
<li><b>'<code>l</code>': </b> fills in the field <code>currentline</code>;
+
</li>
+

+
<li><b>'<code>n</code>': </b> fills in the fields <code>name</code> and <code>namewhat</code>;
+
</li>
+

+
<li><b>'<code>r</code>': </b> fills in the fields <code>ftransfer</code> and <code>ntransfer</code>;
</li>

<li><b>'<code>S</code>': </b>
@@ -6108,9 +6152,6 @@ fills in the fields <code>source</code>, <code>short_src</code>,
<code>linedefined</code>, <code>lastlinedefined</code>, and <code>what</code>;
</li>

-
<li><b>'<code>l</code>': </b> fills in the field <code>currentline</code>;
-
</li>
-

<li><b>'<code>t</code>': </b> fills in the field <code>istailcall</code>;
</li>

@@ -6118,25 +6159,13 @@ fills in the fields <code>source</code>, <code>short_src</code>,
<code>nups</code>, <code>nparams</code>, and <code>isvararg</code>;
</li>

-
<li><b>'<code>f</code>': </b>
-
pushes onto the stack the function that is
-
running at the given level;
-
</li>
-

<li><b>'<code>L</code>': </b>
-
pushes onto the stack a table whose indices are the
-
numbers of the lines that are valid on the function.
-
(A <em>valid line</em> is a line with some associated code,
-
that is, a line where you can put a break point.
-
Non-valid lines include empty lines and comments.)
-

-

-
<p>
+
pushes onto the stack a table whose indices are
+
the lines on the function with some associated code,
+
that is, the lines where you can put a break point.
+
(Lines with no code include empty lines and comments.)
If this option is given together with option '<code>f</code>',
its table is pushed after the function.
-

-

-
<p>
This is the only option that can raise a memory error.
</li>

@@ -6494,7 +6523,7 @@ Adds the byte <code>c</code> to the buffer <code>B</code>


<hr><h3><a name="luaL_addgsub"><code>luaL_addgsub</code></a></h3><p>
-
<span class="apii">[-0, +0, <em>m</em>]</span>
+
<span class="apii">[-?, +?, <em>m</em>]</span>
<pre>const void luaL_addgsub (luaL_Buffer *B, const char *s,
                         const char *p, const char *r);</pre>

@@ -6548,7 +6577,7 @@ to the buffer <code>B</code>


<hr><h3><a name="luaL_addvalue"><code>luaL_addvalue</code></a></h3><p>
-
<span class="apii">[-1, +?, <em>m</em>]</span>
+
<span class="apii">[-?, +?, <em>m</em>]</span>
<pre>void luaL_addvalue (luaL_Buffer *B);</pre>

<p>
@@ -6702,7 +6731,7 @@ Note that any addition to the buffer may invalidate this address.


<hr><h3><a name="luaL_buffinit"><code>luaL_buffinit</code></a></h3><p>
-
<span class="apii">[-0, +0, &ndash;]</span>
+
<span class="apii">[-0, +?, &ndash;]</span>
<pre>void luaL_buffinit (lua_State *L, luaL_Buffer *B);</pre>

<p>
@@ -6740,7 +6769,7 @@ Equivalent to the sequence


<hr><h3><a name="luaL_buffsub"><code>luaL_buffsub</code></a></h3><p>
-
<span class="apii">[-0, +0, &ndash;]</span>
+
<span class="apii">[-?, +?, &ndash;]</span>
<pre>void luaL_buffsub (luaL_Buffer *B, int n);</pre>

<p>
@@ -7543,6 +7572,11 @@ on top of the library table.
These values are popped from the stack after the registration.


+
<p>
+
A function with a <code>NULL</code> value represents a placeholder,
+
which is filled with <b>false</b>.
+

+




@@ -7905,6 +7939,10 @@ See <a href="#2.5">&sect;2.5</a> for more details about garbage collection
and some of these options.


+
<p>
+
This function should not be called by a finalizer.
+

+



<p>
@@ -7922,7 +7960,7 @@ to its caller.

<p>
<hr><h3><a name="pdf-error"><code>error (message [, level])</code></a></h3>
-
Raises an error (see <a href="#2.3">&sect;2.3</a>) with @{message} as the error object.
+
Raises an error (see <a href="#2.3">&sect;2.3</a>) with <code>message</code> as the error object.
This function never returns.


@@ -8097,9 +8135,8 @@ use a numerical <b>for</b>.)


<p>
-
The behavior of <code>next</code> is undefined if,
-
during the traversal,
-
you assign any value to a non-existent field in the table.
+
You should not assign any value to a non-existent field in a table
+
during its traversal.
You may however modify existing fields.
In particular, you may set existing fields to nil.

@@ -8145,7 +8182,7 @@ This means that any error inside&nbsp;<code>f</code> is not propagated;
instead, <code>pcall</code> catches the error
and returns a status code.
Its first result is the status code (a boolean),
-
which is true if the call succeeds without errors.
+
which is <b>true</b> if the call succeeds without errors.
In such case, <code>pcall</code> also returns all results from the call,
after this first result.
In case of any error, <code>pcall</code> returns <b>false</b> plus the error object.
@@ -8398,7 +8435,9 @@ that is,
closes all its pending to-be-closed variables
and puts the coroutine in a dead state.
The given coroutine must be dead or suspended.
-
In case of error closing some variable,
+
In case of error
+
(either the original error that stopped the coroutine or
+
errors in closing methods),
returns <b>false</b> plus the error object;
otherwise returns <b>true</b>.

@@ -8423,7 +8462,7 @@ an object with type <code>"thread"</code>.


<p>
-
Returns true when the coroutine <code>co</code> can yield.
+
Returns <b>true</b> when the coroutine <code>co</code> can yield.
The default for <code>co</code> is the running coroutine.


@@ -8467,7 +8506,7 @@ If there is any error,

<p>
Returns the running coroutine plus a boolean,
-
true when the running coroutine is the main one.
+
<b>true</b> when the running coroutine is the main one.



@@ -9005,7 +9044,7 @@ otherwise, it returns <b>fail</b>.
A third, optional numeric argument <code>init</code> specifies
where to start the search;
its default value is&nbsp;1 and can be negative.
-
A value of <b>true</b> as a fourth, optional argument <code>plain</code>
+
A <b>true</b> as a fourth, optional argument <code>plain</code>
turns off the pattern matching facilities,
so the function does a plain "find substring" operation,
with no characters in <code>pattern</code> being considered magic.
@@ -9030,8 +9069,10 @@ following the description given in its first argument,
which must be a string.
The format string follows the same rules as the ISO&nbsp;C function <code>sprintf</code>.
The only differences are that the conversion specifiers and modifiers
-
<code>*</code>, <code>h</code>, <code>L</code>, <code>l</code>, and <code>n</code> are not supported
+
<code>F</code>, <code>n</code>, <code>*</code>, <code>h</code>, <code>L</code>, and <code>l</code> are not supported
and that there is an extra specifier, <code>q</code>.
+
Both width and precision, when present,
+
are limited to two digits.


<p>
@@ -9055,7 +9096,7 @@ may produce the string:
     "a string with \"quotes\" and \
      new line"
</pre><p>
-
This specifier does not support modifiers (flags, width, length).
+
This specifier does not support modifiers (flags, width, precision).


<p>
@@ -9960,23 +10001,23 @@ from <code>list[1]</code> to <code>list[#list]</code>.
If <code>comp</code> is given,
then it must be a function that receives two list elements
and returns true when the first element must come
-
before the second in the final order
-
(so that, after the sort,
-
<code>i &lt; j</code> implies <code>not comp(list[j],list[i])</code>).
+
before the second in the final order,
+
so that, after the sort,
+
<code>i &lt;= j</code> implies <code>not comp(list[j],list[i])</code>.
If <code>comp</code> is not given,
then the standard Lua operator <code>&lt;</code> is used instead.


<p>
-
Note that the <code>comp</code> function must define
-
a strict partial order over the elements in the list;
-
that is, it must be asymmetric and transitive.
-
Otherwise, no valid sort may be possible.
+
The <code>comp</code> function must define a consistent order;
+
more formally, the function must define a strict weak order.
+
(A weak order is similar to a total order,
+
but it can equate different elements for comparison purposes.)


<p>
The sort algorithm is not stable:
-
elements considered equal by the given order
+
Different elements considered equal by the given order
may have their relative positions changed by the sort.


@@ -10346,7 +10387,7 @@ or <b>fail</b> if <code>x</code> is not a number.

<p>
Returns a boolean,
-
true if and only if integer <code>m</code> is below integer <code>n</code> when
+
<b>true</b> if and only if integer <code>m</code> is below integer <code>n</code> when
they are compared as unsigned integers.


@@ -11908,10 +11949,10 @@ and LiteralString, see <a href="#3.1">&sect;3.1</a>.)

<P CLASS="footer">
Last update:
-
Fri Nov 13 15:35:22 UTC 2020
+
Thu Jan 13 11:33:16 UTC 2022
</P>
<!--
-
Last change: revised for Lua 5.4.2
+
Last change: revised for Lua 5.4.4
-->

</body></html>
modified external/lua/doc/readme.html
@@ -110,7 +110,7 @@ Here are the details.
<OL>
<LI>
Open a terminal window and move to
-
the top-level directory, which is named <TT>lua-5.4.2</TT>.
+
the top-level directory, which is named <TT>lua-5.4.4</TT>.
The <TT>Makefile</TT> there controls both the build process and the installation process.
<P>
<LI>
@@ -303,7 +303,7 @@ For details, see
<A HREF="http://www.lua.org/license.html">this</A>.

<BLOCKQUOTE STYLE="padding-bottom: 0em">
-
Copyright &copy; 1994&ndash;2020 Lua.org, PUC-Rio.
+
Copyright &copy; 1994&ndash;2022 Lua.org, PUC-Rio.

<P>
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -330,10 +330,10 @@ THE SOFTWARE.

<P CLASS="footer">
Last update:
-
Tue Nov 10 20:55:28 UTC 2020
+
Mon Jan  3 09:54:18 UTC 2022
</P>
<!--
-
Last change: revised for Lua 5.4.2
+
Last change: revised for Lua 5.4.4
-->

</BODY>
modified external/lua/src/Makefile
@@ -67,7 +67,7 @@ $(LUAC_T): $(LUAC_O) $(LUA_A)
	$(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)

test:
-
	./lua -v
+
	./$(LUA_T) -v

clean:
	$(RM) $(ALL_T) $(ALL_O)
@@ -79,7 +79,7 @@ echo:
	@echo "PLAT= $(PLAT)"
	@echo "CC= $(CC)"
	@echo "CFLAGS= $(CFLAGS)"
-
	@echo "LDFLAGS= $(SYSLDFLAGS)"
+
	@echo "LDFLAGS= $(LDFLAGS)"
	@echo "LIBS= $(LIBS)"
	@echo "AR= $(AR)"
	@echo "RANLIB= $(RANLIB)"
@@ -108,6 +108,8 @@ c89:
	$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89"
	@echo ''
	@echo '*** C89 does not guarantee 64-bit integers for Lua.'
+
	@echo '*** Make sure to compile all external Lua libraries'
+
	@echo '*** with LUA_USE_C89 to ensure consistency'
	@echo ''

FreeBSD NetBSD OpenBSD freebsd:
modified external/lua/src/lapi.c
@@ -39,7 +39,7 @@ const char lua_ident[] =


/*
-
** Test for a valid index.
+
** Test for a valid index (one that is not the 'nilvalue').
** '!ttisnil(o)' implies 'o != &G(L)->nilvalue', so it is not needed.
** However, it covers the most common cases in a faster way.
*/
@@ -53,6 +53,10 @@ const char lua_ident[] =
#define isupvalue(i)		((i) < LUA_REGISTRYINDEX)


+
/*
+
** Convert an acceptable index to a pointer to its respective value.
+
** Non-valid indices return the special nil value 'G(L)->nilvalue'.
+
*/
static TValue *index2value (lua_State *L, int idx) {
  CallInfo *ci = L->ci;
  if (idx > 0) {
@@ -70,21 +74,28 @@ static TValue *index2value (lua_State *L, int idx) {
  else {  /* upvalues */
    idx = LUA_REGISTRYINDEX - idx;
    api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
-
    if (ttislcf(s2v(ci->func)))  /* light C function? */
-
      return &G(L)->nilvalue;  /* it has no upvalues */
-
    else {
+
    if (ttisCclosure(s2v(ci->func))) {  /* C closure? */
      CClosure *func = clCvalue(s2v(ci->func));
-
      return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : &G(L)->nilvalue;
+
      return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
+
                                      : &G(L)->nilvalue;
+
    }
+
    else {  /* light C function or Lua function (through a hook)?) */
+
      api_check(L, ttislcf(s2v(ci->func)), "caller not a C function");
+
      return &G(L)->nilvalue;  /* no upvalues */
    }
  }
}


-
static StkId index2stack (lua_State *L, int idx) {
+

+
/*
+
** Convert a valid actual index (not a pseudo-index) to its address.
+
*/
+
l_sinline StkId index2stack (lua_State *L, int idx) {
  CallInfo *ci = L->ci;
  if (idx > 0) {
    StkId o = ci->func + idx;
-
    api_check(L, o < L->top, "unacceptable index");
+
    api_check(L, o < L->top, "invalid index");
    return o;
  }
  else {    /* non-positive index */
@@ -172,7 +183,7 @@ LUA_API int lua_gettop (lua_State *L) {

LUA_API void lua_settop (lua_State *L, int idx) {
  CallInfo *ci;
-
  StkId func;
+
  StkId func, newtop;
  ptrdiff_t diff;  /* difference for new top */
  lua_lock(L);
  ci = L->ci;
@@ -187,9 +198,26 @@ LUA_API void lua_settop (lua_State *L, int idx) {
    api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
    diff = idx + 1;  /* will "subtract" index (as it is negative) */
  }
-
  if (diff < 0 && hastocloseCfunc(ci->nresults))
-
    luaF_close(L, L->top + diff, LUA_OK);
-
  L->top += diff;  /* correct top only after closing any upvalue */
+
  api_check(L, L->tbclist < L->top, "previous pop of an unclosed slot");
+
  newtop = L->top + diff;
+
  if (diff < 0 && L->tbclist >= newtop) {
+
    lua_assert(hastocloseCfunc(ci->nresults));
+
    luaF_close(L, newtop, CLOSEKTOP, 0);
+
  }
+
  L->top = newtop;  /* correct top only after closing any upvalue */
+
  lua_unlock(L);
+
}
+

+

+
LUA_API void lua_closeslot (lua_State *L, int idx) {
+
  StkId level;
+
  lua_lock(L);
+
  level = index2stack(L, idx);
+
  api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist == level,
+
     "no variable to close at given level");
+
  luaF_close(L, level, CLOSEKTOP, 0);
+
  level = index2stack(L, idx);  /* stack may be moved */
+
  setnilvalue(s2v(level));
  lua_unlock(L);
}

@@ -200,7 +228,7 @@ LUA_API void lua_settop (lua_State *L, int idx) {
** Note that we move(copy) only the value inside the stack.
** (We do not move additional fields that may exist.)
*/
-
static void reverse (lua_State *L, StkId from, StkId to) {
+
l_sinline void reverse (lua_State *L, StkId from, StkId to) {
  for (; from < to; from++, to--) {
    TValue temp;
    setobj(L, &temp, s2v(from));
@@ -420,7 +448,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
}


-
static void *touserdata (const TValue *o) {
+
l_sinline void *touserdata (const TValue *o) {
  switch (ttype(o)) {
    case LUA_TUSERDATA: return getudatamem(uvalue(o));
    case LUA_TLIGHTUSERDATA: return pvalue(o);
@@ -612,7 +640,7 @@ LUA_API int lua_pushthread (lua_State *L) {
*/


-
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
+
l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) {
  const TValue *slot;
  TString *str = luaS_new(L, k);
  if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
@@ -629,11 +657,21 @@ static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
}


+
/*
+
** Get the global table in the registry. Since all predefined
+
** indices in the registry were inserted right when the registry
+
** was created and never removed, they must always be in the array
+
** part of the registry.
+
*/
+
#define getGtable(L)  \
+
	(&hvalue(&G(L)->l_registry)->array[LUA_RIDX_GLOBALS - 1])
+

+

LUA_API int lua_getglobal (lua_State *L, const char *name) {
-
  Table *reg;
+
  const TValue *G;
  lua_lock(L);
-
  reg = hvalue(&G(L)->l_registry);
-
  return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
+
  G = getGtable(L);
+
  return auxgetstr(L, G, name);
}


@@ -677,7 +715,7 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
}


-
static int finishrawget (lua_State *L, const TValue *val) {
+
l_sinline int finishrawget (lua_State *L, const TValue *val) {
  if (isempty(val))  /* avoid copying empty items to the stack */
    setnilvalue(s2v(L->top));
  else
@@ -811,10 +849,10 @@ static void auxsetstr (lua_State *L, const TValue *t, const char *k) {


LUA_API void lua_setglobal (lua_State *L, const char *name) {
-
  Table *reg;
+
  const TValue *G;
  lua_lock(L);  /* unlock done in 'auxsetstr' */
-
  reg = hvalue(&G(L)->l_registry);
-
  auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
+
  G = getGtable(L);
+
  auxsetstr(L, G, name);
}


@@ -861,12 +899,10 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {

static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
  Table *t;
-
  TValue *slot;
  lua_lock(L);
  api_checknelems(L, n);
  t = gettable(L, idx);
-
  slot = luaH_set(L, t, key);
-
  setobj2t(L, slot, s2v(L->top - 1));
+
  luaH_set(L, t, key, s2v(L->top - 1));
  invalidateTMcache(t);
  luaC_barrierback(L, obj2gco(t), s2v(L->top - 1));
  L->top -= n;
@@ -1063,8 +1099,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
    LClosure *f = clLvalue(s2v(L->top - 1));  /* get newly created function */
    if (f->nupvalues >= 1) {  /* does it have an upvalue? */
      /* get global table from registry */
-
      Table *reg = hvalue(&G(L)->l_registry);
-
      const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+
      const TValue *gt = getGtable(L);
      /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
      setobj(L, f->upvals[0]->v, gt);
      luaC_barrier(L, f->upvals[0], gt);
@@ -1101,18 +1136,19 @@ LUA_API int lua_status (lua_State *L) {
LUA_API int lua_gc (lua_State *L, int what, ...) {
  va_list argp;
  int res = 0;
-
  global_State *g;
+
  global_State *g = G(L);
+
  if (g->gcstp & GCSTPGC)  /* internal stop? */
+
    return -1;  /* all options are invalid when stopped */
  lua_lock(L);
-
  g = G(L);
  va_start(argp, what);
  switch (what) {
    case LUA_GCSTOP: {
-
      g->gcrunning = 0;
+
      g->gcstp = GCSTPUSR;  /* stopped by the user */
      break;
    }
    case LUA_GCRESTART: {
      luaE_setdebt(g, 0);
-
      g->gcrunning = 1;
+
      g->gcstp = 0;  /* (GCSTPGC must be already zero here) */
      break;
    }
    case LUA_GCCOLLECT: {
@@ -1131,8 +1167,8 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
    case LUA_GCSTEP: {
      int data = va_arg(argp, int);
      l_mem debt = 1;  /* =1 to signal that it did an actual step */
-
      lu_byte oldrunning = g->gcrunning;
-
      g->gcrunning = 1;  /* allow GC to run */
+
      lu_byte oldstp = g->gcstp;
+
      g->gcstp = 0;  /* allow GC to run (GCSTPGC must be zero here) */
      if (data == 0) {
        luaE_setdebt(g, 0);  /* do a basic step */
        luaC_step(L);
@@ -1142,7 +1178,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
        luaE_setdebt(g, debt);
        luaC_checkGC(L);
      }
-
      g->gcrunning = oldrunning;  /* restore previous state */
+
      g->gcstp = oldstp;  /* restore previous state */
      if (debt > 0 && g->gcstate == GCSpause)  /* end of cycle? */
        res = 1;  /* signal it */
      break;
@@ -1160,7 +1196,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
      break;
    }
    case LUA_GCISRUNNING: {
-
      res = g->gcrunning;
+
      res = gcrunning(g);
      break;
    }
    case LUA_GCGEN: {
@@ -1240,8 +1276,7 @@ LUA_API void lua_toclose (lua_State *L, int idx) {
  lua_lock(L);
  o = index2stack(L, idx);
  nresults = L->ci->nresults;
-
  api_check(L, L->openupval == NULL || uplevel(L->openupval) <= o,
-
               "marked index below or equal new one");
+
  api_check(L, L->tbclist < o, "given index below or equal a marked one");
  luaF_newtbcupval(L, o);  /* create new to-be-closed upvalue */
  if (!hastocloseCfunc(nresults))  /* function not marked yet? */
    L->ci->nresults = codeNresults(nresults);  /* mark it */
modified external/lua/src/lapi.h
@@ -42,6 +42,8 @@

#define hastocloseCfunc(n)	((n) < LUA_MULTRET)

+
/* Map [-1, inf) (range of 'nresults') into (-inf, -2] */
#define codeNresults(n)		(-(n) - 3)
+
#define decodeNresults(n)	(-(n) - 3)

#endif
modified external/lua/src/lauxlib.c
@@ -190,7 +190,7 @@ LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
}


-
int luaL_typeerror (lua_State *L, int arg, const char *tname) {
+
LUALIB_API int luaL_typeerror (lua_State *L, int arg, const char *tname) {
  const char *msg;
  const char *typearg;  /* name for the type of the actual argument */
  if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
@@ -378,7 +378,7 @@ LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
** but without 'msg'.)
*/
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
-
  if (!lua_checkstack(L, space)) {
+
  if (l_unlikely(!lua_checkstack(L, space))) {
    if (msg)
      luaL_error(L, "stack overflow (%s)", msg);
    else
@@ -388,20 +388,20 @@ LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {


LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
-
  if (lua_type(L, arg) != t)
+
  if (l_unlikely(lua_type(L, arg) != t))
    tag_error(L, arg, t);
}


LUALIB_API void luaL_checkany (lua_State *L, int arg) {
-
  if (lua_type(L, arg) == LUA_TNONE)
+
  if (l_unlikely(lua_type(L, arg) == LUA_TNONE))
    luaL_argerror(L, arg, "value expected");
}


LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
  const char *s = lua_tolstring(L, arg, len);
-
  if (!s) tag_error(L, arg, LUA_TSTRING);
+
  if (l_unlikely(!s)) tag_error(L, arg, LUA_TSTRING);
  return s;
}

@@ -420,7 +420,7 @@ LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
  int isnum;
  lua_Number d = lua_tonumberx(L, arg, &isnum);
-
  if (!isnum)
+
  if (l_unlikely(!isnum))
    tag_error(L, arg, LUA_TNUMBER);
  return d;
}
@@ -442,7 +442,7 @@ static void interror (lua_State *L, int arg) {
LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
  int isnum;
  lua_Integer d = lua_tointegerx(L, arg, &isnum);
-
  if (!isnum) {
+
  if (l_unlikely(!isnum)) {
    interror(L, arg);
  }
  return d;
@@ -475,7 +475,7 @@ static void *resizebox (lua_State *L, int idx, size_t newsize) {
  lua_Alloc allocf = lua_getallocf(L, &ud);
  UBox *box = (UBox *)lua_touserdata(L, idx);
  void *temp = allocf(ud, box->box, box->bsize, newsize);
-
  if (temp == NULL && newsize > 0) {  /* allocation error? */
+
  if (l_unlikely(temp == NULL && newsize > 0)) {  /* allocation error? */
    lua_pushliteral(L, "not enough memory");
    lua_error(L);  /* raise a memory error */
  }
@@ -516,12 +516,21 @@ static void newbox (lua_State *L) {


/*
+
** Whenever buffer is accessed, slot 'idx' must either be a box (which
+
** cannot be NULL) or it is a placeholder for the buffer.
+
*/
+
#define checkbufferlevel(B,idx)  \
+
  lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL  \
+
                            : lua_touserdata(B->L, idx) == (void*)B)
+

+

+
/*
** Compute new size for buffer 'B', enough to accommodate extra 'sz'
** bytes.
*/
static size_t newbuffsize (luaL_Buffer *B, size_t sz) {
  size_t newsize = B->size * 2;  /* double buffer size */
-
  if (MAX_SIZET - sz < B->n)  /* overflow in (B->n + sz)? */
+
  if (l_unlikely(MAX_SIZET - sz < B->n))  /* overflow in (B->n + sz)? */
    return luaL_error(B->L, "buffer too large");
  if (newsize < B->n + sz)  /* double is not big enough? */
    newsize = B->n + sz;
@@ -531,10 +540,11 @@ static size_t newbuffsize (luaL_Buffer *B, size_t sz) {

/*
** Returns a pointer to a free area with at least 'sz' bytes in buffer
-
** 'B'. 'boxidx' is the relative position in the stack where the
-
** buffer's box is or should be.
+
** 'B'. 'boxidx' is the relative position in the stack where is the
+
** buffer's box or its placeholder.
*/
static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) {
+
  checkbufferlevel(B, boxidx);
  if (B->size - B->n >= sz)  /* enough space? */
    return B->b + B->n;
  else {
@@ -545,10 +555,9 @@ static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) {
    if (buffonstack(B))  /* buffer already has a box? */
      newbuff = (char *)resizebox(L, boxidx, newsize);  /* resize it */
    else {  /* no box yet */
-
      lua_pushnil(L);  /* reserve slot for final result */
+
      lua_remove(L, boxidx);  /* remove placeholder */
      newbox(L);  /* create a new box */
-
      /* move box (and slot) to its intended position */
-
      lua_rotate(L, boxidx - 1, 2);
+
      lua_insert(L, boxidx);  /* move box to its intended position */
      lua_toclose(L, boxidx);
      newbuff = (char *)resizebox(L, boxidx, newsize);
      memcpy(newbuff, B->b, B->n * sizeof(char));  /* copy original content */
@@ -583,11 +592,11 @@ LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {

LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
  lua_State *L = B->L;
+
  checkbufferlevel(B, -1);
  lua_pushlstring(L, B->b, B->n);
-
  if (buffonstack(B)) {
-
    lua_copy(L, -1, -3);  /* move string to reserved slot */
-
    lua_pop(L, 2);  /* pop string and box (closing the box) */
-
  }
+
  if (buffonstack(B))
+
    lua_closeslot(L, -2);  /* close the box */
+
  lua_remove(L, -2);  /* remove box or placeholder from the stack */
}


@@ -622,6 +631,7 @@ LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
  B->b = B->init.b;
  B->n = 0;
  B->size = LUAL_BUFFERSIZE;
+
  lua_pushlightuserdata(L, (void*)B);  /* push placeholder */
}


@@ -639,10 +649,14 @@ LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
** =======================================================
*/

-
/* index of free-list header */
-
#define freelist	0
-

+
/* index of free-list header (after the predefined values) */
+
#define freelist	(LUA_RIDX_LAST + 1)

+
/*
+
** The previously freed references form a linked list:
+
** t[freelist] is the index of a first free index, or zero if list is
+
** empty; t[t[freelist]] is the index of the second element; etc.
+
*/
LUALIB_API int luaL_ref (lua_State *L, int t) {
  int ref;
  if (lua_isnil(L, -1)) {
@@ -650,9 +664,16 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
    return LUA_REFNIL;  /* 'nil' has a unique fixed reference */
  }
  t = lua_absindex(L, t);
-
  lua_rawgeti(L, t, freelist);  /* get first free element */
-
  ref = (int)lua_tointeger(L, -1);  /* ref = t[freelist] */
-
  lua_pop(L, 1);  /* remove it from stack */
+
  if (lua_rawgeti(L, t, freelist) == LUA_TNIL) {  /* first access? */
+
    ref = 0;  /* list is empty */
+
    lua_pushinteger(L, 0);  /* initialize as an empty list */
+
    lua_rawseti(L, t, freelist);  /* ref = t[freelist] = 0 */
+
  }
+
  else {  /* already initialized */
+
    lua_assert(lua_isinteger(L, -1));
+
    ref = (int)lua_tointeger(L, -1);  /* ref = t[freelist] */
+
  }
+
  lua_pop(L, 1);  /* remove element from stack */
  if (ref != 0) {  /* any free element? */
    lua_rawgeti(L, t, ref);  /* remove it from list */
    lua_rawseti(L, t, freelist);  /* (t[freelist] = t[ref]) */
@@ -668,6 +689,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
  if (ref >= 0) {
    t = lua_absindex(L, t);
    lua_rawgeti(L, t, freelist);
+
    lua_assert(lua_isinteger(L, -1));
    lua_rawseti(L, t, ref);  /* t[ref] = t[freelist] */
    lua_pushinteger(L, ref);
    lua_rawseti(L, t, freelist);  /* t[freelist] = ref */
@@ -851,7 +873,7 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
  int isnum;
  lua_len(L, idx);
  l = lua_tointegerx(L, -1, &isnum);
-
  if (!isnum)
+
  if (l_unlikely(!isnum))
    luaL_error(L, "object length is not an integer");
  lua_pop(L, 1);  /* remove object */
  return l;
@@ -859,6 +881,7 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {


LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
+
  idx = lua_absindex(L,idx);
  if (luaL_callmeta(L, idx, "__tostring")) {  /* metafield? */
    if (!lua_isstring(L, -1))
      luaL_error(L, "'__tostring' must return a string");
@@ -1064,7 +1087,7 @@ static void warnfon (void *ud, const char *message, int tocont) {

LUALIB_API lua_State *luaL_newstate (void) {
  lua_State *L = lua_newstate(l_alloc, NULL);
-
  if (L) {
+
  if (l_likely(L)) {
    lua_atpanic(L, &panic);
    lua_setwarnf(L, warnfoff, L);  /* default is warnings off */
  }
modified external/lua/src/lauxlib.h
@@ -12,6 +12,7 @@
#include <stddef.h>
#include <stdio.h>

+
#include "luaconf.h"
#include "lua.h"


@@ -101,7 +102,7 @@ LUALIB_API lua_State *(luaL_newstate) (void);

LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);

-
LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
+
LUALIB_API void (luaL_addgsub) (luaL_Buffer *b, const char *s,
                                     const char *p, const char *r);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s,
                                    const char *p, const char *r);
@@ -130,10 +131,10 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
  (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))

#define luaL_argcheck(L, cond,arg,extramsg)	\
-
		((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
+
	((void)(luai_likely(cond) || luaL_argerror(L, (arg), (extramsg))))

#define luaL_argexpected(L,cond,arg,tname)	\
-
		((void)((cond) || luaL_typeerror(L, (arg), (tname))))
+
	((void)(luai_likely(cond) || luaL_typeerror(L, (arg), (tname))))

#define luaL_checkstring(L,n)	(luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d)	(luaL_optlstring(L, (n), (d), NULL))
@@ -153,11 +154,35 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
#define luaL_loadbuffer(L,s,sz,n)	luaL_loadbufferx(L,s,sz,n,NULL)


+
/*
+
** Perform arithmetic operations on lua_Integer values with wrap-around
+
** semantics, as the Lua core does.
+
*/
+
#define luaL_intop(op,v1,v2)  \
+
	((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2)))
+

+

/* push the value used to represent failure/error */
#define luaL_pushfail(L)	lua_pushnil(L)


/*
+
** Internal assertions for in-house debugging
+
*/
+
#if !defined(lua_assert)
+

+
#if defined LUAI_ASSERT
+
  #include <assert.h>
+
  #define lua_assert(c)		assert(c)
+
#else
+
  #define lua_assert(c)		((void)0)
+
#endif
+

+
#endif
+

+

+

+
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
modified external/lua/src/lbaselib.c
@@ -138,7 +138,7 @@ static int luaB_setmetatable (lua_State *L) {
  int t = lua_type(L, 2);
  luaL_checktype(L, 1, LUA_TTABLE);
  luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table");
-
  if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
+
  if (l_unlikely(luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL))
    return luaL_error(L, "cannot change a protected metatable");
  lua_settop(L, 2);
  lua_setmetatable(L, 1);
@@ -182,11 +182,20 @@ static int luaB_rawset (lua_State *L) {


static int pushmode (lua_State *L, int oldmode) {
-
  lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" : "generational");
+
  if (oldmode == -1)
+
    luaL_pushfail(L);  /* invalid call to 'lua_gc' */
+
  else
+
    lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental"
+
                                             : "generational");
  return 1;
}


+
/*
+
** check whether call to 'lua_gc' was valid (not inside a finalizer)
+
*/
+
#define checkvalres(res) { if (res == -1) break; }
+

static int luaB_collectgarbage (lua_State *L) {
  static const char *const opts[] = {"stop", "restart", "collect",
    "count", "step", "setpause", "setstepmul",
@@ -199,12 +208,14 @@ static int luaB_collectgarbage (lua_State *L) {
    case LUA_GCCOUNT: {
      int k = lua_gc(L, o);
      int b = lua_gc(L, LUA_GCCOUNTB);
+
      checkvalres(k);
      lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024));
      return 1;
    }
    case LUA_GCSTEP: {
      int step = (int)luaL_optinteger(L, 2, 0);
      int res = lua_gc(L, o, step);
+
      checkvalres(res);
      lua_pushboolean(L, res);
      return 1;
    }
@@ -212,11 +223,13 @@ static int luaB_collectgarbage (lua_State *L) {
    case LUA_GCSETSTEPMUL: {
      int p = (int)luaL_optinteger(L, 2, 0);
      int previous = lua_gc(L, o, p);
+
      checkvalres(previous);
      lua_pushinteger(L, previous);
      return 1;
    }
    case LUA_GCISRUNNING: {
      int res = lua_gc(L, o);
+
      checkvalres(res);
      lua_pushboolean(L, res);
      return 1;
    }
@@ -233,10 +246,13 @@ static int luaB_collectgarbage (lua_State *L) {
    }
    default: {
      int res = lua_gc(L, o);
+
      checkvalres(res);
      lua_pushinteger(L, res);
      return 1;
    }
  }
+
  luaL_pushfail(L);  /* invalid call (inside a finalizer) */
+
  return 1;
}


@@ -260,6 +276,11 @@ static int luaB_next (lua_State *L) {
}


+
static int pairscont (lua_State *L, int status, lua_KContext k) {
+
  (void)L; (void)status; (void)k;  /* unused */
+
  return 3;
+
}
+

static int luaB_pairs (lua_State *L) {
  luaL_checkany(L, 1);
  if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) {  /* no metamethod? */
@@ -269,7 +290,7 @@ static int luaB_pairs (lua_State *L) {
  }
  else {
    lua_pushvalue(L, 1);  /* argument 'self' to metamethod */
-
    lua_call(L, 1, 3);  /* get 3 values from metamethod */
+
    lua_callk(L, 1, 3, 0, pairscont);  /* get 3 values from metamethod */
  }
  return 3;
}
@@ -279,7 +300,8 @@ static int luaB_pairs (lua_State *L) {
** Traversal function for 'ipairs'
*/
static int ipairsaux (lua_State *L) {
-
  lua_Integer i = luaL_checkinteger(L, 2) + 1;
+
  lua_Integer i = luaL_checkinteger(L, 2);
+
  i = luaL_intop(+, i, 1);
  lua_pushinteger(L, i);
  return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
}
@@ -299,7 +321,7 @@ static int luaB_ipairs (lua_State *L) {


static int load_aux (lua_State *L, int status, int envidx) {
-
  if (status == LUA_OK) {
+
  if (l_likely(status == LUA_OK)) {
    if (envidx != 0) {  /* 'env' parameter? */
      lua_pushvalue(L, envidx);  /* environment for loaded function */
      if (!lua_setupvalue(L, -2, 1))  /* set it as 1st upvalue */
@@ -355,7 +377,7 @@ static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
    *size = 0;
    return NULL;
  }
-
  else if (!lua_isstring(L, -1))
+
  else if (l_unlikely(!lua_isstring(L, -1)))
    luaL_error(L, "reader function must return a string");
  lua_replace(L, RESERVEDSLOT);  /* save string in reserved slot */
  return lua_tolstring(L, RESERVEDSLOT, size);
@@ -393,7 +415,7 @@ static int dofilecont (lua_State *L, int d1, lua_KContext d2) {
static int luaB_dofile (lua_State *L) {
  const char *fname = luaL_optstring(L, 1, NULL);
  lua_settop(L, 1);
-
  if (luaL_loadfile(L, fname) != LUA_OK)
+
  if (l_unlikely(luaL_loadfile(L, fname) != LUA_OK))
    return lua_error(L);
  lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
  return dofilecont(L, 0, 0);
@@ -401,7 +423,7 @@ static int luaB_dofile (lua_State *L) {


static int luaB_assert (lua_State *L) {
-
  if (lua_toboolean(L, 1))  /* condition is true? */
+
  if (l_likely(lua_toboolean(L, 1)))  /* condition is true? */
    return lua_gettop(L);  /* return all arguments */
  else {  /* error */
    luaL_checkany(L, 1);  /* there must be a condition */
@@ -437,7 +459,7 @@ static int luaB_select (lua_State *L) {
** ignored).
*/
static int finishpcall (lua_State *L, int status, lua_KContext extra) {
-
  if (status != LUA_OK && status != LUA_YIELD) {  /* error? */
+
  if (l_unlikely(status != LUA_OK && status != LUA_YIELD)) {  /* error? */
    lua_pushboolean(L, 0);  /* first result (false) */
    lua_pushvalue(L, -2);  /* error message */
    return 2;  /* return false, msg */
modified external/lua/src/lcode.c
@@ -10,6 +10,7 @@
#include "lprefix.h"


+
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
@@ -314,15 +315,6 @@ void luaK_patchtohere (FuncState *fs, int list) {
}


-
/*
-
** MAXimum number of successive Instructions WiTHout ABSolute line
-
** information.
-
*/
-
#if !defined(MAXIWTHABS)
-
#define MAXIWTHABS	120
-
#endif
-

-

/* limit for difference between lines in relative line info. */
#define LIMLINEDIFF	0x80

@@ -337,13 +329,13 @@ void luaK_patchtohere (FuncState *fs, int list) {
static void savelineinfo (FuncState *fs, Proto *f, int line) {
  int linedif = line - fs->previousline;
  int pc = fs->pc - 1;  /* last instruction coded */
-
  if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ > MAXIWTHABS) {
+
  if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ >= MAXIWTHABS) {
    luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo,
                    f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines");
    f->abslineinfo[fs->nabslineinfo].pc = pc;
    f->abslineinfo[fs->nabslineinfo++].line = line;
    linedif = ABSLINEINFO;  /* signal that there is absolute information */
-
    fs->iwthabs = 0;  /* restart counter */
+
    fs->iwthabs = 1;  /* restart counter */
  }
  luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte,
                  MAX_INT, "opcodes");
@@ -545,11 +537,14 @@ static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
** and try to reuse constants. Because some values should not be used
** as keys (nil cannot be a key, integer keys can collapse with float
** keys), the caller must provide a useful 'key' for indexing the cache.
+
** Note that all functions share the same table, so entering or exiting
+
** a function can make some indices wrong.
*/
static int addk (FuncState *fs, TValue *key, TValue *v) {
+
  TValue val;
  lua_State *L = fs->ls->L;
  Proto *f = fs->f;
-
  TValue *idx = luaH_set(L, fs->ls->h, key);  /* index scanner table */
+
  const TValue *idx = luaH_get(fs->ls->h, key);  /* query scanner table */
  int k, oldsize;
  if (ttisinteger(idx)) {  /* is there an index there? */
    k = cast_int(ivalue(idx));
@@ -563,7 +558,8 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
  k = fs->nk;
  /* numerical value does not need GC barrier;
     table has no metatable, so it does not need to invalidate cache */
-
  setivalue(idx, k);
+
  setivalue(&val, k);
+
  luaH_finishset(L, fs->ls->h, key, idx, &val);
  luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
  while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
  setobj(L, &f->k[k], v);
@@ -585,24 +581,41 @@ static int stringK (FuncState *fs, TString *s) {

/*
** Add an integer to list of constants and return its index.
-
** Integers use userdata as keys to avoid collision with floats with
-
** same value; conversion to 'void*' is used only for hashing, so there
-
** are no "precision" problems.
*/
static int luaK_intK (FuncState *fs, lua_Integer n) {
-
  TValue k, o;
-
  setpvalue(&k, cast_voidp(cast_sizet(n)));
+
  TValue o;
  setivalue(&o, n);
-
  return addk(fs, &k, &o);
+
  return addk(fs, &o, &o);  /* use integer itself as key */
}

/*
-
** Add a float to list of constants and return its index.
+
** 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
+
** power-of-two fraction that is still significant in its scale.
+
** For doubles, that would be 1/2^52.
+
** (This method is not bulletproof: there may be another float
+
** with that value, and for floats larger than 2^53 the result is
+
** still an integer. At worst, this only wastes an entry with
+
** a duplicate.)
*/
static int luaK_numberK (FuncState *fs, lua_Number r) {
  TValue o;
+
  lua_Integer ik;
  setfltvalue(&o, r);
-
  return addk(fs, &o, &o);  /* use number itself as key */
+
  if (!luaV_flttointeger(r, &ik, F2Ieq))  /* not an integral value? */
+
    return addk(fs, &o, &o);  /* use number itself as key */
+
  else {  /* must build an alternative key */
+
    const int nbm = l_floatatt(MANT_DIG);
+
    const lua_Number q = l_mathop(ldexp)(l_mathop(1.0), -nbm + 1);
+
    const lua_Number k = (ik == 0) ? q : r + r*q;  /* new key */
+
    TValue kv;
+
    setfltvalue(&kv, k);
+
    /* result is not an integral value, unless value is too large */
+
    lua_assert(!luaV_flttointeger(k, &ik, F2Ieq) ||
+
                l_mathop(fabs)(r) >= l_mathop(1e6));
+
    return addk(fs, &kv, &o);
+
  }
}


@@ -763,7 +776,7 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
      break;
    }
    case VLOCAL: {  /* already in a register */
-
      e->u.info = e->u.var.sidx;
+
      e->u.info = e->u.var.ridx;
      e->k = VNONRELOC;  /* becomes a non-relocatable value */
      break;
    }
@@ -1036,7 +1049,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
  switch (var->k) {
    case VLOCAL: {
      freeexp(fs, ex);
-
      exp2reg(fs, ex, var->u.var.sidx);  /* compute 'ex' into proper place */
+
      exp2reg(fs, ex, var->u.var.ridx);  /* compute 'ex' into proper place */
      return;
    }
    case VUPVAL: {
@@ -1276,7 +1289,7 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
  }
  else {
    /* register index of the table */
-
    t->u.ind.t = (t->k == VLOCAL) ? t->u.var.sidx: t->u.info;
+
    t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info;
    if (isKstr(fs, k)) {
      t->u.ind.idx = k->u.info;  /* literal string */
      t->k = VINDEXSTR;
@@ -1303,7 +1316,8 @@ static int validop (int op, TValue *v1, TValue *v2) {
    case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
    case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: {  /* conversion errors */
      lua_Integer i;
-
      return (tointegerns(v1, &i) && tointegerns(v2, &i));
+
      return (luaV_tointegerns(v1, &i, LUA_FLOORN2I) &&
+
              luaV_tointegerns(v2, &i, LUA_FLOORN2I));
    }
    case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD:  /* division by 0 */
      return (nvalue(v2) != 0);
modified external/lua/src/lcorolib.c
@@ -31,14 +31,14 @@ static lua_State *getco (lua_State *L) {
*/
static int auxresume (lua_State *L, lua_State *co, int narg) {
  int status, nres;
-
  if (!lua_checkstack(co, narg)) {
+
  if (l_unlikely(!lua_checkstack(co, narg))) {
    lua_pushliteral(L, "too many arguments to resume");
    return -1;  /* error flag */
  }
  lua_xmove(L, co, narg);
  status = lua_resume(co, L, narg, &nres);
-
  if (status == LUA_OK || status == LUA_YIELD) {
-
    if (!lua_checkstack(L, nres + 1)) {
+
  if (l_likely(status == LUA_OK || status == LUA_YIELD)) {
+
    if (l_unlikely(!lua_checkstack(L, nres + 1))) {
      lua_pop(co, nres);  /* remove results anyway */
      lua_pushliteral(L, "too many results to resume");
      return -1;  /* error flag */
@@ -57,7 +57,7 @@ static int luaB_coresume (lua_State *L) {
  lua_State *co = getco(L);
  int r;
  r = auxresume(L, co, lua_gettop(L) - 1);
-
  if (r < 0) {
+
  if (l_unlikely(r < 0)) {
    lua_pushboolean(L, 0);
    lua_insert(L, -2);
    return 2;  /* return false + error message */
@@ -73,10 +73,13 @@ static int luaB_coresume (lua_State *L) {
static int luaB_auxwrap (lua_State *L) {
  lua_State *co = lua_tothread(L, lua_upvalueindex(1));
  int r = auxresume(L, co, lua_gettop(L));
-
  if (r < 0) {  /* error? */
+
  if (l_unlikely(r < 0)) {  /* error? */
    int stat = lua_status(co);
-
    if (stat != LUA_OK && stat != LUA_YIELD)  /* error in the coroutine? */
-
      lua_resetthread(co);  /* close its tbc variables */
+
    if (stat != LUA_OK && stat != LUA_YIELD) {  /* error in the coroutine? */
+
      stat = lua_resetthread(co);  /* close its tbc variables */
+
      lua_assert(stat != LUA_OK);
+
      lua_xmove(co, L, 1);  /* move error message to the caller */
+
    }
    if (stat != LUA_ERRMEM &&  /* not a memory error and ... */
        lua_type(L, -1) == LUA_TSTRING) {  /* ... error object is a string? */
      luaL_where(L, 1);  /* add extra info, if available */
@@ -176,7 +179,7 @@ static int luaB_close (lua_State *L) {
      }
      else {
        lua_pushboolean(L, 0);
-
        lua_xmove(co, L, 1);  /* copy error message */
+
        lua_xmove(co, L, 1);  /* move error message */
        return 2;
      }
    }
modified external/lua/src/ldblib.c
@@ -33,7 +33,7 @@ static const char *const HOOKKEY = "_HOOKKEY";
** checked.
*/
static void checkstack (lua_State *L, lua_State *L1, int n) {
-
  if (L != L1 && !lua_checkstack(L1, n))
+
  if (l_unlikely(L != L1 && !lua_checkstack(L1, n)))
    luaL_error(L, "stack overflow");
}

@@ -152,6 +152,7 @@ static int db_getinfo (lua_State *L) {
  lua_State *L1 = getthread(L, &arg);
  const char *options = luaL_optstring(L, arg+2, "flnSrtu");
  checkstack(L, L1, 3);
+
  luaL_argcheck(L, options[0] != '>', arg + 2, "invalid option '>'");
  if (lua_isfunction(L, arg + 1)) {  /* info about a function? */
    options = lua_pushfstring(L, ">%s", options);  /* add '>' to 'options' */
    lua_pushvalue(L, arg + 1);  /* move function to 'L1' stack */
@@ -212,7 +213,7 @@ static int db_getlocal (lua_State *L) {
    lua_Debug ar;
    const char *name;
    int level = (int)luaL_checkinteger(L, arg + 1);
-
    if (!lua_getstack(L1, level, &ar))  /* out of range? */
+
    if (l_unlikely(!lua_getstack(L1, level, &ar)))  /* out of range? */
      return luaL_argerror(L, arg+1, "level out of range");
    checkstack(L, L1, 1);
    name = lua_getlocal(L1, &ar, nvar);
@@ -237,7 +238,7 @@ static int db_setlocal (lua_State *L) {
  lua_Debug ar;
  int level = (int)luaL_checkinteger(L, arg + 1);
  int nvar = (int)luaL_checkinteger(L, arg + 2);
-
  if (!lua_getstack(L1, level, &ar))  /* out of range? */
+
  if (l_unlikely(!lua_getstack(L1, level, &ar)))  /* out of range? */
    return luaL_argerror(L, arg+1, "level out of range");
  luaL_checkany(L, arg+3);
  lua_settop(L, arg+3);
@@ -377,7 +378,7 @@ static int db_sethook (lua_State *L) {
  }
  if (!luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)) {
    /* table just created; initialize it */
-
    lua_pushstring(L, "k");
+
    lua_pushliteral(L, "k");
    lua_setfield(L, -2, "__mode");  /** hooktable.__mode = "k" */
    lua_pushvalue(L, -1);
    lua_setmetatable(L, -2);  /* metatable(hooktable) = hooktable */
@@ -420,7 +421,7 @@ static int db_debug (lua_State *L) {
  for (;;) {
    char buffer[250];
    lua_writestringerror("%s", "lua_debug> ");
-
    if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
+
    if (fgets(buffer, sizeof(buffer), stdin) == NULL ||
        strcmp(buffer, "cont\n") == 0)
      return 0;
    if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
modified external/lua/src/ldebug.c
@@ -33,11 +33,9 @@

#define noLuaClosure(f)		((f) == NULL || (f)->c.tt == LUA_VCCL)

-
/* inverse of 'pcRel' */
-
#define invpcRel(pc, p)		((p)->code + (pc) + 1)

-
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
-
                                    const char **name);
+
static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
+
                                                   const char **name);


static int currentpc (CallInfo *ci) {
@@ -48,10 +46,16 @@ static int currentpc (CallInfo *ci) {

/*
** Get a "base line" to find the line corresponding to an instruction.
-
** For that, search the array of absolute line info for the largest saved
-
** instruction smaller or equal to the wanted instruction. A special
-
** case is when there is no absolute info or the instruction is before
-
** the first absolute one.
+
** Base lines are regularly placed at MAXIWTHABS intervals, so usually
+
** an integer division gets the right place. When the source file has
+
** large sequences of empty/comment lines, it may need extra entries,
+
** so the original estimate needs a correction.
+
** If the original estimate is -1, the initial 'if' ensures that the
+
** 'while' will run at least once.
+
** The assertion that the estimate is a lower bound for the correct base
+
** is valid as long as the debug info has been generated with the same
+
** value for MAXIWTHABS or smaller. (Previous releases use a little
+
** smaller value.)
*/
static int getbaseline (const Proto *f, int pc, int *basepc) {
  if (f->sizeabslineinfo == 0 || pc < f->abslineinfo[0].pc) {
@@ -59,20 +63,12 @@ static int getbaseline (const Proto *f, int pc, int *basepc) {
    return f->linedefined;
  }
  else {
-
    unsigned int i;
-
    if (pc >= f->abslineinfo[f->sizeabslineinfo - 1].pc)
-
      i = f->sizeabslineinfo - 1;  /* instruction is after last saved one */
-
    else {  /* binary search */
-
      unsigned int j = f->sizeabslineinfo - 1;  /* pc < anchorlines[j] */
-
      i = 0;  /* abslineinfo[i] <= pc */
-
      while (i < j - 1) {
-
        unsigned int m = (j + i) / 2;
-
        if (pc >= f->abslineinfo[m].pc)
-
          i = m;
-
        else
-
          j = m;
-
      }
-
    }
+
    int i = cast_uint(pc) / MAXIWTHABS - 1;  /* get an estimate */
+
    /* estimate must be a lower bound of the correct base */
+
    lua_assert(i < 0 ||
+
              (i < f->sizeabslineinfo && f->abslineinfo[i].pc <= pc));
+
    while (i + 1 < f->sizeabslineinfo && pc >= f->abslineinfo[i + 1].pc)
+
      i++;  /* low estimate; adjust it */
    *basepc = f->abslineinfo[i].pc;
    return f->abslineinfo[i].line;
  }
@@ -305,8 +301,15 @@ static void collectvalidlines (lua_State *L, Closure *f) {
    sethvalue2s(L, L->top, t);  /* push it on stack */
    api_incr_top(L);
    setbtvalue(&v);  /* boolean 'true' to be the value of all indices */
-
    for (i = 0; i < p->sizelineinfo; i++) {  /* for all lines with code */
-
      currentline = nextline(p, currentline, i);
+
    if (!p->is_vararg)  /* regular function? */
+
      i = 0;  /* consider all instructions */
+
    else {  /* vararg function */
+
      lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP);
+
      currentline = nextline(p, currentline, 0);
+
      i = 1;  /* skip first instruction (OP_VARARGPREP) */
+
    }
+
    for (; i < p->sizelineinfo; i++) {  /* for each instruction */
+
      currentline = nextline(p, currentline, i);  /* get its line */
      luaH_setint(L, t, currentline, &v);  /* table[line] = true */
    }
  }
@@ -314,15 +317,9 @@ static void collectvalidlines (lua_State *L, Closure *f) {


static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
-
  if (ci == NULL)  /* no 'ci'? */
-
    return NULL;  /* no info */
-
  else if (ci->callstatus & CIST_FIN) {  /* is this a finalizer? */
-
    *name = "__gc";
-
    return "metamethod";  /* report it as such */
-
  }
-
  /* calling function is a known Lua function? */
-
  else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
-
    return funcnamefromcode(L, ci->previous, name);
+
  /* calling function is a known function? */
+
  if (ci != NULL && !(ci->callstatus & CIST_TAIL))
+
    return funcnamefromcall(L, ci->previous, name);
  else return NULL;  /* no way to find a name */
}

@@ -594,16 +591,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
** Returns what the name is (e.g., "for iterator", "method",
** "metamethod") and sets '*name' to point to the name.
*/
-
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
-
                                     const char **name) {
+
static const char *funcnamefromcode (lua_State *L, const Proto *p,
+
                                     int pc, const char **name) {
  TMS tm = (TMS)0;  /* (initial value avoids warnings) */
-
  const Proto *p = ci_func(ci)->p;  /* calling function */
-
  int pc = currentpc(ci);  /* calling instruction index */
  Instruction i = p->code[pc];  /* calling instruction */
-
  if (ci->callstatus & CIST_HOOKED) {  /* was it called inside a hook? */
-
    *name = "?";
-
    return "hook";
-
  }
  switch (GET_OPCODE(i)) {
    case OP_CALL:
    case OP_TAILCALL:
@@ -629,12 +620,10 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
    case OP_LEN: tm = TM_LEN; break;
    case OP_CONCAT: tm = TM_CONCAT; break;
    case OP_EQ: tm = TM_EQ; break;
-
    case OP_LT: case OP_LE: case OP_LTI: case OP_LEI:
-
      *name = "order";  /* '<=' can call '__lt', etc. */
-
      return "metamethod";
-
    case OP_CLOSE: case OP_RETURN:
-
      *name = "close";
-
      return "metamethod";
+
    /* no cases for OP_EQI and OP_EQK, as they don't call metamethods */
+
    case OP_LT: case OP_LTI: case OP_GTI: tm = TM_LT; break;
+
    case OP_LE: case OP_LEI: case OP_GEI: tm = TM_LE; break;
+
    case OP_CLOSE: case OP_RETURN: tm = TM_CLOSE; break;
    default:
      return NULL;  /* cannot find a reasonable name */
  }
@@ -642,19 +631,43 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
  return "metamethod";
}

+

+
/*
+
** Try to find a name for a function based on how it was called.
+
*/
+
static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
+
                                                   const char **name) {
+
  if (ci->callstatus & CIST_HOOKED) {  /* was it called inside a hook? */
+
    *name = "?";
+
    return "hook";
+
  }
+
  else if (ci->callstatus & CIST_FIN) {  /* was it called as a finalizer? */
+
    *name = "__gc";
+
    return "metamethod";  /* report it as such */
+
  }
+
  else if (isLua(ci))
+
    return funcnamefromcode(L, ci_func(ci)->p, currentpc(ci), name);
+
  else
+
    return NULL;
+
}
+

/* }====================================================== */



/*
-
** The subtraction of two potentially unrelated pointers is
-
** not ISO C, but it should not crash a program; the subsequent
-
** checks are ISO C and ensure a correct result.
+
** Check whether pointer 'o' points to some value in the stack
+
** frame of the current function. Because 'o' may not point to a
+
** value in this stack, we cannot compare it with the region
+
** boundaries (undefined behaviour in ISO C).
*/
static int isinstack (CallInfo *ci, const TValue *o) {
-
  StkId base = ci->func + 1;
-
  ptrdiff_t i = cast(StkId, o) - base;
-
  return (0 <= i && i < (ci->top - base) && s2v(base + i) == o);
+
  StkId pos;
+
  for (pos = ci->func + 1; pos < ci->top; pos++) {
+
    if (o == s2v(pos))
+
      return 1;
+
  }
+
  return 0;  /* not found */
}


@@ -677,9 +690,21 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
}


+
static const char *formatvarinfo (lua_State *L, const char *kind,
+
                                                const char *name) {
+
  if (kind == NULL)
+
    return "";  /* no information */
+
  else
+
    return luaO_pushfstring(L, " (%s '%s')", kind, name);
+
}
+

+
/*
+
** Build a string with a "description" for the value 'o', such as
+
** "variable 'x'" or "upvalue 'y'".
+
*/
static const char *varinfo (lua_State *L, const TValue *o) {
-
  const char *name = NULL;  /* to avoid warnings */
  CallInfo *ci = L->ci;
+
  const char *name = NULL;  /* to avoid warnings */
  const char *kind = NULL;
  if (isLua(ci)) {
    kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
@@ -687,13 +712,40 @@ static const char *varinfo (lua_State *L, const TValue *o) {
      kind = getobjname(ci_func(ci)->p, currentpc(ci),
                        cast_int(cast(StkId, o) - (ci->func + 1)), &name);
  }
-
  return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
+
  return formatvarinfo(L, kind, name);
}


-
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+
/*
+
** Raise a type error
+
*/
+
static l_noret typeerror (lua_State *L, const TValue *o, const char *op,
+
                          const char *extra) {
  const char *t = luaT_objtypename(L, o);
-
  luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
+
  luaG_runerror(L, "attempt to %s a %s value%s", op, t, extra);
+
}
+

+

+
/*
+
** Raise a type error with "standard" information about the faulty
+
** object 'o' (using 'varinfo').
+
*/
+
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+
  typeerror(L, o, op, varinfo(L, o));
+
}
+

+

+
/*
+
** Raise an error for calling a non-callable object. Try to find a name
+
** for the object based on how it was called ('funcnamefromcall'); if it
+
** cannot get a name there, try 'varinfo'.
+
*/
+
l_noret luaG_callerror (lua_State *L, const TValue *o) {
+
  CallInfo *ci = L->ci;
+
  const char *name = NULL;  /* to avoid warnings */
+
  const char *kind = funcnamefromcall(L, ci, &name);
+
  const char *extra = kind ? formatvarinfo(L, kind, name) : varinfo(L, o);
+
  typeerror(L, o, "call", extra);
}


@@ -722,7 +774,7 @@ l_noret luaG_opinterror (lua_State *L, const TValue *p1,
*/
l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
  lua_Integer temp;
-
  if (!tointegerns(p1, &temp))
+
  if (!luaV_tointegerns(p1, &temp, LUA_FLOORN2I))
    p2 = p1;
  luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2));
}
@@ -780,16 +832,30 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {

/*
** Check whether new instruction 'newpc' is in a different line from
-
** previous instruction 'oldpc'.
+
** previous instruction 'oldpc'. More often than not, 'newpc' is only
+
** one or a few instructions after 'oldpc' (it must be after, see
+
** caller), so try to avoid calling 'luaG_getfuncline'. If they are
+
** too far apart, there is a good chance of a ABSLINEINFO in the way,
+
** so it goes directly to 'luaG_getfuncline'.
*/
static int changedline (const Proto *p, int oldpc, int newpc) {
  if (p->lineinfo == NULL)  /* no debug information? */
    return 0;
-
  while (oldpc++ < newpc) {
-
    if (p->lineinfo[oldpc] != 0)
-
      return (luaG_getfuncline(p, oldpc - 1) != luaG_getfuncline(p, newpc));
+
  if (newpc - oldpc < MAXIWTHABS / 2) {  /* not too far apart? */
+
    int delta = 0;  /* line diference */
+
    int pc = oldpc;
+
    for (;;) {
+
      int lineinfo = p->lineinfo[++pc];
+
      if (lineinfo == ABSLINEINFO)
+
        break;  /* cannot compute delta; fall through */
+
      delta += lineinfo;
+
      if (pc == newpc)
+
        return (delta != 0);  /* delta computed successfully */
+
    }
  }
-
  return 0;  /* no line changes between positions */
+
  /* either instructions are too far apart or there is an absolute line
+
     info in the way; compute line difference explicitly */
+
  return (luaG_getfuncline(p, oldpc) != luaG_getfuncline(p, newpc));
}


@@ -797,20 +863,19 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
** Traces the execution of a Lua function. Called before the execution
** of each opcode, when debug is on. 'L->oldpc' stores the last
** instruction traced, to detect line changes. When entering a new
-
** function, 'npci' will be zero and will test as a new line without
-
** the need for 'oldpc'; so, 'oldpc' does not need to be initialized
-
** before. Some exceptional conditions may return to a function without
-
** updating 'oldpc'. In that case, 'oldpc' may be invalid; if so, it is
-
** reset to zero.  (A wrong but valid 'oldpc' at most causes an extra
-
** call to a line hook.)
+
** function, 'npci' will be zero and will test as a new line whatever
+
** the value of 'oldpc'.  Some exceptional conditions may return to
+
** a function without setting 'oldpc'. In that case, 'oldpc' may be
+
** invalid; if so, use zero as a valid value. (A wrong but valid 'oldpc'
+
** at most causes an extra call to a line hook.)
+
** This function is not "Protected" when called, so it should correct
+
** 'L->top' before calling anything that can run the GC.
*/
int luaG_traceexec (lua_State *L, const Instruction *pc) {
  CallInfo *ci = L->ci;
  lu_byte mask = L->hookmask;
  const Proto *p = ci_func(ci)->p;
  int counthook;
-
  /* 'L->oldpc' may be invalid; reset it in this case */
-
  int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0;
  if (!(mask & (LUA_MASKLINE | LUA_MASKCOUNT))) {  /* no hooks? */
    ci->u.l.trap = 0;  /* don't need to stop again */
    return 0;  /* turn off 'trap' */
@@ -826,15 +891,16 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) {
    ci->callstatus &= ~CIST_HOOKYIELD;  /* erase mark */
    return 1;  /* do not call hook again (VM yielded, so it did not move) */
  }
-
  if (!isIT(*(ci->u.l.savedpc - 1)))
-
    L->top = ci->top;  /* prepare top */
+
  if (!isIT(*(ci->u.l.savedpc - 1)))  /* top not being used? */
+
    L->top = ci->top;  /* correct top */
  if (counthook)
    luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0);  /* call count hook */
  if (mask & LUA_MASKLINE) {
+
    /* 'L->oldpc' may be invalid; use zero in this case */
+
    int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0;
    int npci = pcRel(pc, p);
-
    if (npci == 0 ||  /* call linehook when enter a new function, */
-
        pc <= invpcRel(oldpc, p) ||  /* when jump back (loop), or when */
-
        changedline(p, oldpc, npci)) {  /* enter new line */
+
    if (npci <= oldpc ||  /* call hook when jump back (loop), */
+
        changedline(p, oldpc, npci)) {  /* or when enter new line */
      int newline = luaG_getfuncline(p, npci);
      luaD_hook(L, LUA_HOOKLINE, newline, 0, 0);  /* call line hook */
    }
modified external/lua/src/ldebug.h
@@ -26,11 +26,22 @@
*/
#define ABSLINEINFO	(-0x80)

+

+
/*
+
** MAXimum number of successive Instructions WiTHout ABSolute line
+
** information. (A power of two allows fast divisions.)
+
*/
+
#if !defined(MAXIWTHABS)
+
#define MAXIWTHABS	128
+
#endif
+

+

LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc);
LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n,
                                                    StkId *pos);
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
                                                const char *opname);
+
LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o);
LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o,
                                               const char *what);
LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1,
modified external/lua/src/ldo.c
@@ -98,11 +98,12 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
      setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
      break;
    }
-
    case CLOSEPROTECT: {
+
    case LUA_OK: {  /* special case only for closing upvalues */
      setnilvalue(s2v(oldtop));  /* no error message */
      break;
    }
    default: {
+
      lua_assert(errorstatus(errcode));  /* real error */
      setobjs2s(L, oldtop, L->top - 1);  /* error message on current top */
      break;
    }
@@ -118,17 +119,13 @@ l_noret luaD_throw (lua_State *L, int errcode) {
  }
  else {  /* thread has no error handler */
    global_State *g = G(L);
-
    errcode = luaF_close(L, L->stack, errcode);  /* close all upvalues */
-
    L->status = cast_byte(errcode);  /* mark it as dead */
+
    errcode = luaE_resetthread(L, errcode);  /* close all upvalues */
    if (g->mainthread->errorJmp) {  /* main thread has a handler? */
      setobjs2s(L, g->mainthread->top++, L->top - 1);  /* copy error obj. */
      luaD_throw(g->mainthread, errcode);  /* re-throw in main thread */
    }
    else {  /* no handler at all; abort */
      if (g->panic) {  /* panic function? */
-
        luaD_seterrorobj(L, errcode, L->top);  /* assume EXTRA_STACK */
-
        if (L->ci->top < L->top)
-
          L->ci->top = L->top;  /* pushing msg. can break this invariant */
        lua_unlock(L);
        g->panic(L);  /* call panic function (last chance to jump out) */
      }
@@ -163,9 +160,8 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
  CallInfo *ci;
  UpVal *up;
-
  if (oldstack == newstack)
-
    return;  /* stack address did not change */
  L->top = (L->top - oldstack) + newstack;
+
  L->tbclist = (L->tbclist - oldstack) + newstack;
  for (up = L->openupval; up != NULL; up = up->u.open.next)
    up->v = s2v((uplevel(up) - oldstack) + newstack);
  for (ci = L->ci; ci != NULL; ci = ci->previous) {
@@ -181,19 +177,35 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
#define ERRORSTACKSIZE	(LUAI_MAXSTACK + 200)


+
/*
+
** Reallocate the stack to a new size, correcting all pointers into
+
** it. (There are pointers to a stack from its upvalues, from its list
+
** of call infos, plus a few individual pointers.) The reallocation is
+
** done in two steps (allocation + free) because the correction must be
+
** done while both addresses (the old stack and the new one) are valid.
+
** (In ISO C, any pointer use after the pointer has been deallocated is
+
** undefined behavior.)
+
** In case of allocation error, raise an error or return false according
+
** to 'raiseerror'.
+
*/
int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
-
  int lim = stacksize(L);
-
  StkId newstack = luaM_reallocvector(L, L->stack,
-
                      lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue);
+
  int oldsize = stacksize(L);
+
  int i;
+
  StkId newstack = luaM_reallocvector(L, NULL, 0,
+
                                      newsize + EXTRA_STACK, StackValue);
  lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
-
  if (unlikely(newstack == NULL)) {  /* reallocation failed? */
+
  if (l_unlikely(newstack == NULL)) {  /* reallocation failed? */
    if (raiseerror)
      luaM_error(L);
    else return 0;  /* do not raise an error */
  }
-
  for (; lim < newsize; lim++)
-
    setnilvalue(s2v(newstack + lim + EXTRA_STACK)); /* erase new segment */
+
  /* number of elements to be copied to the new stack */
+
  i = ((oldsize <= newsize) ? oldsize : newsize) + EXTRA_STACK;
+
  memcpy(newstack, L->stack, i * sizeof(StackValue));
+
  for (; i < newsize + EXTRA_STACK; i++)
+
    setnilvalue(s2v(newstack + i)); /* erase new segment */
  correctstack(L, L->stack, newstack);
+
  luaM_freearray(L, L->stack, oldsize + EXTRA_STACK);
  L->stack = newstack;
  L->stack_last = L->stack + newsize;
  return 1;
@@ -206,7 +218,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
*/
int luaD_growstack (lua_State *L, int n, int raiseerror) {
  int size = stacksize(L);
-
  if (unlikely(size > LUAI_MAXSTACK)) {
+
  if (l_unlikely(size > LUAI_MAXSTACK)) {
    /* if stack is larger than maximum, thread is already using the
       extra space reserved for errors, that is, thread is handling
       a stack error; cannot grow further than that. */
@@ -222,7 +234,7 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
      newsize = LUAI_MAXSTACK;
    if (newsize < needed)  /* but must respect what was asked for */
      newsize = needed;
-
    if (likely(newsize <= LUAI_MAXSTACK))
+
    if (l_likely(newsize <= LUAI_MAXSTACK))
      return luaD_reallocstack(L, newsize, raiseerror);
    else {  /* stack overflow */
      /* add extra size to be able to handle the error message */
@@ -297,8 +309,8 @@ void luaD_hook (lua_State *L, int event, int line,
  if (hook && L->allowhook) {  /* make sure there is a hook */
    int mask = CIST_HOOKED;
    CallInfo *ci = L->ci;
-
    ptrdiff_t top = savestack(L, L->top);
-
    ptrdiff_t ci_top = savestack(L, ci->top);
+
    ptrdiff_t top = savestack(L, L->top);  /* preserve original 'top' */
+
    ptrdiff_t ci_top = savestack(L, ci->top);  /* idem for 'ci->top' */
    lua_Debug ar;
    ar.event = event;
    ar.currentline = line;
@@ -308,8 +320,10 @@ void luaD_hook (lua_State *L, int event, int line,
      ci->u2.transferinfo.ftransfer = ftransfer;
      ci->u2.transferinfo.ntransfer = ntransfer;
    }
+
    if (isLua(ci) && L->top < ci->top)
+
      L->top = ci->top;  /* protect entire activation register */
    luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
-
    if (L->top + LUA_MINSTACK > ci->top)
+
    if (ci->top < L->top + LUA_MINSTACK)
      ci->top = L->top + LUA_MINSTACK;
    L->allowhook = 0;  /* cannot call hooks inside a hook */
    ci->callstatus |= mask;
@@ -331,38 +345,40 @@ void luaD_hook (lua_State *L, int event, int line,
** active.
*/
void luaD_hookcall (lua_State *L, CallInfo *ci) {
-
  int hook = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL : LUA_HOOKCALL;
-
  Proto *p;
-
  if (!(L->hookmask & LUA_MASKCALL))  /* some other hook? */
-
    return;  /* don't call hook */
-
  p = clLvalue(s2v(ci->func))->p;
-
  L->top = ci->top;  /* prepare top */
-
  ci->u.l.savedpc++;  /* hooks assume 'pc' is already incremented */
-
  luaD_hook(L, hook, -1, 1, p->numparams);
-
  ci->u.l.savedpc--;  /* correct 'pc' */
-
}
-

-

-
static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) {
-
  ptrdiff_t oldtop = savestack(L, L->top);  /* hook may change top */
-
  int delta = 0;
-
  if (isLuacode(ci)) {
+
  L->oldpc = 0;  /* set 'oldpc' for new function */
+
  if (L->hookmask & LUA_MASKCALL) {  /* is call hook on? */
+
    int event = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL
+
                                             : LUA_HOOKCALL;
    Proto *p = ci_func(ci)->p;
-
    if (p->is_vararg)
-
      delta = ci->u.l.nextraargs + p->numparams + 1;
-
    if (L->top < ci->top)
-
      L->top = ci->top;  /* correct top to run hook */
+
    ci->u.l.savedpc++;  /* hooks assume 'pc' is already incremented */
+
    luaD_hook(L, event, -1, 1, p->numparams);
+
    ci->u.l.savedpc--;  /* correct 'pc' */
  }
+
}
+

+

+
/*
+
** Executes a return hook for Lua and C functions and sets/corrects
+
** 'oldpc'. (Note that this correction is needed by the line hook, so it
+
** is done even when return hooks are off.)
+
*/
+
static void rethook (lua_State *L, CallInfo *ci, int nres) {
  if (L->hookmask & LUA_MASKRET) {  /* is return hook on? */
+
    StkId firstres = L->top - nres;  /* index of first result */
+
    int delta = 0;  /* correction for vararg functions */
    int ftransfer;
+
    if (isLua(ci)) {
+
      Proto *p = ci_func(ci)->p;
+
      if (p->is_vararg)
+
        delta = ci->u.l.nextraargs + p->numparams + 1;
+
    }
    ci->func += delta;  /* if vararg, back to virtual 'func' */
    ftransfer = cast(unsigned short, firstres - ci->func);
    luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres);  /* call it */
    ci->func -= delta;
  }
  if (isLua(ci = ci->previous))
-
    L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p);  /* update 'oldpc' */
-
  return restorestack(L, oldtop);
+
    L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p);  /* set 'oldpc' */
}


@@ -371,15 +387,18 @@ static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) {
** stack, below original 'func', so that 'luaD_precall' can call it. Raise
** an error if there is no '__call' metafield.
*/
-
void luaD_tryfuncTM (lua_State *L, StkId func) {
-
  const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL);
+
StkId luaD_tryfuncTM (lua_State *L, StkId func) {
+
  const TValue *tm;
  StkId p;
-
  if (unlikely(ttisnil(tm)))
-
    luaG_typeerror(L, s2v(func), "call");  /* nothing to call */
+
  checkstackGCp(L, 1, func);  /* space for metamethod */
+
  tm = luaT_gettmbyobj(L, s2v(func), TM_CALL);  /* (after previous GC) */
+
  if (l_unlikely(ttisnil(tm)))
+
    luaG_callerror(L, s2v(func));  /* nothing to call */
  for (p = L->top; p > func; p--)  /* open space for metamethod */
    setobjs2s(L, p, p-1);
  L->top++;  /* stack space pre-allocated by the caller */
  setobj2s(L, func, tm);  /* metamethod is the new function to be called */
+
  return func;
}


@@ -389,7 +408,7 @@ void luaD_tryfuncTM (lua_State *L, StkId func) {
** expressions, multiple results for tail calls/single parameters)
** separated.
*/
-
static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
+
l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
  StkId firstresult;
  int i;
  switch (wanted) {  /* handle typical cases separately */
@@ -399,27 +418,34 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
    case 1:  /* one value needed */
      if (nres == 0)   /* no results? */
        setnilvalue(s2v(res));  /* adjust with nil */
-
      else
+
      else  /* at least one result */
        setobjs2s(L, res, L->top - nres);  /* move it to proper place */
      L->top = res + 1;
      return;
    case LUA_MULTRET:
      wanted = nres;  /* we want all results */
      break;
-
    default:  /* multiple results (or to-be-closed variables) */
+
    default:  /* two/more results and/or to-be-closed variables */
      if (hastocloseCfunc(wanted)) {  /* to-be-closed variables? */
        ptrdiff_t savedres = savestack(L, res);
-
        luaF_close(L, res, LUA_OK);  /* may change the stack */
-
        res = restorestack(L, savedres);
-
        wanted = codeNresults(wanted);  /* correct value */
+
        L->ci->callstatus |= CIST_CLSRET;  /* in case of yields */
+
        L->ci->u2.nres = nres;
+
        luaF_close(L, res, CLOSEKTOP, 1);
+
        L->ci->callstatus &= ~CIST_CLSRET;
+
        if (L->hookmask)  /* if needed, call hook after '__close's */
+
          rethook(L, L->ci, nres);
+
        res = restorestack(L, savedres);  /* close and hook can move stack */
+
        wanted = decodeNresults(wanted);
        if (wanted == LUA_MULTRET)
-
          wanted = nres;
+
          wanted = nres;  /* we want all results */
      }
      break;
  }
+
  /* generic case */
  firstresult = L->top - nres;  /* index of first result */
-
  /* move all results to correct place */
-
  for (i = 0; i < nres && i < wanted; i++)
+
  if (nres > wanted)  /* extra results? */
+
    nres = wanted;  /* don't need them */
+
  for (i = 0; i < nres; i++)  /* move all results to correct place */
    setobjs2s(L, res + i, firstresult + i);
  for (; i < wanted; i++)  /* complete wanted number of results */
    setnilvalue(s2v(res + i));
@@ -428,15 +454,21 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {


/*
-
** Finishes a function call: calls hook if necessary, removes CallInfo,
-
** moves current number of results to proper place.
+
** Finishes a function call: calls hook if necessary, moves current
+
** number of results to proper place, and returns to previous call
+
** info. If function has to close variables, hook must be called after
+
** that.
*/
void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
-
  if (L->hookmask)
-
    L->top = rethook(L, ci, L->top - nres, nres);
-
  L->ci = ci->previous;  /* back to caller */
+
  int wanted = ci->nresults;
+
  if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted)))
+
    rethook(L, ci, nres);
  /* move results to proper place */
-
  moveresults(L, ci->func, nres, ci->nresults);
+
  moveresults(L, ci->func, nres, wanted);
+
  /* function cannot be in any of these cases when returning */
+
  lua_assert(!(ci->callstatus &
+
        (CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
+
  L->ci = ci->previous;  /* back to caller (after closing variables) */
}


@@ -444,27 +476,81 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
#define next_ci(L)  (L->ci->next ? L->ci->next : luaE_extendCI(L))


+
l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
+
                                                int mask, StkId top) {
+
  CallInfo *ci = L->ci = next_ci(L);  /* new frame */
+
  ci->func = func;
+
  ci->nresults = nret;
+
  ci->callstatus = mask;
+
  ci->top = top;
+
  return ci;
+
}
+

+

+
/*
+
** precall for C functions
+
*/
+
l_sinline int precallC (lua_State *L, StkId func, int nresults,
+
                                            lua_CFunction f) {
+
  int n;  /* number of returns */
+
  CallInfo *ci;
+
  checkstackGCp(L, LUA_MINSTACK, func);  /* ensure minimum stack size */
+
  L->ci = ci = prepCallInfo(L, func, nresults, CIST_C,
+
                               L->top + LUA_MINSTACK);
+
  lua_assert(ci->top <= L->stack_last);
+
  if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
+
    int narg = cast_int(L->top - func) - 1;
+
    luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
+
  }
+
  lua_unlock(L);
+
  n = (*f)(L);  /* do the actual call */
+
  lua_lock(L);
+
  api_checknelems(L, n);
+
  luaD_poscall(L, ci, n);
+
  return n;
+
}
+

+

/*
** Prepare a function for a tail call, building its call info on top
** of the current call info. 'narg1' is the number of arguments plus 1
-
** (so that it includes the function itself).
+
** (so that it includes the function itself). Return the number of
+
** results, if it was a C function, or -1 for a Lua function.
*/
-
void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
-
  Proto *p = clLvalue(s2v(func))->p;
-
  int fsize = p->maxstacksize;  /* frame size */
-
  int nfixparams = p->numparams;
-
  int i;
-
  for (i = 0; i < narg1; i++)  /* move down function and arguments */
-
    setobjs2s(L, ci->func + i, func + i);
-
  checkstackGC(L, fsize);
-
  func = ci->func;  /* moved-down function */
-
  for (; narg1 <= nfixparams; narg1++)
-
    setnilvalue(s2v(func + narg1));  /* complete missing arguments */
-
  ci->top = func + 1 + fsize;  /* top for new function */
-
  lua_assert(ci->top <= L->stack_last);
-
  ci->u.l.savedpc = p->code;  /* starting point */
-
  ci->callstatus |= CIST_TAIL;
-
  L->top = func + narg1;  /* set top */
+
int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
+
                                    int narg1, int delta) {
+
 retry:
+
  switch (ttypetag(s2v(func))) {
+
    case LUA_VCCL:  /* C closure */
+
      return precallC(L, func, LUA_MULTRET, clCvalue(s2v(func))->f);
+
    case LUA_VLCF:  /* light C function */
+
      return precallC(L, func, LUA_MULTRET, fvalue(s2v(func)));
+
    case LUA_VLCL: {  /* Lua function */
+
      Proto *p = clLvalue(s2v(func))->p;
+
      int fsize = p->maxstacksize;  /* frame size */
+
      int nfixparams = p->numparams;
+
      int i;
+
      checkstackGCp(L, fsize - delta, func);
+
      ci->func -= delta;  /* restore 'func' (if vararg) */
+
      for (i = 0; i < narg1; i++)  /* move down function and arguments */
+
        setobjs2s(L, ci->func + i, func + i);
+
      func = ci->func;  /* moved-down function */
+
      for (; narg1 <= nfixparams; narg1++)
+
        setnilvalue(s2v(func + narg1));  /* complete missing arguments */
+
      ci->top = func + 1 + fsize;  /* top for new function */
+
      lua_assert(ci->top <= L->stack_last);
+
      ci->u.l.savedpc = p->code;  /* starting point */
+
      ci->callstatus |= CIST_TAIL;
+
      L->top = func + narg1;  /* set top */
+
      return -1;
+
    }
+
    default: {  /* not a function */
+
      func = luaD_tryfuncTM(L, func);  /* try to get '__call' metamethod */
+
      /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */
+
      narg1++;
+
      goto retry;  /* try again */
+
    }
+
  }
}


@@ -477,35 +563,14 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
** original function position.
*/
CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
-
  lua_CFunction f;
 retry:
  switch (ttypetag(s2v(func))) {
    case LUA_VCCL:  /* C closure */
-
      f = clCvalue(s2v(func))->f;
-
      goto Cfunc;
+
      precallC(L, func, nresults, clCvalue(s2v(func))->f);
+
      return NULL;
    case LUA_VLCF:  /* light C function */
-
      f = fvalue(s2v(func));
-
     Cfunc: {
-
      int n;  /* number of returns */
-
      CallInfo *ci;
-
      checkstackGCp(L, LUA_MINSTACK, func);  /* ensure minimum stack size */
-
      L->ci = ci = next_ci(L);
-
      ci->nresults = nresults;
-
      ci->callstatus = CIST_C;
-
      ci->top = L->top + LUA_MINSTACK;
-
      ci->func = func;
-
      lua_assert(ci->top <= L->stack_last);
-
      if (L->hookmask & LUA_MASKCALL) {
-
        int narg = cast_int(L->top - func) - 1;
-
        luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
-
      }
-
      lua_unlock(L);
-
      n = (*f)(L);  /* do the actual call */
-
      lua_lock(L);
-
      api_checknelems(L, n);
-
      luaD_poscall(L, ci, n);
+
      precallC(L, func, nresults, fvalue(s2v(func)));
      return NULL;
-
    }
    case LUA_VLCL: {  /* Lua function */
      CallInfo *ci;
      Proto *p = clLvalue(s2v(func))->p;
@@ -513,20 +578,16 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
      int nfixparams = p->numparams;
      int fsize = p->maxstacksize;  /* frame size */
      checkstackGCp(L, fsize, func);
-
      L->ci = ci = next_ci(L);
-
      ci->nresults = nresults;
+
      L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize);
      ci->u.l.savedpc = p->code;  /* starting point */
-
      ci->top = func + 1 + fsize;
-
      ci->func = func;
-
      L->ci = ci;
      for (; narg < nfixparams; narg++)
        setnilvalue(s2v(L->top++));  /* complete missing arguments */
      lua_assert(ci->top <= L->stack_last);
      return ci;
    }
    default: {  /* not a function */
-
      checkstackGCp(L, 1, func);  /* space for metamethod */
-
      luaD_tryfuncTM(L, func);  /* try to get '__call' metamethod */
+
      func = luaD_tryfuncTM(L, func);  /* try to get '__call' metamethod */
+
      /* return luaD_precall(L, func, nresults); */
      goto retry;  /* try again with metamethod */
    }
  }
@@ -538,10 +599,10 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
** number of recursive invocations in the C stack) or nyci (the same
** plus increment number of non-yieldable calls).
*/
-
static void ccall (lua_State *L, StkId func, int nResults, int inc) {
+
l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) {
  CallInfo *ci;
  L->nCcalls += inc;
-
  if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
+
  if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
    luaE_checkcstack(L);
  if ((ci = luaD_precall(L, func, nResults)) != NULL) {  /* Lua function? */
    ci->callstatus = CIST_FRESH;  /* mark that it is a "fresh" execute */
@@ -568,27 +629,74 @@ void luaD_callnoyield (lua_State *L, StkId func, int nResults) {


/*
-
** Completes the execution of an interrupted C function, calling its
-
** continuation function.
+
** Finish the job of 'lua_pcallk' after it was interrupted by an yield.
+
** (The caller, 'finishCcall', does the final call to 'adjustresults'.)
+
** The main job is to complete the 'luaD_pcall' called by 'lua_pcallk'.
+
** If a '__close' method yields here, eventually control will be back
+
** to 'finishCcall' (when that '__close' method finally returns) and
+
** 'finishpcallk' will run again and close any still pending '__close'
+
** methods. Similarly, if a '__close' method errs, 'precover' calls
+
** 'unroll' which calls ''finishCcall' and we are back here again, to
+
** close any pending '__close' methods.
+
** Note that, up to the call to 'luaF_close', the corresponding
+
** 'CallInfo' is not modified, so that this repeated run works like the
+
** first one (except that it has at least one less '__close' to do). In
+
** particular, field CIST_RECST preserves the error status across these
+
** multiple runs, changing only if there is a new error.
*/
-
static void finishCcall (lua_State *L, int status) {
-
  CallInfo *ci = L->ci;
-
  int n;
-
  /* must have a continuation and must be able to call it */
-
  lua_assert(ci->u.c.k != NULL && yieldable(L));
-
  /* error status can only happen in a protected call */
-
  lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
-
  if (ci->callstatus & CIST_YPCALL) {  /* was inside a pcall? */
-
    ci->callstatus &= ~CIST_YPCALL;  /* continuation is also inside it */
-
    L->errfunc = ci->u.c.old_errfunc;  /* with the same error function */
-
  }
-
  /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
-
     handled */
-
  adjustresults(L, ci->nresults);
-
  lua_unlock(L);
-
  n = (*ci->u.c.k)(L, status, ci->u.c.ctx);  /* call continuation function */
-
  lua_lock(L);
-
  api_checknelems(L, n);
+
static int finishpcallk (lua_State *L,  CallInfo *ci) {
+
  int status = getcistrecst(ci);  /* get original status */
+
  if (l_likely(status == LUA_OK))  /* no error? */
+
    status = LUA_YIELD;  /* was interrupted by an yield */
+
  else {  /* error */
+
    StkId func = restorestack(L, ci->u2.funcidx);
+
    L->allowhook = getoah(ci->callstatus);  /* restore 'allowhook' */
+
    luaF_close(L, func, status, 1);  /* can yield or raise an error */
+
    func = restorestack(L, ci->u2.funcidx);  /* stack may be moved */
+
    luaD_seterrorobj(L, status, func);
+
    luaD_shrinkstack(L);   /* restore stack size in case of overflow */
+
    setcistrecst(ci, LUA_OK);  /* clear original status */
+
  }
+
  ci->callstatus &= ~CIST_YPCALL;
+
  L->errfunc = ci->u.c.old_errfunc;
+
  /* if it is here, there were errors or yields; unlike 'lua_pcallk',
+
     do not change status */
+
  return status;
+
}
+

+

+
/*
+
** Completes the execution of a C function interrupted by an yield.
+
** The interruption must have happened while the function was either
+
** closing its tbc variables in 'moveresults' or executing
+
** 'lua_callk'/'lua_pcallk'. In the first case, it just redoes
+
** 'luaD_poscall'. In the second case, the call to 'finishpcallk'
+
** finishes the interrupted execution of 'lua_pcallk'.  After that, it
+
** calls the continuation of the interrupted function and finally it
+
** completes the job of the 'luaD_call' that called the function.  In
+
** the call to 'adjustresults', we do not know the number of results
+
** of the function called by 'lua_callk'/'lua_pcallk', so we are
+
** conservative and use LUA_MULTRET (always adjust).
+
*/
+
static void finishCcall (lua_State *L, CallInfo *ci) {
+
  int n;  /* actual number of results from C function */
+
  if (ci->callstatus & CIST_CLSRET) {  /* was returning? */
+
    lua_assert(hastocloseCfunc(ci->nresults));
+
    n = ci->u2.nres;  /* just redo 'luaD_poscall' */
+
    /* don't need to reset CIST_CLSRET, as it will be set again anyway */
+
  }
+
  else {
+
    int status = LUA_YIELD;  /* default if there were no errors */
+
    /* must have a continuation and must be able to call it */
+
    lua_assert(ci->u.c.k != NULL && yieldable(L));
+
    if (ci->callstatus & CIST_YPCALL)   /* was inside a 'lua_pcallk'? */
+
      status = finishpcallk(L, ci);  /* finish it */
+
    adjustresults(L, LUA_MULTRET);  /* finish 'lua_callk' */
+
    lua_unlock(L);
+
    n = (*ci->u.c.k)(L, status, ci->u.c.ctx);  /* call continuation */
+
    lua_lock(L);
+
    api_checknelems(L, n);
+
  }
  luaD_poscall(L, ci, n);  /* finish 'luaD_call' */
}

@@ -596,18 +704,14 @@ static void finishCcall (lua_State *L, int status) {
/*
** Executes "full continuation" (everything in the stack) of a
** previously interrupted coroutine until the stack is empty (or another
-
** interruption long-jumps out of the loop). If the coroutine is
-
** recovering from an error, 'ud' points to the error status, which must
-
** be passed to the first continuation function (otherwise the default
-
** status is LUA_YIELD).
+
** interruption long-jumps out of the loop).
*/
static void unroll (lua_State *L, void *ud) {
  CallInfo *ci;
-
  if (ud != NULL)  /* error status? */
-
    finishCcall(L, *(int *)ud);  /* finish 'lua_pcallk' callee */
+
  UNUSED(ud);
  while ((ci = L->ci) != &L->base_ci) {  /* something in the stack */
    if (!isLua(ci))  /* C function? */
-
      finishCcall(L, LUA_YIELD);  /* complete its execution */
+
      finishCcall(L, ci);  /* complete its execution */
    else {  /* Lua function */
      luaV_finishOp(L);  /* finish interrupted instruction */
      luaV_execute(L, ci);  /* execute down to higher C 'boundary' */
@@ -631,28 +735,6 @@ static CallInfo *findpcall (lua_State *L) {


/*
-
** Recovers from an error in a coroutine. Finds a recover point (if
-
** there is one) and completes the execution of the interrupted
-
** 'luaD_pcall'. If there is no recover point, returns zero.
-
*/
-
static int recover (lua_State *L, int status) {
-
  StkId oldtop;
-
  CallInfo *ci = findpcall(L);
-
  if (ci == NULL) return 0;  /* no recovery point */
-
  /* "finish" luaD_pcall */
-
  oldtop = restorestack(L, ci->u2.funcidx);
-
  L->ci = ci;
-
  L->allowhook = getoah(ci->callstatus);  /* restore original 'allowhook' */
-
  status = luaF_close(L, oldtop, status);  /* may change the stack */
-
  oldtop = restorestack(L, ci->u2.funcidx);
-
  luaD_seterrorobj(L, status, oldtop);
-
  luaD_shrinkstack(L);   /* restore stack size in case of overflow */
-
  L->errfunc = ci->u.c.old_errfunc;
-
  return 1;  /* continue running the coroutine */
-
}
-

-

-
/*
** Signal an error in the call to 'lua_resume', not in the execution
** of the coroutine itself. (Such errors should not be handled by any
** coroutine error handler and should not kill the coroutine.)
@@ -678,13 +760,14 @@ static void resume (lua_State *L, void *ud) {
  StkId firstArg = L->top - n;  /* first argument */
  CallInfo *ci = L->ci;
  if (L->status == LUA_OK)  /* starting a coroutine? */
-
    ccall(L, firstArg - 1, LUA_MULTRET, 1);  /* just call its body */
+
    ccall(L, firstArg - 1, LUA_MULTRET, 0);  /* just call its body */
  else {  /* resuming from previous yield */
    lua_assert(L->status == LUA_YIELD);
    L->status = LUA_OK;  /* mark that it is running (again) */
-
    luaE_incCstack(L);  /* control the C stack */
-
    if (isLua(ci))  /* yielded inside a hook? */
+
    if (isLua(ci)) {  /* yielded inside a hook? */
+
      L->top = firstArg;  /* discard arguments */
      luaV_execute(L, ci);  /* just continue running Lua code */
+
    }
    else {  /* 'common' yield */
      if (ci->u.c.k != NULL) {  /* does it have a continuation function? */
        lua_unlock(L);
@@ -698,6 +781,26 @@ static void resume (lua_State *L, void *ud) {
  }
}

+

+
/*
+
** Unrolls a coroutine in protected mode while there are recoverable
+
** errors, that is, errors inside a protected call. (Any error
+
** interrupts 'unroll', and this loop protects it again so it can
+
** continue.) Stops with a normal end (status == LUA_OK), an yield
+
** (status == LUA_YIELD), or an unprotected error ('findpcall' doesn't
+
** find a recover point).
+
*/
+
static int precover (lua_State *L, int status) {
+
  CallInfo *ci;
+
  while (errorstatus(status) && (ci = findpcall(L)) != NULL) {
+
    L->ci = ci;  /* go down to recovery functions */
+
    setcistrecst(ci, status);  /* status to finish 'pcall' */
+
    status = luaD_rawrunprotected(L, unroll, NULL);
+
  }
+
  return status;
+
}
+

+

LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
                                      int *nresults) {
  int status;
@@ -711,15 +814,15 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
  else if (L->status != LUA_YIELD)  /* ended with errors? */
    return resume_error(L, "cannot resume dead coroutine", nargs);
  L->nCcalls = (from) ? getCcalls(from) : 0;
+
  if (getCcalls(L) >= LUAI_MAXCCALLS)
+
    return resume_error(L, "C stack overflow", nargs);
+
  L->nCcalls++;
  luai_userstateresume(L, nargs);
  api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
  status = luaD_rawrunprotected(L, resume, &nargs);
   /* continue running after recoverable errors */
-
  while (errorstatus(status) && recover(L, status)) {
-
    /* unroll continuation */
-
    status = luaD_rawrunprotected(L, unroll, &status);
-
  }
-
  if (likely(!errorstatus(status)))
+
  status = precover(L, status);
+
  if (l_likely(!errorstatus(status)))
    lua_assert(status == L->status);  /* normal end or yield */
  else {  /* unrecoverable error */
    L->status = cast_byte(status);  /* mark thread as 'dead' */
@@ -745,22 +848,22 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
  lua_lock(L);
  ci = L->ci;
  api_checknelems(L, nresults);
-
  if (unlikely(!yieldable(L))) {
+
  if (l_unlikely(!yieldable(L))) {
    if (L != G(L)->mainthread)
      luaG_runerror(L, "attempt to yield across a C-call boundary");
    else
      luaG_runerror(L, "attempt to yield from outside a coroutine");
  }
  L->status = LUA_YIELD;
+
  ci->u2.nyield = nresults;  /* save number of results */
  if (isLua(ci)) {  /* inside a hook? */
    lua_assert(!isLuacode(ci));
+
    api_check(L, nresults == 0, "hooks cannot yield values");
    api_check(L, k == NULL, "hooks cannot continue after yielding");
-
    ci->u2.nyield = 0;  /* no results */
  }
  else {
    if ((ci->u.c.k = k) != NULL)  /* is there a continuation? */
      ci->u.c.ctx = ctx;  /* save context */
-
    ci->u2.nyield = nresults;  /* save number of results */
    luaD_throw(L, LUA_YIELD);
  }
  lua_assert(ci->callstatus & CIST_HOOKED);  /* must be inside a hook */
@@ -770,6 +873,45 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,


/*
+
** Auxiliary structure to call 'luaF_close' in protected mode.
+
*/
+
struct CloseP {
+
  StkId level;
+
  int status;
+
};
+

+

+
/*
+
** Auxiliary function to call 'luaF_close' in protected mode.
+
*/
+
static void closepaux (lua_State *L, void *ud) {
+
  struct CloseP *pcl = cast(struct CloseP *, ud);
+
  luaF_close(L, pcl->level, pcl->status, 0);
+
}
+

+

+
/*
+
** Calls 'luaF_close' in protected mode. Return the original status
+
** or, in case of errors, the new status.
+
*/
+
int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status) {
+
  CallInfo *old_ci = L->ci;
+
  lu_byte old_allowhooks = L->allowhook;
+
  for (;;) {  /* keep closing upvalues until no more errors */
+
    struct CloseP pcl;
+
    pcl.level = restorestack(L, level); pcl.status = status;
+
    status = luaD_rawrunprotected(L, &closepaux, &pcl);
+
    if (l_likely(status == LUA_OK))  /* no more errors? */
+
      return pcl.status;
+
    else {  /* an error occurred; restore saved state and repeat */
+
      L->ci = old_ci;
+
      L->allowhook = old_allowhooks;
+
    }
+
  }
+
}
+

+

+
/*
** Call the C function 'func' in protected mode, restoring basic
** thread information ('allowhook', etc.) and in particular
** its stack level in case of errors.
@@ -782,13 +924,11 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
  ptrdiff_t old_errfunc = L->errfunc;
  L->errfunc = ef;
  status = luaD_rawrunprotected(L, func, u);
-
  if (unlikely(status != LUA_OK)) {  /* an error occurred? */
-
    StkId oldtop = restorestack(L, old_top);
+
  if (l_unlikely(status != LUA_OK)) {  /* an error occurred? */
    L->ci = old_ci;
    L->allowhook = old_allowhooks;
-
    status = luaF_close(L, oldtop, status);
-
    oldtop = restorestack(L, old_top);  /* previous call may change stack */
-
    luaD_seterrorobj(L, status, oldtop);
+
    status = luaD_closeprotected(L, old_top, status);
+
    luaD_seterrorobj(L, status, restorestack(L, old_top));
    luaD_shrinkstack(L);   /* restore stack size in case of overflow */
  }
  L->errfunc = old_errfunc;
modified external/lua/src/ldo.h
@@ -23,7 +23,7 @@
** at every check.
*/
#define luaD_checkstackaux(L,n,pre,pos)  \
-
	if (L->stack_last - L->top <= (n)) \
+
	if (l_unlikely(L->stack_last - L->top <= (n))) \
	  { pre; luaD_growstack(L, n, 1); pos; } \
        else { condmovestack(L,pre,pos); }

@@ -58,11 +58,12 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line,
                                        int fTransfer, int nTransfer);
LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci);
-
LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n);
+
LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,                                                    int narg1, int delta);
LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
-
LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func);
+
LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func);
+
LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
                                        ptrdiff_t oldtop, ptrdiff_t ef);
LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres);
modified external/lua/src/lfunc.c
@@ -100,115 +100,83 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
}


-
static void callclose (lua_State *L, void *ud) {
-
  UNUSED(ud);
-
  luaD_callnoyield(L, L->top - 3, 0);
-
}
-

-

/*
-
** Prepare closing method plus its arguments for object 'obj' with
-
** error message 'err'. (This function assumes EXTRA_STACK.)
+
** Call closing method for object 'obj' with error message 'err'. The
+
** boolean 'yy' controls whether the call is yieldable.
+
** (This function assumes EXTRA_STACK.)
*/
-
static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) {
+
static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) {
  StkId top = L->top;
  const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE);
-
  if (ttisnil(tm))  /* no metamethod? */
-
    return 0;  /* nothing to call */
  setobj2s(L, top, tm);  /* will call metamethod... */
  setobj2s(L, top + 1, obj);  /* with 'self' as the 1st argument */
  setobj2s(L, top + 2, err);  /* and error msg. as 2nd argument */
  L->top = top + 3;  /* add function and arguments */
-
  return 1;
+
  if (yy)
+
    luaD_call(L, top, 0);
+
  else
+
    luaD_callnoyield(L, top, 0);
}


/*
-
** Raise an error with message 'msg', inserting the name of the
-
** local variable at position 'level' in the stack.
+
** Check whether object at given level has a close metamethod and raise
+
** an error if not.
*/
-
static void varerror (lua_State *L, StkId level, const char *msg) {
-
  int idx = cast_int(level - L->ci->func);
-
  const char *vname = luaG_findlocal(L, L->ci, idx, NULL);
-
  if (vname == NULL) vname = "?";
-
  luaG_runerror(L, msg, vname);
+
static void checkclosemth (lua_State *L, StkId level) {
+
  const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE);
+
  if (ttisnil(tm)) {  /* no metamethod? */
+
    int idx = cast_int(level - L->ci->func);  /* variable index */
+
    const char *vname = luaG_findlocal(L, L->ci, idx, NULL);
+
    if (vname == NULL) vname = "?";
+
    luaG_runerror(L, "variable '%s' got a non-closable value", vname);
+
  }
}


/*
-
** Prepare and call a closing method. If status is OK, code is still
-
** inside the original protected call, and so any error will be handled
-
** there. Otherwise, a previous error already activated the original
-
** protected call, and so the call to the closing method must be
-
** protected here. (A status == CLOSEPROTECT behaves like a previous
-
** error, to also run the closing method in protected mode).
-
** If status is OK, the call to the closing method will be pushed
-
** at the top of the stack. Otherwise, values are pushed after
-
** the 'level' of the upvalue being closed, as everything after
-
** that won't be used again.
+
** Prepare and call a closing method.
+
** If status is CLOSEKTOP, the call to the closing method will be pushed
+
** at the top of the stack. Otherwise, values can be pushed right after
+
** the 'level' of the upvalue being closed, as everything after that
+
** won't be used again.
*/
-
static int callclosemth (lua_State *L, StkId level, int status) {
+
static void prepcallclosemth (lua_State *L, StkId level, int status, int yy) {
  TValue *uv = s2v(level);  /* value being closed */
-
  if (likely(status == LUA_OK)) {
-
    if (prepclosingmethod(L, uv, &G(L)->nilvalue))  /* something to call? */
-
      callclose(L, NULL);  /* call closing method */
-
    else if (!l_isfalse(uv))  /* non-closable non-false value? */
-
      varerror(L, level, "attempt to close non-closable variable '%s'");
-
  }
-
  else {  /* must close the object in protected mode */
-
    ptrdiff_t oldtop;
-
    level++;  /* space for error message */
-
    oldtop = savestack(L, level + 1);  /* top will be after that */
-
    luaD_seterrorobj(L, status, level);  /* set error message */
-
    if (prepclosingmethod(L, uv, s2v(level))) {  /* something to call? */
-
      int newstatus = luaD_pcall(L, callclose, NULL, oldtop, 0);
-
      if (newstatus != LUA_OK && status == CLOSEPROTECT)  /* first error? */
-
        status = newstatus;  /* this will be the new error */
-
      else {
-
        if (newstatus != LUA_OK)  /* suppressed error? */
-
          luaE_warnerror(L, "__close metamethod");
-
        /* leave original error (or nil) on top */
-
        L->top = restorestack(L, oldtop);
-
      }
-
    }
-
    /* else no metamethod; ignore this case and keep original error */
+
  TValue *errobj;
+
  if (status == CLOSEKTOP)
+
    errobj = &G(L)->nilvalue;  /* error object is nil */
+
  else {  /* 'luaD_seterrorobj' will set top to level + 2 */
+
    errobj = s2v(level + 1);  /* error object goes after 'uv' */
+
    luaD_seterrorobj(L, status, level + 1);  /* set error object */
  }
-
  return status;
+
  callclosemethod(L, uv, errobj, yy);
}


/*
-
** Try to create a to-be-closed upvalue
-
** (can raise a memory-allocation error)
+
** Maximum value for deltas in 'tbclist', dependent on the type
+
** of delta. (This macro assumes that an 'L' is in scope where it
+
** is used.)
*/
-
static void trynewtbcupval (lua_State *L, void *ud) {
-
  newupval(L, 1, cast(StkId, ud), &L->openupval);
-
}
+
#define MAXDELTA  \
+
	((256ul << ((sizeof(L->stack->tbclist.delta) - 1) * 8)) - 1)


/*
-
** Create a to-be-closed upvalue. If there is a memory error
-
** when creating the upvalue, the closing method must be called here,
-
** as there is no upvalue to call it later.
+
** Insert a variable in the list of to-be-closed variables.
*/
void luaF_newtbcupval (lua_State *L, StkId level) {
-
  TValue *obj = s2v(level);
-
  lua_assert(L->openupval == NULL || uplevel(L->openupval) < level);
-
  if (!l_isfalse(obj)) {  /* false doesn't need to be closed */
-
    int status;
-
    const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE);
-
    if (ttisnil(tm))  /* no metamethod? */
-
      varerror(L, level, "variable '%s' got a non-closable value");
-
    status = luaD_rawrunprotected(L, trynewtbcupval, level);
-
    if (unlikely(status != LUA_OK)) {  /* memory error creating upvalue? */
-
      lua_assert(status == LUA_ERRMEM);
-
      luaD_seterrorobj(L, LUA_ERRMEM, level + 1);  /* save error message */
-
      /* next call must succeed, as object is closable */
-
      prepclosingmethod(L, s2v(level), s2v(level + 1));
-
      callclose(L, NULL);  /* call closing method */
-
      luaD_throw(L, LUA_ERRMEM);  /* throw memory error */
-
    }
+
  lua_assert(level > L->tbclist);
+
  if (l_isfalse(s2v(level)))
+
    return;  /* false doesn't need to be closed */
+
  checkclosemth(L, level);  /* value must have a close method */
+
  while (cast_uint(level - L->tbclist) > MAXDELTA) {
+
    L->tbclist += MAXDELTA;  /* create a dummy node at maximum delta */
+
    L->tbclist->tbclist.delta = 0;
  }
+
  level->tbclist.delta = cast(unsigned short, level - L->tbclist);
+
  L->tbclist = level;
}


@@ -220,18 +188,16 @@ void luaF_unlinkupval (UpVal *uv) {
}


-
int luaF_close (lua_State *L, StkId level, int status) {
+
/*
+
** Close all upvalues up to the given stack level.
+
*/
+
void luaF_closeupval (lua_State *L, StkId level) {
  UpVal *uv;
-
  while ((uv = L->openupval) != NULL && uplevel(uv) >= level) {
+
  StkId upl;  /* stack index pointed by 'uv' */
+
  while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) {
    TValue *slot = &uv->u.value;  /* new position for value */
    lua_assert(uplevel(uv) < L->top);
-
    if (uv->tbc && status != NOCLOSINGMETH) {
-
      /* must run closing method, which may change the stack */
-
      ptrdiff_t levelrel = savestack(L, level);
-
      status = callclosemth(L, uplevel(uv), status);
-
      level = restorestack(L, levelrel);
-
    }
-
    luaF_unlinkupval(uv);
+
    luaF_unlinkupval(uv);  /* remove upvalue from 'openupval' list */
    setobj(L, slot, uv->v);  /* move value to upvalue slot */
    uv->v = slot;  /* now current value lives here */
    if (!iswhite(uv)) {  /* neither white nor dead? */
@@ -239,7 +205,35 @@ int luaF_close (lua_State *L, StkId level, int status) {
      luaC_barrier(L, uv, slot);
    }
  }
-
  return status;
+
}
+

+

+
/*
+
** Remove firt element from the tbclist plus its dummy nodes.
+
*/
+
static void poptbclist (lua_State *L) {
+
  StkId tbc = L->tbclist;
+
  lua_assert(tbc->tbclist.delta > 0);  /* first element cannot be dummy */
+
  tbc -= tbc->tbclist.delta;
+
  while (tbc > L->stack && tbc->tbclist.delta == 0)
+
    tbc -= MAXDELTA;  /* remove dummy nodes */
+
  L->tbclist = tbc;
+
}
+

+

+
/*
+
** Close all upvalues and to-be-closed variables up to the given stack
+
** level.
+
*/
+
void luaF_close (lua_State *L, StkId level, int status, int yy) {
+
  ptrdiff_t levelrel = savestack(L, level);
+
  luaF_closeupval(L, level);  /* first, close the upvalues */
+
  while (L->tbclist >= level) {  /* traverse tbc's down to that level */
+
    StkId tbc = L->tbclist;  /* get variable index */
+
    poptbclist(L);  /* remove it from list */
+
    prepcallclosemth(L, tbc, status, yy);  /* close variable */
+
    level = restorestack(L, levelrel);
+
  }
}


modified external/lua/src/lfunc.h
@@ -42,15 +42,9 @@
#define MAXMISS		10


-
/*
-
** Special "status" for 'luaF_close'
-
*/
-

-
/* close upvalues without running their closing methods */
-
#define NOCLOSINGMETH	(-1)

-
/* close upvalues running all closing methods in protected mode */
-
#define CLOSEPROTECT	(-2)
+
/* special status to close upvalues preserving the top of the stack */
+
#define CLOSEKTOP	(-1)


LUAI_FUNC Proto *luaF_newproto (lua_State *L);
@@ -59,7 +53,8 @@ LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals);
LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level);
-
LUAI_FUNC int luaF_close (lua_State *L, StkId level, int status);
+
LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level);
+
LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy);
LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
modified external/lua/src/lgc.c
@@ -906,18 +906,18 @@ static void GCTM (lua_State *L) {
  if (!notm(tm)) {  /* is there a finalizer? */
    int status;
    lu_byte oldah = L->allowhook;
-
    int running  = g->gcrunning;
+
    int oldgcstp  = g->gcstp;
+
    g->gcstp |= GCSTPGC;  /* avoid GC steps */
    L->allowhook = 0;  /* stop debug hooks during GC metamethod */
-
    g->gcrunning = 0;  /* avoid GC steps */
    setobj2s(L, L->top++, tm);  /* push finalizer... */
    setobj2s(L, L->top++, &v);  /* ... and its argument */
    L->ci->callstatus |= CIST_FIN;  /* will run a finalizer */
    status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
    L->ci->callstatus &= ~CIST_FIN;  /* not running a finalizer anymore */
    L->allowhook = oldah;  /* restore hooks */
-
    g->gcrunning = running;  /* restore state */
-
    if (unlikely(status != LUA_OK)) {  /* error while running __gc? */
-
      luaE_warnerror(L, "__gc metamethod");
+
    g->gcstp = oldgcstp;  /* restore state */
+
    if (l_unlikely(status != LUA_OK)) {  /* error while running __gc? */
+
      luaE_warnerror(L, "__gc");
      L->top--;  /* pops error object */
    }
  }
@@ -1011,7 +1011,8 @@ static void correctpointers (global_State *g, GCObject *o) {
void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
  global_State *g = G(L);
  if (tofinalize(o) ||                 /* obj. is already marked... */
-
      gfasttm(g, mt, TM_GC) == NULL)   /* or has no finalizer? */
+
      gfasttm(g, mt, TM_GC) == NULL ||    /* or has no finalizer... */
+
      (g->gcstp & GCSTPCLS))                   /* or closing state? */
    return;  /* nothing to be done */
  else {  /* move 'o' to 'finobj' list */
    GCObject **p;
@@ -1502,12 +1503,13 @@ static void deletelist (lua_State *L, GCObject *p, GCObject *limit) {
*/
void luaC_freeallobjects (lua_State *L) {
  global_State *g = G(L);
+
  g->gcstp = GCSTPCLS;  /* no extra finalizers after here */
  luaC_changemode(L, KGC_INC);
  separatetobefnz(g, 1);  /* separate all objects with finalizers */
  lua_assert(g->finobj == NULL);
  callallpendingfinalizers(L);
  deletelist(L, g->allgc, obj2gco(g->mainthread));
-
  deletelist(L, g->finobj, NULL);
+
  lua_assert(g->finobj == NULL);  /* no new finalizers */
  deletelist(L, g->fixedgc, NULL);  /* collect fixed objects */
  lua_assert(g->strt.nuse == 0);
}
@@ -1575,52 +1577,64 @@ static int sweepstep (lua_State *L, global_State *g,

static lu_mem singlestep (lua_State *L) {
  global_State *g = G(L);
+
  lu_mem work;
+
  lua_assert(!g->gcstopem);  /* collector is not reentrant */
+
  g->gcstopem = 1;  /* no emergency collections while collecting */
  switch (g->gcstate) {
    case GCSpause: {
      restartcollection(g);
      g->gcstate = GCSpropagate;
-
      return 1;
+
      work = 1;
+
      break;
    }
    case GCSpropagate: {
      if (g->gray == NULL) {  /* no more gray objects? */
        g->gcstate = GCSenteratomic;  /* finish propagate phase */
-
        return 0;
+
        work = 0;
      }
      else
-
        return propagatemark(g);  /* traverse one gray object */
+
        work = propagatemark(g);  /* traverse one gray object */
+
      break;
    }
    case GCSenteratomic: {
-
      lu_mem work = atomic(L);  /* work is what was traversed by 'atomic' */
+
      work = atomic(L);  /* work is what was traversed by 'atomic' */
      entersweep(L);
      g->GCestimate = gettotalbytes(g);  /* first estimate */;
-
      return work;
+
      break;
    }
    case GCSswpallgc: {  /* sweep "regular" objects */
-
      return sweepstep(L, g, GCSswpfinobj, &g->finobj);
+
      work = sweepstep(L, g, GCSswpfinobj, &g->finobj);
+
      break;
    }
    case GCSswpfinobj: {  /* sweep objects with finalizers */
-
      return sweepstep(L, g, GCSswptobefnz, &g->tobefnz);
+
      work = sweepstep(L, g, GCSswptobefnz, &g->tobefnz);
+
      break;
    }
    case GCSswptobefnz: {  /* sweep objects to be finalized */
-
      return sweepstep(L, g, GCSswpend, NULL);
+
      work = sweepstep(L, g, GCSswpend, NULL);
+
      break;
    }
    case GCSswpend: {  /* finish sweeps */
      checkSizes(L, g);
      g->gcstate = GCScallfin;
-
      return 0;
+
      work = 0;
+
      break;
    }
    case GCScallfin: {  /* call remaining finalizers */
      if (g->tobefnz && !g->gcemergency) {
-
        int n = runafewfinalizers(L, GCFINMAX);
-
        return n * GCFINALIZECOST;
+
        g->gcstopem = 0;  /* ok collections during finalizers */
+
        work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST;
      }
      else {  /* emergency mode or no more finalizers */
        g->gcstate = GCSpause;  /* finish collection */
-
        return 0;
+
        work = 0;
      }
+
      break;
    }
    default: lua_assert(0); return 0;
  }
+
  g->gcstopem = 0;
+
  return work;
}


@@ -1635,6 +1649,7 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
}


+

/*
** Performs a basic incremental step. The debt and step size are
** converted from bytes to "units of work"; then the function loops
@@ -1666,7 +1681,7 @@ static void incstep (lua_State *L, global_State *g) {
void luaC_step (lua_State *L) {
  global_State *g = G(L);
  lua_assert(!g->gcemergency);
-
  if (g->gcrunning) {  /* running? */
+
  if (gcrunning(g)) {  /* running? */
    if(isdecGCmodegen(g))
      genstep(L, g);
    else
modified external/lua/src/lgc.h
@@ -148,6 +148,16 @@
*/
#define isdecGCmodegen(g)	(g->gckind == KGC_GEN || g->lastatomic != 0)

+

+
/*
+
** Control when GC is running:
+
*/
+
#define GCSTPUSR	1  /* bit true when GC stopped by user */
+
#define GCSTPGC		2  /* bit true when GC stopped by itself */
+
#define GCSTPCLS	4  /* bit true when closing Lua state */
+
#define gcrunning(g)	((g)->gcstp == 0)
+

+

/*
** Does one step of collection when debt becomes positive. 'pre'/'pos'
** allows some adjustments to be done only when needed. macro
modified external/lua/src/liolib.c
@@ -52,12 +52,6 @@ static int l_checkmode (const char *mode) {
** =======================================================
*/

-
#if !defined(l_checkmodep)
-
/* By default, Lua accepts only "r" or "w" as mode */
-
#define l_checkmodep(m)	((m[0] == 'r' || m[0] == 'w') && m[1] == '\0')
-
#endif
-

-

#if !defined(l_popen)		/* { */

#if defined(LUA_USE_POSIX)	/* { */
@@ -70,6 +64,12 @@ static int l_checkmode (const char *mode) {
#define l_popen(L,c,m)		(_popen(c,m))
#define l_pclose(L,file)	(_pclose(file))

+
#if !defined(l_checkmodep)
+
/* Windows accepts "[rw][bt]?" as valid modes */
+
#define l_checkmodep(m)	((m[0] == 'r' || m[0] == 'w') && \
+
  (m[1] == '\0' || ((m[1] == 'b' || m[1] == 't') && m[2] == '\0')))
+
#endif
+

#else				/* }{ */

/* ISO C definitions */
@@ -83,6 +83,12 @@ static int l_checkmode (const char *mode) {

#endif				/* } */

+

+
#if !defined(l_checkmodep)
+
/* By default, Lua accepts only "r" or "w" as valid modes */
+
#define l_checkmodep(m)        ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0')
+
#endif
+

/* }====================================================== */


@@ -180,7 +186,7 @@ static int f_tostring (lua_State *L) {

static FILE *tofile (lua_State *L) {
  LStream *p = tolstream(L);
-
  if (isclosed(p))
+
  if (l_unlikely(isclosed(p)))
    luaL_error(L, "attempt to use a closed file");
  lua_assert(p->f);
  return p->f;
@@ -255,7 +261,7 @@ static LStream *newfile (lua_State *L) {
static void opencheck (lua_State *L, const char *fname, const char *mode) {
  LStream *p = newfile(L);
  p->f = fopen(fname, mode);
-
  if (p->f == NULL)
+
  if (l_unlikely(p->f == NULL))
    luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno));
}

@@ -303,7 +309,7 @@ static FILE *getiofile (lua_State *L, const char *findex) {
  LStream *p;
  lua_getfield(L, LUA_REGISTRYINDEX, findex);
  p = (LStream *)lua_touserdata(L, -1);
-
  if (isclosed(p))
+
  if (l_unlikely(isclosed(p)))
    luaL_error(L, "default %s file is closed", findex + IOPREF_LEN);
  return p->f;
}
@@ -430,7 +436,7 @@ typedef struct {
** Add current char to buffer (if not out of space) and read next one
*/
static int nextc (RN *rn) {
-
  if (rn->n >= L_MAXLENNUM) {  /* buffer overflow? */
+
  if (l_unlikely(rn->n >= L_MAXLENNUM)) {  /* buffer overflow? */
    rn->buff[0] = '\0';  /* invalidate result */
    return 0;  /* fail */
  }
@@ -493,8 +499,8 @@ static int read_number (lua_State *L, FILE *f) {
  ungetc(rn.c, rn.f);  /* unread look-ahead char */
  l_unlockfile(rn.f);
  rn.buff[rn.n] = '\0';  /* finish string */
-
  if (lua_stringtonumber(L, rn.buff))  /* is this a valid number? */
-
    return 1;  /* ok */
+
  if (l_likely(lua_stringtonumber(L, rn.buff)))
+
    return 1;  /* ok, it is a valid number */
  else {  /* invalid format */
   lua_pushnil(L);  /* "result" to be removed */
   return 0;  /* read fails */
@@ -670,7 +676,8 @@ static int g_write (lua_State *L, FILE *f, int arg) {
      status = status && (fwrite(s, sizeof(char), l, f) == l);
    }
  }
-
  if (status) return 1;  /* file handle already on stack top */
+
  if (l_likely(status))
+
    return 1;  /* file handle already on stack top */
  else return luaL_fileresult(L, status, NULL);
}

@@ -697,7 +704,7 @@ static int f_seek (lua_State *L) {
  luaL_argcheck(L, (lua_Integer)offset == p3, 3,
                  "not an integer in proper range");
  op = l_fseek(f, offset, mode[op]);
-
  if (op)
+
  if (l_unlikely(op))
    return luaL_fileresult(L, 0, NULL);  /* error */
  else {
    lua_pushinteger(L, (lua_Integer)l_ftell(f));
modified external/lua/src/llex.c
@@ -122,26 +122,29 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {


/*
-
** creates a new string and anchors it in scanner's table so that
-
** it will not be collected until the end of the compilation
-
** (by that time it should be anchored somewhere)
+
** Creates a new string and anchors it in scanner's table so that it
+
** will not be collected until the end of the compilation; by that time
+
** it should be anchored somewhere. It also internalizes long strings,
+
** ensuring there is only one copy of each unique string.  The table
+
** here is used as a set: the string enters as the key, while its value
+
** is irrelevant. We use the string itself as the value only because it
+
** is a TValue readly available. Later, the code generation can change
+
** this value.
*/
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
  lua_State *L = ls->L;
-
  TValue *o;  /* entry for 'str' */
  TString *ts = luaS_newlstr(L, str, l);  /* create new string */
-
  setsvalue2s(L, L->top++, ts);  /* temporarily anchor it in stack */
-
  o = luaH_set(L, ls->h, s2v(L->top - 1));
-
  if (isempty(o)) {  /* not in use yet? */
-
    /* boolean value does not need GC barrier;
-
       table is not a metatable, so it does not need to invalidate cache */
-
    setbtvalue(o);  /* t[string] = true */
+
  const TValue *o = luaH_getstr(ls->h, ts);
+
  if (!ttisnil(o))  /* string already present? */
+
    ts = keystrval(nodefromval(o));  /* get saved copy */
+
  else {  /* not in use yet */
+
    TValue *stv = s2v(L->top++);  /* reserve stack space for string */
+
    setsvalue(L, stv, ts);  /* temporarily anchor the string */
+
    luaH_finishset(L, ls->h, stv, o, stv);  /* t[string] = string */
+
    /* table is not a metatable, so it does not need to invalidate cache */
    luaC_checkGC(L);
+
    L->top--;  /* remove string from stack */
  }
-
  else {  /* string already present */
-
    ts = keystrval(nodefromval(o));  /* re-use value previously stored */
-
  }
-
  L->top--;  /* remove string from stack */
  return ts;
}

modified external/lua/src/llimits.h
@@ -150,35 +150,33 @@ typedef LUAI_UACINT l_uacInt;


/*
-
** macros to improve jump prediction (used mainly for error handling)
+
** non-return type
*/
-
#if !defined(likely)
+
#if !defined(l_noret)

#if defined(__GNUC__)
-
#define likely(x)	(__builtin_expect(((x) != 0), 1))
-
#define unlikely(x)	(__builtin_expect(((x) != 0), 0))
+
#define l_noret		void __attribute__((noreturn))
+
#elif defined(_MSC_VER) && _MSC_VER >= 1200
+
#define l_noret		void __declspec(noreturn)
#else
-
#define likely(x)	(x)
-
#define unlikely(x)	(x)
+
#define l_noret		void
#endif

#endif


/*
-
** non-return type
+
** Inline functions
*/
-
#if !defined(l_noret)
-

-
#if defined(__GNUC__)
-
#define l_noret		void __attribute__((noreturn))
-
#elif defined(_MSC_VER) && _MSC_VER >= 1200
-
#define l_noret		void __declspec(noreturn)
+
#if !defined(LUA_USE_C89)
+
#define l_inline	inline
+
#elif defined(__GNUC__)
+
#define l_inline	__inline__
#else
-
#define l_noret		void
+
#define l_inline	/* empty */
#endif

-
#endif
+
#define l_sinline	static l_inline


/*
@@ -363,7 +361,7 @@ typedef l_uint32 Instruction;
#define condchangemem(L,pre,pos)	((void)0)
#else
#define condchangemem(L,pre,pos)  \
-
	{ if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } }
+
	{ if (gcrunning(G(L))) { pre; luaC_fullgc(L, 0); pos; } }
#endif

#endif
modified external/lua/src/lmathlib.c
@@ -73,7 +73,7 @@ static int math_atan (lua_State *L) {
static int math_toint (lua_State *L) {
  int valid;
  lua_Integer n = lua_tointegerx(L, 1, &valid);
-
  if (valid)
+
  if (l_likely(valid))
    lua_pushinteger(L, n);
  else {
    luaL_checkany(L, 1);
@@ -175,7 +175,8 @@ static int math_log (lua_State *L) {
    lua_Number base = luaL_checknumber(L, 2);
#if !defined(LUA_USE_C89)
    if (base == l_mathop(2.0))
-
      res = l_mathop(log2)(x); else
+
      res = l_mathop(log2)(x);
+
    else
#endif
    if (base == l_mathop(10.0))
      res = l_mathop(log10)(x);
@@ -474,7 +475,7 @@ static lua_Number I2d (Rand64 x) {

/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */
#define scaleFIG  \
-
	((lua_Number)1.0 / (UONE << 30) / 8.0 / (UONE << (FIGS - 33)))
+
    (l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33)))

/*
** use FIGS - 32 bits from lower half, throwing out the other
@@ -485,7 +486,7 @@ static lua_Number I2d (Rand64 x) {
/*
** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32)
*/
-
#define shiftHI		((lua_Number)(UONE << (FIGS - 33)) * 2.0)
+
#define shiftHI		((lua_Number)(UONE << (FIGS - 33)) * l_mathop(2.0))


static lua_Number I2d (Rand64 x) {
modified external/lua/src/lmem.c
@@ -24,12 +24,12 @@

#if defined(EMERGENCYGCTESTS)
/*
-
** First allocation will fail whenever not building initial state
-
** and not shrinking a block. (This fail will trigger 'tryagain' and
-
** a full GC cycle at every allocation.)
+
** First allocation will fail whenever not building initial state.
+
** (This fail will trigger 'tryagain' and a full GC cycle at every
+
** allocation.)
*/
static void *firsttry (global_State *g, void *block, size_t os, size_t ns) {
-
  if (ttisnil(&g->nilvalue) && ns > os)
+
  if (completestate(g) && ns > 0)  /* frees never fail */
    return NULL;  /* fail */
  else  /* normal allocation */
    return (*g->frealloc)(g->ud, block, os, ns);
@@ -83,7 +83,7 @@ void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize,
  if (nelems + 1 <= size)  /* does one extra element still fit? */
    return block;  /* nothing to be done */
  if (size >= limit / 2) {  /* cannot double it? */
-
    if (unlikely(size >= limit))  /* cannot grow even a little? */
+
    if (l_unlikely(size >= limit))  /* cannot grow even a little? */
      luaG_runerror(L, "too many %s (limit is %d)", what, limit);
    size = limit;  /* still have at least one free place */
  }
@@ -138,15 +138,17 @@ void luaM_free_ (lua_State *L, void *block, size_t osize) {


/*
-
** In case of allocation fail, this function will call the GC to try
-
** to free some memory and then try the allocation again.
-
** (It should not be called when shrinking a block, because then the
-
** interpreter may be in the middle of a collection step.)
+
** In case of allocation fail, this function will do an emergency
+
** collection to free some memory and then try the allocation again.
+
** The GC should not be called while state is not fully built, as the
+
** collector is not yet fully initialized. Also, it should not be called
+
** when 'gcstopem' is true, because then the interpreter is in the
+
** middle of a collection step.
*/
static void *tryagain (lua_State *L, void *block,
                       size_t osize, size_t nsize) {
  global_State *g = G(L);
-
  if (ttisnil(&g->nilvalue)) {  /* is state fully build? */
+
  if (completestate(g) && !g->gcstopem) {
    luaC_fullgc(L, 1);  /* try to free some memory... */
    return (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
  }
@@ -156,17 +158,14 @@ static void *tryagain (lua_State *L, void *block,

/*
** Generic allocation routine.
-
** If allocation fails while shrinking a block, do not try again; the
-
** GC shrinks some blocks and it is not reentrant.
*/
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
  void *newblock;
  global_State *g = G(L);
  lua_assert((osize == 0) == (block == NULL));
  newblock = firsttry(g, block, osize, nsize);
-
  if (unlikely(newblock == NULL && nsize > 0)) {
-
    if (nsize > osize)  /* not shrinking a block? */
-
      newblock = tryagain(L, block, osize, nsize);
+
  if (l_unlikely(newblock == NULL && nsize > 0)) {
+
    newblock = tryagain(L, block, osize, nsize);
    if (newblock == NULL)  /* still no memory? */
      return NULL;  /* do not update 'GCdebt' */
  }
@@ -179,7 +178,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize,
                                                    size_t nsize) {
  void *newblock = luaM_realloc_(L, block, osize, nsize);
-
  if (unlikely(newblock == NULL && nsize > 0))  /* allocation failed? */
+
  if (l_unlikely(newblock == NULL && nsize > 0))  /* allocation failed? */
    luaM_error(L);
  return newblock;
}
@@ -191,7 +190,7 @@ void *luaM_malloc_ (lua_State *L, size_t size, int tag) {
  else {
    global_State *g = G(L);
    void *newblock = firsttry(g, NULL, tag, size);
-
    if (unlikely(newblock == NULL)) {
+
    if (l_unlikely(newblock == NULL)) {
      newblock = tryagain(L, NULL, tag, size);
      if (newblock == NULL)
        luaM_error(L);
modified external/lua/src/loadlib.c
@@ -132,14 +132,16 @@ static void lsys_unloadlib (void *lib) {

static void *lsys_load (lua_State *L, const char *path, int seeglb) {
  void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
-
  if (lib == NULL) lua_pushstring(L, dlerror());
+
  if (l_unlikely(lib == NULL))
+
    lua_pushstring(L, dlerror());
  return lib;
}


static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
  lua_CFunction f = cast_func(dlsym(lib, sym));
-
  if (f == NULL) lua_pushstring(L, dlerror());
+
  if (l_unlikely(f == NULL))
+
    lua_pushstring(L, dlerror());
  return f;
}

@@ -410,7 +412,7 @@ static int ll_loadlib (lua_State *L) {
  const char *path = luaL_checkstring(L, 1);
  const char *init = luaL_checkstring(L, 2);
  int stat = lookforfunc(L, path, init);
-
  if (stat == 0)  /* no errors? */
+
  if (l_likely(stat == 0))  /* no errors? */
    return 1;  /* return the loaded function */
  else {  /* error; error message is on stack top */
    luaL_pushfail(L);
@@ -523,14 +525,14 @@ static const char *findfile (lua_State *L, const char *name,
  const char *path;
  lua_getfield(L, lua_upvalueindex(1), pname);
  path = lua_tostring(L, -1);
-
  if (path == NULL)
+
  if (l_unlikely(path == NULL))
    luaL_error(L, "'package.%s' must be a string", pname);
  return searchpath(L, name, path, ".", dirsep);
}


static int checkload (lua_State *L, int stat, const char *filename) {
-
  if (stat) {  /* module loaded successfully? */
+
  if (l_likely(stat)) {  /* module loaded successfully? */
    lua_pushstring(L, filename);  /* will be 2nd argument to module */
    return 2;  /* return open function and file name */
  }
@@ -623,13 +625,14 @@ static void findloader (lua_State *L, const char *name) {
  int i;
  luaL_Buffer msg;  /* to build error message */
  /* push 'package.searchers' to index 3 in the stack */
-
  if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE)
+
  if (l_unlikely(lua_getfield(L, lua_upvalueindex(1), "searchers")
+
                 != LUA_TTABLE))
    luaL_error(L, "'package.searchers' must be a table");
  luaL_buffinit(L, &msg);
  /*  iterate over available searchers to find a loader */
  for (i = 1; ; i++) {
    luaL_addstring(&msg, "\n\t");  /* error-message prefix */
-
    if (lua_rawgeti(L, 3, i) == LUA_TNIL) {  /* no more searchers? */
+
    if (l_unlikely(lua_rawgeti(L, 3, i) == LUA_TNIL)) {  /* no more searchers? */
      lua_pop(L, 1);  /* remove nil */
      luaL_buffsub(&msg, 2);  /* remove prefix */
      luaL_pushresult(&msg);  /* create error message */
modified external/lua/src/lobject.c
@@ -164,7 +164,7 @@ static int isneg (const char **s) {
*/
static lua_Number lua_strx2number (const char *s, char **endptr) {
  int dot = lua_getlocaledecpoint();
-
  lua_Number r = 0.0;  /* result (accumulator) */
+
  lua_Number r = l_mathop(0.0);  /* result (accumulator) */
  int sigdig = 0;  /* number of significant digits */
  int nosigdig = 0;  /* number of non-significant digits */
  int e = 0;  /* exponent correction */
@@ -174,7 +174,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
  while (lisspace(cast_uchar(*s))) s++;  /* skip initial spaces */
  neg = isneg(&s);  /* check sign */
  if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')))  /* check '0x' */
-
    return 0.0;  /* invalid format (no '0x') */
+
    return l_mathop(0.0);  /* invalid format (no '0x') */
  for (s += 2; ; s++) {  /* skip '0x' and read numeral */
    if (*s == dot) {
      if (hasdot) break;  /* second dot? stop loop */
@@ -184,14 +184,14 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
      if (sigdig == 0 && *s == '0')  /* non-significant digit (zero)? */
        nosigdig++;
      else if (++sigdig <= MAXSIGDIG)  /* can read it without overflow? */
-
          r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
+
          r = (r * l_mathop(16.0)) + luaO_hexavalue(*s);
      else e++; /* too many digits; ignore, but still count for exponent */
      if (hasdot) e--;  /* decimal digit? correct exponent */
    }
    else break;  /* neither a dot nor a digit */
  }
  if (nosigdig + sigdig == 0)  /* no digits? */
-
    return 0.0;  /* invalid format */
+
    return l_mathop(0.0);  /* invalid format */
  *endptr = cast_charp(s);  /* valid up to here */
  e *= 4;  /* each digit multiplies/divides value by 2^4 */
  if (*s == 'p' || *s == 'P') {  /* exponent part? */
@@ -200,7 +200,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
    s++;  /* skip 'p' */
    neg1 = isneg(&s);  /* sign */
    if (!lisdigit(cast_uchar(*s)))
-
      return 0.0;  /* invalid; must have at least one digit */
+
      return l_mathop(0.0);  /* invalid; must have at least one digit */
    while (lisdigit(cast_uchar(*s)))  /* read exponent */
      exp1 = exp1 * 10 + *(s++) - '0';
    if (neg1) exp1 = -exp1;
modified external/lua/src/lobject.h
@@ -68,7 +68,7 @@ typedef struct TValue {


#define val_(o)		((o)->value_)
-
#define valraw(o)	(&val_(o))
+
#define valraw(o)	(val_(o))


/* raw type tag of a TValue */
@@ -112,7 +112,7 @@ typedef struct TValue {
#define settt_(o,t)	((o)->tt_=(t))


-
/* main macro to copy values (from 'obj1' to 'obj2') */
+
/* main macro to copy values (from 'obj2' to 'obj1') */
#define setobj(L,obj1,obj2) \
	{ TValue *io1=(obj1); const TValue *io2=(obj2); \
          io1->value_ = io2->value_; settt_(io1, io2->tt_); \
@@ -136,10 +136,19 @@ typedef struct TValue {


/*
-
** Entries in the Lua stack
+
** Entries in a Lua stack. Field 'tbclist' forms a list of all
+
** to-be-closed variables active in this stack. Dummy entries are
+
** used when the distance between two tbc variables does not fit
+
** in an unsigned short. They are represented by delta==0, and
+
** their real delta is always the maximum value that fits in
+
** that field.
*/
typedef union StackValue {
  TValue val;
+
  struct {
+
    TValuefields;
+
    unsigned short delta;
+
  } tbclist;
} StackValue;


@@ -570,10 +579,11 @@ typedef struct Proto {
#define LUA_VCCL	makevariant(LUA_TFUNCTION, 2)  /* C closure */

#define ttisfunction(o)		checktype(o, LUA_TFUNCTION)
-
#define ttisclosure(o)		((rawtt(o) & 0x1F) == LUA_VLCL)
#define ttisLclosure(o)		checktag((o), ctb(LUA_VLCL))
#define ttislcf(o)		checktag((o), LUA_VLCF)
#define ttisCclosure(o)		checktag((o), ctb(LUA_VCCL))
+
#define ttisclosure(o)         (ttisLclosure(o) || ttisCclosure(o))
+


#define isLfunction(o)	ttisLclosure(o)

modified external/lua/src/lopcodes.h
@@ -190,7 +190,8 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */


/*
-
** grep "ORDER OP" if you change these enums
+
** Grep "ORDER OP" if you change these enums. Opcodes marked with a (*)
+
** has extra descriptions in the notes after the enumeration.
*/

typedef enum {
@@ -203,7 +204,7 @@ OP_LOADF,/* A sBx R[A] := (lua_Number)sBx */
OP_LOADK,/*	A Bx	R[A] := K[Bx]					*/
OP_LOADKX,/*	A	R[A] := K[extra arg]				*/
OP_LOADFALSE,/*	A	R[A] := false					*/
-
OP_LFALSESKIP,/*A	R[A] := false; pc++				*/
+
OP_LFALSESKIP,/*A	R[A] := false; pc++	(*)			*/
OP_LOADTRUE,/*	A	R[A] := true					*/
OP_LOADNIL,/*	A B	R[A], R[A+1], ..., R[A+B] := nil		*/
OP_GETUPVAL,/*	A B	R[A] := UpValue[B]				*/
@@ -225,13 +226,13 @@ OP_SELF,/* A B C R[A+1] := R[B]; R[A] := R[B][RK(C):string] */

OP_ADDI,/*	A B sC	R[A] := R[B] + sC				*/

-
OP_ADDK,/*	A B C	R[A] := R[B] + K[C]				*/
-
OP_SUBK,/*	A B C	R[A] := R[B] - K[C]				*/
-
OP_MULK,/*	A B C	R[A] := R[B] * K[C]				*/
-
OP_MODK,/*	A B C	R[A] := R[B] % K[C]				*/
-
OP_POWK,/*	A B C	R[A] := R[B] ^ K[C]				*/
-
OP_DIVK,/*	A B C	R[A] := R[B] / K[C]				*/
-
OP_IDIVK,/*	A B C	R[A] := R[B] // K[C]				*/
+
OP_ADDK,/*	A B C	R[A] := R[B] + K[C]:number			*/
+
OP_SUBK,/*	A B C	R[A] := R[B] - K[C]:number			*/
+
OP_MULK,/*	A B C	R[A] := R[B] * K[C]:number			*/
+
OP_MODK,/*	A B C	R[A] := R[B] % K[C]:number			*/
+
OP_POWK,/*	A B C	R[A] := R[B] ^ K[C]:number			*/
+
OP_DIVK,/*	A B C	R[A] := R[B] / K[C]:number			*/
+
OP_IDIVK,/*	A B C	R[A] := R[B] // K[C]:number			*/

OP_BANDK,/*	A B C	R[A] := R[B] & K[C]:integer			*/
OP_BORK,/*	A B C	R[A] := R[B] | K[C]:integer			*/
@@ -254,7 +255,7 @@ OP_BXOR,/* A B C R[A] := R[B] ~ R[C] */
OP_SHL,/*	A B C	R[A] := R[B] << R[C]				*/
OP_SHR,/*	A B C	R[A] := R[B] >> R[C]				*/

-
OP_MMBIN,/*	A B C	call C metamethod over R[A] and R[B]		*/
+
OP_MMBIN,/*	A B C	call C metamethod over R[A] and R[B]	(*)	*/
OP_MMBINI,/*	A sB C k	call C metamethod over R[A] and sB	*/
OP_MMBINK,/*	A B C k		call C metamethod over R[A] and K[B]	*/

@@ -280,7 +281,7 @@ OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */
OP_GEI,/*	A sB k	if ((R[A] >= sB) ~= k) then pc++		*/

OP_TEST,/*	A k	if (not R[A] == k) then pc++			*/
-
OP_TESTSET,/*	A B k	if (not R[B] == k) then pc++ else R[A] := R[B]	*/
+
OP_TESTSET,/*	A B k	if (not R[B] == k) then pc++ else R[A] := R[B] (*) */

OP_CALL,/*	A B C	R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */
OP_TAILCALL,/*	A B C k	return R[A](R[A+1], ... ,R[A+B-1])		*/
@@ -315,6 +316,18 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */

/*===========================================================================
  Notes:
+

+
  (*) Opcode OP_LFALSESKIP is used to convert a condition to a boolean
+
  value, in a code equivalent to (not cond ? false : true).  (It
+
  produces false and skips the next instruction producing true.)
+

+
  (*) Opcodes OP_MMBIN and variants follow each arithmetic and
+
  bitwise opcode. If the operation succeeds, it skips this next
+
  opcode. Otherwise, this opcode calls the corresponding metamethod.
+

+
  (*) Opcode OP_TESTSET is used in short-circuit expressions that need
+
  both to jump and to produce a value, such as (a = b or c).
+

  (*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then
  'top' is set to last_result+1, so next open instruction (OP_CALL,
  OP_RETURN*, OP_SETLIST) may use 'top'.
modified external/lua/src/loslib.c
@@ -170,7 +170,7 @@ static int os_tmpname (lua_State *L) {
  char buff[LUA_TMPNAMBUFSIZE];
  int err;
  lua_tmpnam(buff, err);
-
  if (err)
+
  if (l_unlikely(err))
    return luaL_error(L, "unable to generate a unique filename");
  lua_pushstring(L, buff);
  return 1;
@@ -208,7 +208,7 @@ static int os_clock (lua_State *L) {
*/
static void setfield (lua_State *L, const char *key, int value, int delta) {
  #if (defined(LUA_NUMTIME) && LUA_MAXINTEGER <= INT_MAX)
-
    if (value > LUA_MAXINTEGER - delta)
+
    if (l_unlikely(value > LUA_MAXINTEGER - delta))
      luaL_error(L, "field '%s' is out-of-bound", key);
  #endif
  lua_pushinteger(L, (lua_Integer)value + delta);
@@ -253,9 +253,9 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
  int t = lua_getfield(L, -1, key);  /* get field and its type */
  lua_Integer res = lua_tointegerx(L, -1, &isnum);
  if (!isnum) {  /* field is not an integer? */
-
    if (t != LUA_TNIL)  /* some other value? */
+
    if (l_unlikely(t != LUA_TNIL))  /* some other value? */
      return luaL_error(L, "field '%s' is not an integer", key);
-
    else if (d < 0)  /* absent field; no default? */
+
    else if (l_unlikely(d < 0))  /* absent field; no default? */
      return luaL_error(L, "field '%s' missing in date table", key);
    res = d;
  }
modified external/lua/src/lparser.c
@@ -128,7 +128,7 @@ static void checknext (LexState *ls, int c) {
** in line 'where' (if that is not the current line).
*/
static void check_match (LexState *ls, int what, int who, int where) {
-
  if (unlikely(!testnext(ls, what))) {
+
  if (l_unlikely(!testnext(ls, what))) {
    if (where == ls->linenumber)  /* all in the same line? */
      error_expected(ls, what);  /* do not need a complex message */
    else {
@@ -222,26 +222,26 @@ static Vardesc *getlocalvardesc (FuncState *fs, int vidx) {


/*
-
** Convert 'nvar', a compiler index level, to it corresponding
-
** stack index level. For that, search for the highest variable
-
** below that level that is in the stack and uses its stack
-
** index ('sidx').
+
** Convert 'nvar', a compiler index level, to its corresponding
+
** register. For that, search for the highest variable below that level
+
** that is in a register and uses its register index ('ridx') plus one.
*/
-
static int stacklevel (FuncState *fs, int nvar) {
+
static int reglevel (FuncState *fs, int nvar) {
  while (nvar-- > 0) {
-
    Vardesc *vd = getlocalvardesc(fs, nvar);  /* get variable */
-
    if (vd->vd.kind != RDKCTC)  /* is in the stack? */
-
      return vd->vd.sidx + 1;
+
    Vardesc *vd = getlocalvardesc(fs, nvar);  /* get previous variable */
+
    if (vd->vd.kind != RDKCTC)  /* is in a register? */
+
      return vd->vd.ridx + 1;
  }
-
  return 0;  /* no variables in the stack */
+
  return 0;  /* no variables in registers */
}


/*
-
** Return the number of variables in the stack for function 'fs'
+
** Return the number of variables in the register stack for the given
+
** function.
*/
int luaY_nvarstack (FuncState *fs) {
-
  return stacklevel(fs, fs->nactvar);
+
  return reglevel(fs, fs->nactvar);
}


@@ -267,7 +267,7 @@ static void init_var (FuncState *fs, expdesc *e, int vidx) {
  e->f = e->t = NO_JUMP;
  e->k = VLOCAL;
  e->u.var.vidx = vidx;
-
  e->u.var.sidx = getlocalvardesc(fs, vidx)->vd.sidx;
+
  e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx;
}


@@ -310,12 +310,12 @@ static void check_readonly (LexState *ls, expdesc *e) {
*/
static void adjustlocalvars (LexState *ls, int nvars) {
  FuncState *fs = ls->fs;
-
  int stklevel = luaY_nvarstack(fs);
+
  int reglevel = luaY_nvarstack(fs);
  int i;
  for (i = 0; i < nvars; i++) {
    int vidx = fs->nactvar++;
    Vardesc *var = getlocalvardesc(fs, vidx);
-
    var->vd.sidx = stklevel++;
+
    var->vd.ridx = reglevel++;
    var->vd.pidx = registerlocalvar(ls, fs, var->vd.name);
  }
}
@@ -366,7 +366,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
  FuncState *prev = fs->prev;
  if (v->k == VLOCAL) {
    up->instack = 1;
-
    up->idx = v->u.var.sidx;
+
    up->idx = v->u.var.ridx;
    up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind;
    lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name));
  }
@@ -417,6 +417,17 @@ static void markupval (FuncState *fs, int level) {


/*
+
** Mark that current block has a to-be-closed variable.
+
*/
+
static void marktobeclosed (FuncState *fs) {
+
  BlockCnt *bl = fs->bl;
+
  bl->upval = 1;
+
  bl->insidetbc = 1;
+
  fs->needclose = 1;
+
}
+

+

+
/*
** Find a variable with the given name 'n'. If it is an upvalue, add
** this upvalue into all intermediate functions. If it is a global, set
** 'var' as 'void' as a flag.
@@ -517,7 +528,7 @@ static void solvegoto (LexState *ls, int g, Labeldesc *label) {
  Labellist *gl = &ls->dyd->gt;  /* list of goto's */
  Labeldesc *gt = &gl->arr[g];  /* goto to be resolved */
  lua_assert(eqstr(gt->name, label->name));
-
  if (unlikely(gt->nactvar < label->nactvar))  /* enter some scope? */
+
  if (l_unlikely(gt->nactvar < label->nactvar))  /* enter some scope? */
    jumpscopeerror(ls, gt);
  luaK_patchlist(ls->fs, gt->pc, label->pc);
  for (i = g; i < gl->n - 1; i++)  /* remove goto from pending list */
@@ -620,7 +631,7 @@ static void movegotosout (FuncState *fs, BlockCnt *bl) {
  for (i = bl->firstgoto; i < gl->n; i++) {  /* for each pending goto */
    Labeldesc *gt = &gl->arr[i];
    /* leaving a variable scope? */
-
    if (stacklevel(fs, gt->nactvar) > stacklevel(fs, bl->nactvar))
+
    if (reglevel(fs, gt->nactvar) > reglevel(fs, bl->nactvar))
      gt->close |= bl->upval;  /* jump may need a close */
    gt->nactvar = bl->nactvar;  /* update goto level */
  }
@@ -661,7 +672,7 @@ static void leaveblock (FuncState *fs) {
  BlockCnt *bl = fs->bl;
  LexState *ls = fs->ls;
  int hasclose = 0;
-
  int stklevel = stacklevel(fs, bl->nactvar);  /* level outside the block */
+
  int stklevel = reglevel(fs, bl->nactvar);  /* level outside the block */
  if (bl->isloop)  /* fix pending breaks? */
    hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0);
  if (!hasclose && bl->previous && bl->upval)
@@ -1330,13 +1341,13 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
        }
      }
      else {  /* table is a register */
-
        if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.sidx) {
+
        if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.ridx) {
          conflict = 1;  /* table is the local being assigned now */
          lh->v.u.ind.t = extra;  /* assignment will use safe copy */
        }
        /* is index the local being assigned? */
        if (lh->v.k == VINDEXED && v->k == VLOCAL &&
-
            lh->v.u.ind.idx == v->u.var.sidx) {
+
            lh->v.u.ind.idx == v->u.var.ridx) {
          conflict = 1;
          lh->v.u.ind.idx = extra;  /* previous assignment will use safe copy */
        }
@@ -1346,7 +1357,7 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
  if (conflict) {
    /* copy upvalue/local value to a temporary (in position 'extra') */
    if (v->k == VLOCAL)
-
      luaK_codeABC(fs, OP_MOVE, extra, v->u.var.sidx, 0);
+
      luaK_codeABC(fs, OP_MOVE, extra, v->u.var.ridx, 0);
    else
      luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0);
    luaK_reserveregs(fs, 1);
@@ -1411,7 +1422,7 @@ static void gotostat (LexState *ls) {
    newgotoentry(ls, name, line, luaK_jump(fs));
  else {  /* found a label */
    /* backward jump; will be resolved here */
-
    int lblevel = stacklevel(fs, lb->nactvar);  /* label level */
+
    int lblevel = reglevel(fs, lb->nactvar);  /* label level */
    if (luaY_nvarstack(fs) > lblevel)  /* leaving the scope of a variable? */
      luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0);
    /* create jump and link it to the label */
@@ -1435,7 +1446,7 @@ static void breakstat (LexState *ls) {
*/
static void checkrepeated (LexState *ls, TString *name) {
  Labeldesc *lb = findlabel(ls, name);
-
  if (unlikely(lb != NULL)) {  /* already defined? */
+
  if (l_unlikely(lb != NULL)) {  /* already defined? */
    const char *msg = "label '%s' already defined on line %d";
    msg = luaO_pushfstring(ls->L, msg, getstr(name), lb->line);
    luaK_semerror(ls, msg);  /* error */
@@ -1488,7 +1499,7 @@ static void repeatstat (LexState *ls, int line) {
  if (bl2.upval) {  /* upvalues? */
    int exit = luaK_jump(fs);  /* normal exit must jump over fix */
    luaK_patchtohere(fs, condexit);  /* repetition must close upvalues */
-
    luaK_codeABC(fs, OP_CLOSE, stacklevel(fs, bl2.nactvar), 0, 0);
+
    luaK_codeABC(fs, OP_CLOSE, reglevel(fs, bl2.nactvar), 0, 0);
    condexit = luaK_jump(fs);  /* repeat after closing upvalues */
    luaK_patchtohere(fs, exit);  /* normal exit comes to here */
  }
@@ -1520,7 +1531,7 @@ static void fixforjump (FuncState *fs, int pc, int dest, int back) {
  int offset = dest - (pc + 1);
  if (back)
    offset = -offset;
-
  if (unlikely(offset > MAXARG_Bx))
+
  if (l_unlikely(offset > MAXARG_Bx))
    luaX_syntaxerror(fs->ls, "control structure too long");
  SETARG_Bx(*jmp, offset);
}
@@ -1599,7 +1610,7 @@ static void forlist (LexState *ls, TString *indexname) {
  line = ls->linenumber;
  adjust_assign(ls, 4, explist(ls, &e), &e);
  adjustlocalvars(ls, 4);  /* control variables */
-
  markupval(fs, fs->nactvar);  /* last control var. must be closed */
+
  marktobeclosed(fs);  /* last control var. must be closed */
  luaK_checkstack(fs, 3);  /* extra space to call generator */
  forbody(ls, base, line, nvars - 4, 1);
}
@@ -1703,12 +1714,10 @@ static int getlocalattribute (LexState *ls) {
}


-
static void checktoclose (LexState *ls, int level) {
+
static void checktoclose (FuncState *fs, int level) {
  if (level != -1) {  /* is there a to-be-closed variable? */
-
    FuncState *fs = ls->fs;
-
    markupval(fs, level + 1);
-
    fs->bl->insidetbc = 1;  /* in the scope of a to-be-closed variable */
-
    luaK_codeABC(fs, OP_TBC, stacklevel(fs, level), 0, 0);
+
    marktobeclosed(fs);
+
    luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0);
  }
}

@@ -1751,7 +1760,7 @@ static void localstat (LexState *ls) {
    adjust_assign(ls, nvars, nexps, &e);
    adjustlocalvars(ls, nvars);
  }
-
  checktoclose(ls, toclose);
+
  checktoclose(fs, toclose);
}


@@ -1776,6 +1785,7 @@ static void funcstat (LexState *ls, int line) {
  luaX_next(ls);  /* skip FUNCTION */
  ismethod = funcname(ls, &v);
  body(ls, &b, ismethod, line);
+
  check_readonly(ls, &v);
  luaK_storevar(ls->fs, &v, &b);
  luaK_fixline(ls->fs, line);  /* definition "happens" in the first line */
}
modified external/lua/src/lparser.h
@@ -35,7 +35,7 @@ typedef enum {
             (string is fixed by the lexer) */
  VNONRELOC,  /* expression has its value in a fixed register;
                 info = result register */
-
  VLOCAL,  /* local variable; var.sidx = stack index (local register);
+
  VLOCAL,  /* local variable; var.ridx = register index;
              var.vidx = relative index in 'actvar.arr'  */
  VUPVAL,  /* upvalue variable; info = index of upvalue in 'upvalues' */
  VCONST,  /* compile-time <const> variable;
@@ -77,7 +77,7 @@ typedef struct expdesc {
      lu_byte t;  /* table (register or upvalue) */
    } ind;
    struct {  /* for local variables */
-
      lu_byte sidx;  /* index in the stack */
+
      lu_byte ridx;  /* register holding the variable */
      unsigned short vidx;  /* compiler index (in 'actvar.arr')  */
    } var;
  } u;
@@ -97,7 +97,7 @@ typedef union Vardesc {
  struct {
    TValuefields;  /* constant value (if it is a compile-time constant) */
    lu_byte kind;
-
    lu_byte sidx;  /* index of the variable in the stack */
+
    lu_byte ridx;  /* register holding the variable */
    short pidx;  /* index of the variable in the Proto's 'locvars' array */
    TString *name;  /* variable name */
  } vd;
modified external/lua/src/lstate.c
@@ -166,13 +166,13 @@ void luaE_checkcstack (lua_State *L) {
  if (getCcalls(L) == LUAI_MAXCCALLS)
    luaG_runerror(L, "C stack overflow");
  else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
-
    luaD_throw(L, LUA_ERRERR);  /* error while handing stack error */
+
    luaD_throw(L, LUA_ERRERR);  /* error while handling stack error */
}


LUAI_FUNC void luaE_incCstack (lua_State *L) {
  L->nCcalls++;
-
  if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
+
  if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
    luaE_checkcstack(L);
}

@@ -181,6 +181,7 @@ static void stack_init (lua_State *L1, lua_State *L) {
  int i; CallInfo *ci;
  /* initialize stack array */
  L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
+
  L1->tbclist = L1->stack;
  for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++)
    setnilvalue(s2v(L1->stack + i));  /* erase new stack */
  L1->top = L1->stack;
@@ -213,24 +214,19 @@ static void freestack (lua_State *L) {
** Create registry table and its predefined values
*/
static void init_registry (lua_State *L, global_State *g) {
-
  TValue temp;
  /* create registry */
  Table *registry = luaH_new(L);
  sethvalue(L, &g->l_registry, registry);
  luaH_resize(L, registry, LUA_RIDX_LAST, 0);
  /* registry[LUA_RIDX_MAINTHREAD] = L */
-
  setthvalue(L, &temp, L);  /* temp = L */
-
  luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
-
  /* registry[LUA_RIDX_GLOBALS] = table of globals */
-
  sethvalue(L, &temp, luaH_new(L));  /* temp = new table (global table) */
-
  luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
+
  setthvalue(L, &registry->array[LUA_RIDX_MAINTHREAD - 1], L);
+
  /* registry[LUA_RIDX_GLOBALS] = new table (table of globals) */
+
  sethvalue(L, &registry->array[LUA_RIDX_GLOBALS - 1], luaH_new(L));
}


/*
** open parts of the state that may cause memory-allocation errors.
-
** ('g->nilvalue' being a nil value flags that the state was completely
-
** build.)
*/
static void f_luaopen (lua_State *L, void *ud) {
  global_State *g = G(L);
@@ -240,8 +236,8 @@ static void f_luaopen (lua_State *L, void *ud) {
  luaS_init(L);
  luaT_init(L);
  luaX_init(L);
-
  g->gcrunning = 1;  /* allow gc */
-
  setnilvalue(&g->nilvalue);
+
  g->gcstp = 0;  /* allow gc */
+
  setnilvalue(&g->nilvalue);  /* now state is complete */
  luai_userstateopen(L);
}

@@ -256,6 +252,7 @@ static void preinit_thread (lua_State *L, global_State *g) {
  L->ci = NULL;
  L->nci = 0;
  L->twups = L;  /* thread has no upvalues */
+
  L->nCcalls = 0;
  L->errorJmp = NULL;
  L->hook = NULL;
  L->hookmask = 0;
@@ -271,10 +268,14 @@ static void preinit_thread (lua_State *L, global_State *g) {

static void close_state (lua_State *L) {
  global_State *g = G(L);
-
  luaF_close(L, L->stack, CLOSEPROTECT);  /* close all upvalues */
-
  luaC_freeallobjects(L);  /* collect all objects */
-
  if (ttisnil(&g->nilvalue))  /* closing a fully built state? */
+
  if (!completestate(g))  /* closing a partially built state? */
+
    luaC_freeallobjects(L);  /* just collect its objects */
+
  else {  /* closing a fully built state */
+
    L->ci = &L->base_ci;  /* unwind CallInfo list */
+
    luaD_closeprotected(L, 1, LUA_OK);  /* close all upvalues */
+
    luaC_freeallobjects(L);  /* collect all objects */
    luai_userstateclose(L);
+
  }
  luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
  freestack(L);
  lua_assert(gettotalbytes(g) == sizeof(LG));
@@ -299,7 +300,6 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
  setthvalue2s(L, L->top, L1);
  api_incr_top(L);
  preinit_thread(L1, g);
-
  L1->nCcalls = 0;
  L1->hookmask = L->hookmask;
  L1->basehookcount = L->basehookcount;
  L1->hook = L->hook;
@@ -316,7 +316,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {

void luaE_freethread (lua_State *L, lua_State *L1) {
  LX *l = fromstate(L1);
-
  luaF_close(L1, L1->stack, NOCLOSINGMETH);  /* close all upvalues */
+
  luaF_closeupval(L1, L1->stack);  /* close all upvalues */
  lua_assert(L1->openupval == NULL);
  luai_userstatefree(L, L1);
  freestack(L1);
@@ -324,23 +324,29 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
}


-
int lua_resetthread (lua_State *L) {
-
  CallInfo *ci;
-
  int status;
-
  lua_lock(L);
-
  L->ci = ci = &L->base_ci;  /* unwind CallInfo list */
+
int luaE_resetthread (lua_State *L, int status) {
+
  CallInfo *ci = L->ci = &L->base_ci;  /* unwind CallInfo list */
  setnilvalue(s2v(L->stack));  /* 'function' entry for basic 'ci' */
  ci->func = L->stack;
  ci->callstatus = CIST_C;
-
  status = luaF_close(L, L->stack, CLOSEPROTECT);
-
  if (status != CLOSEPROTECT)  /* real errors? */
-
    luaD_seterrorobj(L, status, L->stack + 1);
-
  else {
+
  if (status == LUA_YIELD)
    status = LUA_OK;
+
  L->status = LUA_OK;  /* so it can run __close metamethods */
+
  status = luaD_closeprotected(L, 1, status);
+
  if (status != LUA_OK)  /* errors? */
+
    luaD_seterrorobj(L, status, L->stack + 1);
+
  else
    L->top = L->stack + 1;
-
  }
  ci->top = L->top + LUA_MINSTACK;
-
  L->status = status;
+
  luaD_reallocstack(L, cast_int(ci->top - L->stack), 0);
+
  return status;
+
}
+

+

+
LUA_API int lua_resetthread (lua_State *L) {
+
  int status;
+
  lua_lock(L);
+
  status = luaE_resetthread(L, L->status);
  lua_unlock(L);
  return status;
}
@@ -360,7 +366,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
  preinit_thread(L, g);
  g->allgc = obj2gco(L);  /* by now, only object is the main thread */
  L->next = NULL;
-
  L->nCcalls = 0;
  incnny(L);  /* main thread is always non yieldable */
  g->frealloc = f;
  g->ud = ud;
@@ -368,13 +373,14 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
  g->ud_warn = NULL;
  g->mainthread = L;
  g->seed = luai_makeseed(L);
-
  g->gcrunning = 0;  /* no GC while building state */
+
  g->gcstp = GCSTPGC;  /* no GC while building state */
  g->strt.size = g->strt.nuse = 0;
  g->strt.hash = NULL;
  setnilvalue(&g->l_registry);
  g->panic = NULL;
  g->gcstate = GCSpause;
  g->gckind = KGC_INC;
+
  g->gcstopem = 0;
  g->gcemergency = 0;
  g->finobj = g->tobefnz = g->fixedgc = NULL;
  g->firstold1 = g->survival = g->old1 = g->reallyold = NULL;
modified external/lua/src/lstate.h
@@ -156,6 +156,18 @@ typedef struct stringtable {

/*
** Information about a call.
+
** About union 'u':
+
** - field 'l' is used only for Lua functions;
+
** - field 'c' is used only for C functions.
+
** About union 'u2':
+
** - field 'funcidx' is used only by C functions while doing a
+
** protected call;
+
** - field 'nyield' is used only while a function is "doing" an
+
** yield (from the yield until the next resume);
+
** - field 'nres' is used only while closing tbc variables when
+
** returning from a function;
+
** - field 'transferinfo' is used only during call/returnhooks,
+
** before the function starts or after it ends.
*/
typedef struct CallInfo {
  StkId func;  /* function index in the stack */
@@ -176,6 +188,7 @@ typedef struct CallInfo {
  union {
    int funcidx;  /* called-function index */
    int nyield;  /* number of values yielded */
+
    int nres;  /* number of values returned */
    struct {  /* info about transferred values (for call/return hooks) */
      unsigned short ftransfer;  /* offset of first value transferred */
      unsigned short ntransfer;  /* number of values transferred */
@@ -191,17 +204,34 @@ typedef struct CallInfo {
*/
#define CIST_OAH	(1<<0)	/* original value of 'allowhook' */
#define CIST_C		(1<<1)	/* call is running a C function */
-
#define CIST_FRESH	(1<<2)  /* call is on a fresh "luaV_execute" frame */
+
#define CIST_FRESH	(1<<2)	/* call is on a fresh "luaV_execute" frame */
#define CIST_HOOKED	(1<<3)	/* call is running a debug hook */
-
#define CIST_YPCALL	(1<<4)	/* call is a yieldable protected call */
+
#define CIST_YPCALL	(1<<4)	/* doing a yieldable protected call */
#define CIST_TAIL	(1<<5)	/* call was tail called */
#define CIST_HOOKYIELD	(1<<6)	/* last hook called yielded */
-
#define CIST_FIN	(1<<7)  /* call is running a finalizer */
+
#define CIST_FIN	(1<<7)	/* function "called" a finalizer */
#define CIST_TRAN	(1<<8)	/* 'ci' has transfer information */
+
#define CIST_CLSRET	(1<<9)  /* function is closing tbc variables */
+
/* Bits 10-12 are used for CIST_RECST (see below) */
+
#define CIST_RECST	10
#if defined(LUA_COMPAT_LT_LE)
-
#define CIST_LEQ	(1<<9)  /* using __lt for __le */
+
#define CIST_LEQ	(1<<13)  /* using __lt for __le */
#endif

+

+
/*
+
** Field CIST_RECST stores the "recover status", used to keep the error
+
** status while closing to-be-closed variables in coroutines, so that
+
** Lua can correctly resume after an yield from a __close method called
+
** because of an error.  (Three bits are enough for error status.)
+
*/
+
#define getcistrecst(ci)     (((ci)->callstatus >> CIST_RECST) & 7)
+
#define setcistrecst(ci,st)  \
+
  check_exp(((st) & 7) == (st),   /* status must fit in three bits */  \
+
            ((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST))  \
+
                                                  | ((st) << CIST_RECST)))
+

+

/* active function is a Lua function */
#define isLua(ci)	(!((ci)->callstatus & CIST_C))

@@ -230,9 +260,10 @@ typedef struct global_State {
  lu_byte currentwhite;
  lu_byte gcstate;  /* state of garbage collector */
  lu_byte gckind;  /* kind of GC running */
+
  lu_byte gcstopem;  /* stops emergency collections */
  lu_byte genminormul;  /* control for minor generational collections */
  lu_byte genmajormul;  /* control for major generational collections */
-
  lu_byte gcrunning;  /* true if GC is running */
+
  lu_byte gcstp;  /* control whether GC is running */
  lu_byte gcemergency;  /* true if this is an emergency collection */
  lu_byte gcpause;  /* size of pause between successive GCs */
  lu_byte gcstepmul;  /* GC "speed" */
@@ -281,6 +312,7 @@ struct lua_State {
  StkId stack_last;  /* end of stack (last element + 1) */
  StkId stack;  /* stack base */
  UpVal *openupval;  /* list of open upvalues in this stack */
+
  StkId tbclist;  /* list of to-be-closed variables */
  GCObject *gclist;
  struct lua_State *twups;  /* list of threads with open upvalues */
  struct lua_longjmp *errorJmp;  /* current error recover point */
@@ -297,6 +329,12 @@ struct lua_State {

#define G(L)	(L->l_G)

+
/*
+
** 'g->nilvalue' being a nil value flags that the state was completely
+
** build.
+
*/
+
#define completestate(g)	ttisnil(&g->nilvalue)
+


/*
** Union of all collectable objects (only for conversions)
@@ -359,6 +397,7 @@ LUAI_FUNC void luaE_checkcstack (lua_State *L);
LUAI_FUNC void luaE_incCstack (lua_State *L);
LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont);
LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where);
+
LUAI_FUNC int luaE_resetthread (lua_State *L, int status);


#endif
modified external/lua/src/lstring.c
@@ -89,7 +89,7 @@ void luaS_resize (lua_State *L, int nsize) {
  if (nsize < osize)  /* shrinking table? */
    tablerehash(tb->hash, osize, nsize);  /* depopulate shrinking part */
  newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*);
-
  if (unlikely(newvect == NULL)) {  /* reallocation failed? */
+
  if (l_unlikely(newvect == NULL)) {  /* reallocation failed? */
    if (nsize < osize)  /* was it shrinking table? */
      tablerehash(tb->hash, nsize, osize);  /* restore to original size */
    /* leave table as it was */
@@ -172,7 +172,7 @@ void luaS_remove (lua_State *L, TString *ts) {


static void growstrtab (lua_State *L, stringtable *tb) {
-
  if (unlikely(tb->nuse == MAX_INT)) {  /* too many strings? */
+
  if (l_unlikely(tb->nuse == MAX_INT)) {  /* too many strings? */
    luaC_fullgc(L, 1);  /* try to free some... */
    if (tb->nuse == MAX_INT)  /* still too many? */
      luaM_error(L);  /* cannot even create a message... */
@@ -223,7 +223,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
    return internshrstr(L, str, l);
  else {
    TString *ts;
-
    if (unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char)))
+
    if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char)))
      luaM_toobig(L);
    ts = luaS_createlngstrobj(L, l);
    memcpy(getstr(ts), str, l * sizeof(char));
@@ -259,7 +259,7 @@ Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) {
  Udata *u;
  int i;
  GCObject *o;
-
  if (unlikely(s > MAX_SIZE - udatamemoffset(nuvalue)))
+
  if (l_unlikely(s > MAX_SIZE - udatamemoffset(nuvalue)))
    luaM_toobig(L);
  o = luaC_newobj(L, LUA_VUSERDATA, sizeudata(nuvalue, s));
  u = gco2u(o);
modified external/lua/src/lstrlib.c
@@ -152,8 +152,9 @@ static int str_rep (lua_State *L) {
  const char *s = luaL_checklstring(L, 1, &l);
  lua_Integer n = luaL_checkinteger(L, 2);
  const char *sep = luaL_optlstring(L, 3, "", &lsep);
-
  if (n <= 0) lua_pushliteral(L, "");
-
  else if (l + lsep < l || l + lsep > MAXSIZE / n)  /* may overflow? */
+
  if (n <= 0)
+
    lua_pushliteral(L, "");
+
  else if (l_unlikely(l + lsep < l || l + lsep > MAXSIZE / n))
    return luaL_error(L, "resulting string too large");
  else {
    size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep;
@@ -181,7 +182,7 @@ static int str_byte (lua_State *L) {
  size_t pose = getendpos(L, 3, pi, l);
  int n, i;
  if (posi > pose) return 0;  /* empty interval; return no values */
-
  if (pose - posi >= (size_t)INT_MAX)  /* arithmetic overflow? */
+
  if (l_unlikely(pose - posi >= (size_t)INT_MAX))  /* arithmetic overflow? */
    return luaL_error(L, "string slice too long");
  n = (int)(pose -  posi) + 1;
  luaL_checkstack(L, n, "string slice too long");
@@ -235,7 +236,7 @@ static int str_dump (lua_State *L) {
  luaL_checktype(L, 1, LUA_TFUNCTION);
  lua_settop(L, 1);  /* ensure function is on the top of the stack */
  state.init = 0;
-
  if (lua_dump(L, writer, &state, strip) != 0)
+
  if (l_unlikely(lua_dump(L, writer, &state, strip) != 0))
    return luaL_error(L, "unable to dump given function");
  luaL_pushresult(&state.B);
  return 1;
@@ -275,7 +276,8 @@ static int tonum (lua_State *L, int arg) {

static void trymt (lua_State *L, const char *mtname) {
  lua_settop(L, 2);  /* back to the original arguments */
-
  if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname))
+
  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_typename(L, -2), luaL_typename(L, -1));
  lua_insert(L, -3);  /* put metamethod before arguments */
@@ -383,7 +385,8 @@ static const char *match (MatchState *ms, const char *s, const char *p);

static int check_capture (MatchState *ms, int l) {
  l -= '1';
-
  if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
+
  if (l_unlikely(l < 0 || l >= ms->level ||
+
                 ms->capture[l].len == CAP_UNFINISHED))
    return luaL_error(ms->L, "invalid capture index %%%d", l + 1);
  return l;
}
@@ -400,14 +403,14 @@ static int capture_to_close (MatchState *ms) {
static const char *classend (MatchState *ms, const char *p) {
  switch (*p++) {
    case L_ESC: {
-
      if (p == ms->p_end)
+
      if (l_unlikely(p == ms->p_end))
        luaL_error(ms->L, "malformed pattern (ends with '%%')");
      return p+1;
    }
    case '[': {
      if (*p == '^') p++;
      do {  /* look for a ']' */
-
        if (p == ms->p_end)
+
        if (l_unlikely(p == ms->p_end))
          luaL_error(ms->L, "malformed pattern (missing ']')");
        if (*(p++) == L_ESC && p < ms->p_end)
          p++;  /* skip escapes (e.g. '%]') */
@@ -482,7 +485,7 @@ static int singlematch (MatchState *ms, const char *s, const char *p,

static const char *matchbalance (MatchState *ms, const char *s,
                                   const char *p) {
-
  if (p >= ms->p_end - 1)
+
  if (l_unlikely(p >= ms->p_end - 1))
    luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')");
  if (*s != *p) return NULL;
  else {
@@ -565,7 +568,7 @@ static const char *match_capture (MatchState *ms, const char *s, int l) {


static const char *match (MatchState *ms, const char *s, const char *p) {
-
  if (ms->matchdepth-- == 0)
+
  if (l_unlikely(ms->matchdepth-- == 0))
    luaL_error(ms->L, "pattern too complex");
  init: /* using goto's to optimize tail recursion */
  if (p != ms->p_end) {  /* end of pattern? */
@@ -599,7 +602,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
          case 'f': {  /* frontier? */
            const char *ep; char previous;
            p += 2;
-
            if (*p != '[')
+
            if (l_unlikely(*p != '['))
              luaL_error(ms->L, "missing '[' after '%%f' in pattern");
            ep = classend(ms, p);  /* points to what is next */
            previous = (s == ms->src_init) ? '\0' : *(s - 1);
@@ -699,7 +702,7 @@ static const char *lmemfind (const char *s1, size_t l1,
static size_t get_onecapture (MatchState *ms, int i, const char *s,
                              const char *e, const char **cap) {
  if (i >= ms->level) {
-
    if (i != 0)
+
    if (l_unlikely(i != 0))
      luaL_error(ms->L, "invalid capture index %%%d", i + 1);
    *cap = s;
    return e - s;
@@ -707,7 +710,7 @@ static size_t get_onecapture (MatchState *ms, int i, const char *s,
  else {
    ptrdiff_t capl = ms->capture[i].len;
    *cap = ms->capture[i].init;
-
    if (capl == CAP_UNFINISHED)
+
    if (l_unlikely(capl == CAP_UNFINISHED))
      luaL_error(ms->L, "unfinished capture");
    else if (capl == CAP_POSITION)
      lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
@@ -926,7 +929,7 @@ static int add_value (MatchState *ms, luaL_Buffer *b, const char *s,
    luaL_addlstring(b, s, e - s);  /* keep original text */
    return 0;  /* no changes */
  }
-
  else if (!lua_isstring(L, -1))
+
  else if (l_unlikely(!lua_isstring(L, -1)))
    return luaL_error(L, "invalid replacement value (a %s)",
                         luaL_typename(L, -1));
  else {
@@ -1058,7 +1061,7 @@ static int lua_number2strx (lua_State *L, char *buff, int sz,
    for (i = 0; i < n; i++)
      buff[i] = toupper(uchar(buff[i]));
  }
-
  else if (fmt[SIZELENMOD] != 'a')
+
  else if (l_unlikely(fmt[SIZELENMOD] != 'a'))
    return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
  return n;
}
@@ -1087,13 +1090,31 @@ static int lua_number2strx (lua_State *L, char *buff, int sz,


/* valid flags in a format specification */
-
#if !defined(L_FMTFLAGS)
-
#define L_FMTFLAGS	"-+ #0"
+
#if !defined(L_FMTFLAGSF)
+

+
/* valid flags for a, A, e, E, f, F, g, and G conversions */
+
#define L_FMTFLAGSF	"-+#0 "
+

+
/* valid flags for o, x, and X conversions */
+
#define L_FMTFLAGSX	"-#0"
+

+
/* valid flags for d and i conversions */
+
#define L_FMTFLAGSI	"-+0 "
+

+
/* valid flags for u conversions */
+
#define L_FMTFLAGSU	"-0"
+

+
/* valid flags for c, p, and s conversions */
+
#define L_FMTFLAGSC	"-"
+

#endif


/*
-
** maximum size of each format specification (such as "%-099.99d")
+
** Maximum size of each format specification (such as "%-099.99d"):
+
** Initial '%', flags (up to 5), width (2), period, precision (2),
+
** length modifier (8), conversion specifier, and final '\0', plus some
+
** extra.
*/
#define MAX_FORMAT	32

@@ -1186,25 +1207,53 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
}


-
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
-
  const char *p = strfrmt;
-
  while (*p != '\0' && strchr(L_FMTFLAGS, *p) != NULL) p++;  /* skip flags */
-
  if ((size_t)(p - strfrmt) >= sizeof(L_FMTFLAGS)/sizeof(char))
-
    luaL_error(L, "invalid format (repeated flags)");
-
  if (isdigit(uchar(*p))) p++;  /* skip width */
-
  if (isdigit(uchar(*p))) p++;  /* (2 digits at most) */
-
  if (*p == '.') {
-
    p++;
-
    if (isdigit(uchar(*p))) p++;  /* skip precision */
-
    if (isdigit(uchar(*p))) p++;  /* (2 digits at most) */
+
static const char *get2digits (const char *s) {
+
  if (isdigit(uchar(*s))) {
+
    s++;
+
    if (isdigit(uchar(*s))) s++;  /* (2 digits at most) */
+
  }
+
  return s;
+
}
+

+

+
/*
+
** Check whether a conversion specification is valid. When called,
+
** first character in 'form' must be '%' and last character must
+
** be a valid conversion specifier. 'flags' are the accepted flags;
+
** 'precision' signals whether to accept a precision.
+
*/
+
static void checkformat (lua_State *L, const char *form, const char *flags,
+
                                       int precision) {
+
  const char *spec = form + 1;  /* skip '%' */
+
  spec += strspn(spec, flags);  /* skip flags */
+
  if (*spec != '0') {  /* a width cannot start with '0' */
+
    spec = get2digits(spec);  /* skip width */
+
    if (*spec == '.' && precision) {
+
      spec++;
+
      spec = get2digits(spec);  /* skip precision */
+
    }
  }
-
  if (isdigit(uchar(*p)))
-
    luaL_error(L, "invalid format (width or precision too long)");
+
  if (!isalpha(uchar(*spec)))  /* did not go to the end? */
+
    luaL_error(L, "invalid conversion specification: '%s'", form);
+
}
+

+

+
/*
+
** Get a conversion specification and copy it to 'form'.
+
** Return the address of its last character.
+
*/
+
static const char *getformat (lua_State *L, const char *strfrmt,
+
                                            char *form) {
+
  /* spans flags, width, and precision ('0' is included as a flag) */
+
  size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789.");
+
  len++;  /* adds following character (should be the specifier) */
+
  /* still needs space for '%', '\0', plus a length modifier */
+
  if (len >= MAX_FORMAT - 10)
+
    luaL_error(L, "invalid format (too long)");
  *(form++) = '%';
-
  memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char));
-
  form += (p - strfrmt) + 1;
-
  *form = '\0';
-
  return p;
+
  memcpy(form, strfrmt, len * sizeof(char));
+
  *(form + len) = '\0';
+
  return strfrmt + len - 1;
}


@@ -1227,6 +1276,7 @@ static int str_format (lua_State *L) {
  size_t sfl;
  const char *strfrmt = luaL_checklstring(L, arg, &sfl);
  const char *strfrmt_end = strfrmt+sfl;
+
  const char *flags;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  while (strfrmt < strfrmt_end) {
@@ -1236,25 +1286,35 @@ static int str_format (lua_State *L) {
      luaL_addchar(&b, *strfrmt++);  /* %% */
    else { /* format item */
      char form[MAX_FORMAT];  /* to store the format ('%...') */
-
      int maxitem = MAX_ITEM;
-
      char *buff = luaL_prepbuffsize(&b, maxitem);  /* to put formatted item */
-
      int nb = 0;  /* number of bytes in added item */
+
      int maxitem = MAX_ITEM;  /* maximum length for the result */
+
      char *buff = luaL_prepbuffsize(&b, maxitem);  /* to put result */
+
      int nb = 0;  /* number of bytes in result */
      if (++arg > top)
        return luaL_argerror(L, arg, "no value");
-
      strfrmt = scanformat(L, strfrmt, form);
+
      strfrmt = getformat(L, strfrmt, form);
      switch (*strfrmt++) {
        case 'c': {
+
          checkformat(L, form, L_FMTFLAGSC, 0);
          nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg));
          break;
        }
        case 'd': case 'i':
-
        case 'o': case 'u': case 'x': case 'X': {
+
          flags = L_FMTFLAGSI;
+
          goto intcase;
+
        case 'u':
+
          flags = L_FMTFLAGSU;
+
          goto intcase;
+
        case 'o': case 'x': case 'X':
+
          flags = L_FMTFLAGSX;
+
         intcase: {
          lua_Integer n = luaL_checkinteger(L, arg);
+
          checkformat(L, form, flags, 1);
          addlenmod(form, LUA_INTEGER_FRMLEN);
          nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n);
          break;
        }
        case 'a': case 'A':
+
          checkformat(L, form, L_FMTFLAGSF, 1);
          addlenmod(form, LUA_NUMBER_FRMLEN);
          nb = lua_number2strx(L, buff, maxitem, form,
                                  luaL_checknumber(L, arg));
@@ -1265,12 +1325,14 @@ static int str_format (lua_State *L) {
          /* FALLTHROUGH */
        case 'e': case 'E': case 'g': case 'G': {
          lua_Number n = luaL_checknumber(L, arg);
+
          checkformat(L, form, L_FMTFLAGSF, 1);
          addlenmod(form, LUA_NUMBER_FRMLEN);
          nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n);
          break;
        }
        case 'p': {
          const void *p = lua_topointer(L, arg);
+
          checkformat(L, form, L_FMTFLAGSC, 0);
          if (p == NULL) {  /* avoid calling 'printf' with argument NULL */
            p = "(null)";  /* result */
            form[strlen(form) - 1] = 's';  /* format it as a string */
@@ -1291,7 +1353,8 @@ static int str_format (lua_State *L) {
            luaL_addvalue(&b);  /* keep entire string */
          else {
            luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
-
            if (!strchr(form, '.') && l >= 100) {
+
            checkformat(L, form, L_FMTFLAGSC, 1);
+
            if (strchr(form, '.') == NULL && l >= 100) {
              /* no precision and string is too long to be formatted */
              luaL_addvalue(&b);  /* keep entire string */
            }
@@ -1349,25 +1412,6 @@ static const union {
} nativeendian = {1};


-
/* dummy structure to get native alignment requirements */
-
struct cD {
-
  char c;
-
  union { double d; void *p; lua_Integer i; lua_Number n; } u;
-
};
-

-
#define MAXALIGN	(offsetof(struct cD, u))
-

-

-
/*
-
** Union for serializing floats
-
*/
-
typedef union Ftypes {
-
  float f;
-
  double d;
-
  lua_Number n;
-
} Ftypes;
-

-

/*
** information to pack/unpack stuff
*/
@@ -1384,7 +1428,9 @@ typedef struct Header {
typedef enum KOption {
  Kint,		/* signed integers */
  Kuint,	/* unsigned integers */
-
  Kfloat,	/* floating-point numbers */
+
  Kfloat,	/* single-precision floating-point numbers */
+
  Knumber,	/* Lua "native" floating-point numbers */
+
  Kdouble,	/* double-precision floating-point numbers */
  Kchar,	/* fixed-length strings */
  Kstring,	/* strings with prefixed length */
  Kzstr,	/* zero-terminated strings */
@@ -1419,7 +1465,7 @@ static int getnum (const char **fmt, int df) {
*/
static int getnumlimit (Header *h, const char **fmt, int df) {
  int sz = getnum(fmt, df);
-
  if (sz > MAXINTSIZE || sz <= 0)
+
  if (l_unlikely(sz > MAXINTSIZE || sz <= 0))
    return luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
                            sz, MAXINTSIZE);
  return sz;
@@ -1440,6 +1486,8 @@ static void initheader (lua_State *L, Header *h) {
** Read and classify next option. 'size' is filled with option's size.
*/
static KOption getoption (Header *h, const char **fmt, int *size) {
+
  /* dummy structure to get native alignment requirements */
+
  struct cD { char c; union { LUAI_MAXALIGN; } u; };
  int opt = *((*fmt)++);
  *size = 0;  /* default */
  switch (opt) {
@@ -1453,14 +1501,14 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
    case 'J': *size = sizeof(lua_Integer); return Kuint;
    case 'T': *size = sizeof(size_t); return Kuint;
    case 'f': *size = sizeof(float); return Kfloat;
-
    case 'd': *size = sizeof(double); return Kfloat;
-
    case 'n': *size = sizeof(lua_Number); return Kfloat;
+
    case 'n': *size = sizeof(lua_Number); return Knumber;
+
    case 'd': *size = sizeof(double); return Kdouble;
    case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint;
    case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
    case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
    case 'c':
      *size = getnum(fmt, -1);
-
      if (*size == -1)
+
      if (l_unlikely(*size == -1))
        luaL_error(h->L, "missing size for format option 'c'");
      return Kchar;
    case 'z': return Kzstr;
@@ -1470,7 +1518,11 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
    case '<': h->islittle = 1; break;
    case '>': h->islittle = 0; break;
    case '=': h->islittle = nativeendian.little; break;
-
    case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break;
+
    case '!': {
+
      const int maxalign = offsetof(struct cD, u);
+
      h->maxalign = getnumlimit(h, fmt, maxalign);
+
      break;
+
    }
    default: luaL_error(h->L, "invalid format option '%c'", opt);
  }
  return Knop;
@@ -1499,7 +1551,7 @@ static KOption getdetails (Header *h, size_t totalsize,
  else {
    if (align > h->maxalign)  /* enforce maximum alignment */
      align = h->maxalign;
-
    if ((align & (align - 1)) != 0)  /* is 'align' not a power of 2? */
+
    if (l_unlikely((align & (align - 1)) != 0))  /* not a power of 2? */
      luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
    *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1);
  }
@@ -1580,15 +1632,27 @@ static int str_pack (lua_State *L) {
        packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
        break;
      }
-
      case Kfloat: {  /* floating-point options */
-
        Ftypes u;
-
        char *buff = luaL_prepbuffsize(&b, size);
-
        lua_Number n = luaL_checknumber(L, arg);  /* get argument */
-
        if (size == sizeof(u.f)) u.f = (float)n;  /* copy it into 'u' */
-
        else if (size == sizeof(u.d)) u.d = (double)n;
-
        else u.n = n;
-
        /* move 'u' to final result, correcting endianness if needed */
-
        copywithendian(buff, (char *)&u, size, h.islittle);
+
      case Kfloat: {  /* C float */
+
        float f = (float)luaL_checknumber(L, arg);  /* get argument */
+
        char *buff = luaL_prepbuffsize(&b, sizeof(f));
+
        /* move 'f' to final result, correcting endianness if needed */
+
        copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
+
        luaL_addsize(&b, size);
+
        break;
+
      }
+
      case Knumber: {  /* Lua float */
+
        lua_Number f = luaL_checknumber(L, arg);  /* get argument */
+
        char *buff = luaL_prepbuffsize(&b, sizeof(f));
+
        /* move 'f' to final result, correcting endianness if needed */
+
        copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
+
        luaL_addsize(&b, size);
+
        break;
+
      }
+
      case Kdouble: {  /* C double */
+
        double f = (double)luaL_checknumber(L, arg);  /* get argument */
+
        char *buff = luaL_prepbuffsize(&b, sizeof(f));
+
        /* move 'f' to final result, correcting endianness if needed */
+
        copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
        luaL_addsize(&b, size);
        break;
      }
@@ -1679,7 +1743,7 @@ static lua_Integer unpackint (lua_State *L, const char *str,
  else if (size > SZINT) {  /* must check unread bytes */
    int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC;
    for (i = limit; i < size; i++) {
-
      if ((unsigned char)str[islittle ? i : size - 1 - i] != mask)
+
      if (l_unlikely((unsigned char)str[islittle ? i : size - 1 - i] != mask))
        luaL_error(L, "%d-byte integer does not fit into Lua Integer", size);
    }
  }
@@ -1714,13 +1778,21 @@ static int str_unpack (lua_State *L) {
        break;
      }
      case Kfloat: {
-
        Ftypes u;
-
        lua_Number num;
-
        copywithendian((char *)&u, data + pos, size, h.islittle);
-
        if (size == sizeof(u.f)) num = (lua_Number)u.f;
-
        else if (size == sizeof(u.d)) num = (lua_Number)u.d;
-
        else num = u.n;
-
        lua_pushnumber(L, num);
+
        float f;
+
        copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
+
        lua_pushnumber(L, (lua_Number)f);
+
        break;
+
      }
+
      case Knumber: {
+
        lua_Number f;
+
        copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
+
        lua_pushnumber(L, f);
+
        break;
+
      }
+
      case Kdouble: {
+
        double f;
+
        copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
+
        lua_pushnumber(L, (lua_Number)f);
        break;
      }
      case Kchar: {
modified external/lua/src/ltable.c
@@ -68,20 +68,23 @@
#define MAXHSIZE	luaM_limitN(1u << MAXHBITS, Node)


+
/*
+
** When the original hash value is good, hashing by a power of 2
+
** avoids the cost of '%'.
+
*/
#define hashpow2(t,n)		(gnode(t, lmod((n), sizenode(t))))

-
#define hashstr(t,str)		hashpow2(t, (str)->hash)
-
#define hashboolean(t,p)	hashpow2(t, p)
-
#define hashint(t,i)		hashpow2(t, i)
-

-

/*
-
** for some types, it is better to avoid modulus by power of 2, as
-
** they tend to have many 2 factors.
+
** for other types, it is better to avoid modulo by power of 2, as
+
** they can have many 2 factors.
*/
#define hashmod(t,n)	(gnode(t, ((n) % ((sizenode(t)-1)|1))))


+
#define hashstr(t,str)		hashpow2(t, (str)->hash)
+
#define hashboolean(t,p)	hashpow2(t, p)
+

+

#define hashpointer(t,p)	hashmod(t, point2uint(p))


@@ -96,6 +99,20 @@ static const Node dummynode_ = {
static const TValue absentkey = {ABSTKEYCONSTANT};


+
/*
+
** Hash for integers. To allow a good hash, use the remainder operator
+
** ('%'). If integer fits as a non-negative int, compute an int
+
** remainder, which is faster. Otherwise, use an unsigned-integer
+
** remainder, which uses all bits and ensures a non-negative result.
+
*/
+
static Node *hashint (const Table *t, lua_Integer i) {
+
  lua_Unsigned ui = l_castS2U(i);
+
  if (ui <= (unsigned int)INT_MAX)
+
    return hashmod(t, cast_int(ui));
+
  else
+
    return hashmod(t, ui);
+
}
+


/*
** Hash for floating-point numbers.
@@ -129,39 +146,50 @@ static int l_hashfloat (lua_Number n) {

/*
** returns the 'main' position of an element in a table (that is,
-
** the index of its hash value). The key comes broken (tag in 'ktt'
-
** and value in 'vkl') so that we can call it on keys inserted into
-
** nodes.
+
** the index of its hash value).
*/
-
static Node *mainposition (const Table *t, int ktt, const Value *kvl) {
-
  switch (withvariant(ktt)) {
-
    case LUA_VNUMINT:
-
      return hashint(t, ivalueraw(*kvl));
-
    case LUA_VNUMFLT:
-
      return hashmod(t, l_hashfloat(fltvalueraw(*kvl)));
-
    case LUA_VSHRSTR:
-
      return hashstr(t, tsvalueraw(*kvl));
-
    case LUA_VLNGSTR:
-
      return hashpow2(t, luaS_hashlongstr(tsvalueraw(*kvl)));
+
static Node *mainpositionTV (const Table *t, const TValue *key) {
+
  switch (ttypetag(key)) {
+
    case LUA_VNUMINT: {
+
      lua_Integer i = ivalue(key);
+
      return hashint(t, i);
+
    }
+
    case LUA_VNUMFLT: {
+
      lua_Number n = fltvalue(key);
+
      return hashmod(t, l_hashfloat(n));
+
    }
+
    case LUA_VSHRSTR: {
+
      TString *ts = tsvalue(key);
+
      return hashstr(t, ts);
+
    }
+
    case LUA_VLNGSTR: {
+
      TString *ts = tsvalue(key);
+
      return hashpow2(t, luaS_hashlongstr(ts));
+
    }
    case LUA_VFALSE:
      return hashboolean(t, 0);
    case LUA_VTRUE:
      return hashboolean(t, 1);
-
    case LUA_VLIGHTUSERDATA:
-
      return hashpointer(t, pvalueraw(*kvl));
-
    case LUA_VLCF:
-
      return hashpointer(t, fvalueraw(*kvl));
-
    default:
-
      return hashpointer(t, gcvalueraw(*kvl));
+
    case LUA_VLIGHTUSERDATA: {
+
      void *p = pvalue(key);
+
      return hashpointer(t, p);
+
    }
+
    case LUA_VLCF: {
+
      lua_CFunction f = fvalue(key);
+
      return hashpointer(t, f);
+
    }
+
    default: {
+
      GCObject *o = gcvalue(key);
+
      return hashpointer(t, o);
+
    }
  }
}


-
/*
-
** Returns the main position of an element given as a 'TValue'
-
*/
-
static Node *mainpositionTV (const Table *t, const TValue *key) {
-
  return mainposition(t, rawtt(key), valraw(key));
+
l_sinline Node *mainpositionfromnode (const Table *t, Node *nd) {
+
  TValue key;
+
  getnodekey(cast(lua_State *, NULL), &key, nd);
+
  return mainpositionTV(t, &key);
}


@@ -307,7 +335,7 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key,
    return i;  /* yes; that's the index */
  else {
    const TValue *n = getgeneric(t, key, 1);
-
    if (unlikely(isabstkey(n)))
+
    if (l_unlikely(isabstkey(n)))
      luaG_runerror(L, "invalid key to 'next'");  /* key not found */
    i = cast_int(nodefromval(n) - gnode(t, 0));  /* key index in hash table */
    /* hash elements are numbered after array ones */
@@ -485,7 +513,7 @@ static void reinsert (lua_State *L, Table *ot, Table *t) {
         already present in the table */
      TValue k;
      getnodekey(L, &k, old);
-
      setobjt2t(L, luaH_set(L, t, &k), gval(old));
+
      luaH_set(L, t, &k, gval(old));
    }
  }
}
@@ -541,7 +569,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
  }
  /* allocate new array */
  newarray = luaM_reallocvector(L, t->array, oldasize, newasize, TValue);
-
  if (unlikely(newarray == NULL && newasize > 0)) {  /* allocation failed? */
+
  if (l_unlikely(newarray == NULL && newasize > 0)) {  /* allocation failed? */
    freehash(L, &newt);  /* release new hash part */
    luaM_error(L);  /* raise error (with array unchanged) */
  }
@@ -632,10 +660,10 @@ static Node *getfreepos (Table *t) {
** put new key in its main position; otherwise (colliding node is in its main
** position), new key goes to an empty position.
*/
-
TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
+
void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) {
  Node *mp;
  TValue aux;
-
  if (unlikely(ttisnil(key)))
+
  if (l_unlikely(ttisnil(key)))
    luaG_runerror(L, "table index is nil");
  else if (ttisfloat(key)) {
    lua_Number f = fltvalue(key);
@@ -644,9 +672,11 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
      setivalue(&aux, k);
      key = &aux;  /* insert it as an integer */
    }
-
    else if (unlikely(luai_numisnan(f)))
+
    else if (l_unlikely(luai_numisnan(f)))
      luaG_runerror(L, "table index is NaN");
  }
+
  if (ttisnil(value))
+
    return;  /* do not insert nil values */
  mp = mainpositionTV(t, key);
  if (!isempty(gval(mp)) || isdummy(t)) {  /* main position is taken? */
    Node *othern;
@@ -654,10 +684,11 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
    if (f == NULL) {  /* cannot find a free place? */
      rehash(L, t, key);  /* grow table */
      /* whatever called 'newkey' takes care of TM cache */
-
      return luaH_set(L, t, key);  /* insert key into grown table */
+
      luaH_set(L, t, key, value);  /* insert key into grown table */
+
      return;
    }
    lua_assert(!isdummy(t));
-
    othern = mainposition(t, keytt(mp), &keyval(mp));
+
    othern = mainpositionfromnode(t, mp);
    if (othern != mp) {  /* is colliding node out of its main position? */
      /* yes; move colliding node into free position */
      while (othern + gnext(othern) != mp)  /* find previous */
@@ -682,7 +713,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
  setnodekey(L, mp, key);
  luaC_barrierback(L, obj2gco(t), key);
  lua_assert(isempty(gval(mp)));
-
  return gval(mp);
+
  setobj2t(L, gval(mp), value);
}


@@ -770,28 +801,39 @@ const TValue *luaH_get (Table *t, const TValue *key) {


/*
+
** Finish a raw "set table" operation, where 'slot' is where the value
+
** should have been (the result of a previous "get table").
+
** Beware: when using this function you probably need to check a GC
+
** barrier and invalidate the TM cache.
+
*/
+
void luaH_finishset (lua_State *L, Table *t, const TValue *key,
+
                                   const TValue *slot, TValue *value) {
+
  if (isabstkey(slot))
+
    luaH_newkey(L, t, key, value);
+
  else
+
    setobj2t(L, cast(TValue *, slot), value);
+
}
+

+

+
/*
** beware: when using this function you probably need to check a GC
** barrier and invalidate the TM cache.
*/
-
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
-
  const TValue *p = luaH_get(t, key);
-
  if (!isabstkey(p))
-
    return cast(TValue *, p);
-
  else return luaH_newkey(L, t, key);
+
void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) {
+
  const TValue *slot = luaH_get(t, key);
+
  luaH_finishset(L, t, key, slot, value);
}


void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
  const TValue *p = luaH_getint(t, key);
-
  TValue *cell;
-
  if (!isabstkey(p))
-
    cell = cast(TValue *, p);
-
  else {
+
  if (isabstkey(p)) {
    TValue k;
    setivalue(&k, key);
-
    cell = luaH_newkey(L, t, &k);
+
    luaH_newkey(L, t, &k, value);
  }
-
  setobj2t(L, cell, value);
+
  else
+
    setobj2t(L, cast(TValue *, p), value);
}


modified external/lua/src/ltable.h
@@ -41,8 +41,12 @@ LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
-
LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
-
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
+
LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key,
+
                                                    TValue *value);
+
LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key,
+
                                                 TValue *value);
+
LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key,
+
                                       const TValue *slot, TValue *value);
LUAI_FUNC Table *luaH_new (lua_State *L);
LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
                                                    unsigned int nhsize);
modified external/lua/src/ltablib.c
@@ -59,8 +59,9 @@ static void checktab (lua_State *L, int arg, int what) {


static int tinsert (lua_State *L) {
-
  lua_Integer e = aux_getn(L, 1, TAB_RW) + 1;  /* first empty element */
  lua_Integer pos;  /* where to insert new element */
+
  lua_Integer e = aux_getn(L, 1, TAB_RW);
+
  e = luaL_intop(+, e, 1);  /* first empty element */
  switch (lua_gettop(L)) {
    case 2: {  /* called with only 2 arguments */
      pos = e;  /* insert new element at the end */
@@ -145,9 +146,9 @@ static int tmove (lua_State *L) {

static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) {
  lua_geti(L, 1, i);
-
  if (!lua_isstring(L, -1))
-
    luaL_error(L, "invalid value (%s) at index %d in table for 'concat'",
-
                  luaL_typename(L, -1), i);
+
  if (l_unlikely(!lua_isstring(L, -1)))
+
    luaL_error(L, "invalid value (%s) at index %I in table for 'concat'",
+
                  luaL_typename(L, -1), (LUAI_UACINT)i);
  luaL_addvalue(b);
}

@@ -196,7 +197,8 @@ static int tunpack (lua_State *L) {
  lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1));
  if (i > e) return 0;  /* empty range */
  n = (lua_Unsigned)e - i;  /* number of elements minus 1 (avoid overflows) */
-
  if (n >= (unsigned int)INT_MAX  || !lua_checkstack(L, (int)(++n)))
+
  if (l_unlikely(n >= (unsigned int)INT_MAX  ||
+
                 !lua_checkstack(L, (int)(++n))))
    return luaL_error(L, "too many results to unpack");
  for (; i < e; i++) {  /* push arg[i..e - 1] (to avoid overflows) */
    lua_geti(L, 1, i);
@@ -300,14 +302,14 @@ static IdxT partition (lua_State *L, IdxT lo, IdxT up) {
  for (;;) {
    /* next loop: repeat ++i while a[i] < P */
    while ((void)lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) {
-
      if (i == up - 1)  /* a[i] < P  but a[up - 1] == P  ?? */
+
      if (l_unlikely(i == up - 1))  /* a[i] < P  but a[up - 1] == P  ?? */
        luaL_error(L, "invalid order function for sorting");
      lua_pop(L, 1);  /* remove a[i] */
    }
    /* after the loop, a[i] >= P and a[lo .. i - 1] < P */
    /* next loop: repeat --j while P < a[j] */
    while ((void)lua_geti(L, 1, --j), sort_comp(L, -3, -1)) {
-
      if (j < i)  /* j < i  but  a[j] > P ?? */
+
      if (l_unlikely(j < i))  /* j < i  but  a[j] > P ?? */
        luaL_error(L, "invalid order function for sorting");
      lua_pop(L, 1);  /* remove a[j] */
    }
modified external/lua/src/ltm.c
@@ -147,7 +147,7 @@ static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,

void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
                    StkId res, TMS event) {
-
  if (!callbinTM(L, p1, p2, res, event)) {
+
  if (l_unlikely(!callbinTM(L, p1, p2, res, event))) {
    switch (event) {
      case TM_BAND: case TM_BOR: case TM_BXOR:
      case TM_SHL: case TM_SHR: case TM_BNOT: {
@@ -166,7 +166,8 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,

void luaT_tryconcatTM (lua_State *L) {
  StkId top = L->top;
-
  if (!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, TM_CONCAT))
+
  if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2,
+
                               TM_CONCAT)))
    luaG_concaterror(L, s2v(top - 2), s2v(top - 1));
}

modified external/lua/src/lua.c
@@ -37,6 +37,26 @@ static lua_State *globalL = NULL;
static const char *progname = LUA_PROGNAME;


+
#if defined(LUA_USE_POSIX)   /* { */
+

+
/*
+
** Use 'sigaction' when available.
+
*/
+
static void setsignal (int sig, void (*handler)(int)) {
+
  struct sigaction sa;
+
  sa.sa_handler = handler;
+
  sa.sa_flags = 0;
+
  sigemptyset(&sa.sa_mask);  /* do not mask any signal */
+
  sigaction(sig, &sa, NULL);
+
}
+

+
#else           /* }{ */
+

+
#define setsignal            signal
+

+
#endif                               /* } */
+

+

/*
** Hook set by signal function to stop the interpreter.
*/
@@ -55,7 +75,7 @@ static void lstop (lua_State *L, lua_Debug *ar) {
*/
static void laction (int i) {
  int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT;
-
  signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */
+
  setsignal(i, SIG_DFL); /* if another SIGINT happens, terminate process */
  lua_sethook(globalL, lstop, flag, 1);
}

@@ -69,14 +89,15 @@ static void print_usage (const char *badoption) {
  lua_writestringerror(
  "usage: %s [options] [script [args]]\n"
  "Available options are:\n"
-
  "  -e stat  execute string 'stat'\n"
-
  "  -i       enter interactive mode after executing 'script'\n"
-
  "  -l name  require library 'name' into global 'name'\n"
-
  "  -v       show version information\n"
-
  "  -E       ignore environment variables\n"
-
  "  -W       turn warnings on\n"
-
  "  --       stop handling options\n"
-
  "  -        stop handling options and execute stdin\n"
+
  "  -e stat   execute string 'stat'\n"
+
  "  -i        enter interactive mode after executing 'script'\n"
+
  "  -l mod    require library 'mod' into global 'mod'\n"
+
  "  -l g=mod  require library 'mod' into global 'g'\n"
+
  "  -v        show version information\n"
+
  "  -E        ignore environment variables\n"
+
  "  -W        turn warnings on\n"
+
  "  --        stop handling options\n"
+
  "  -         stop handling options and execute stdin\n"
  ,
  progname);
}
@@ -135,9 +156,9 @@ static int docall (lua_State *L, int narg, int nres) {
  lua_pushcfunction(L, msghandler);  /* push message handler */
  lua_insert(L, base);  /* put it under function and args */
  globalL = L;  /* to be available to 'laction' */
-
  signal(SIGINT, laction);  /* set C-signal handler */
+
  setsignal(SIGINT, laction);  /* set C-signal handler */
  status = lua_pcall(L, narg, nres, base);
-
  signal(SIGINT, SIG_DFL); /* reset C-signal handler */
+
  setsignal(SIGINT, SIG_DFL); /* reset C-signal handler */
  lua_remove(L, base);  /* remove message handler from the stack */
  return status;
}
@@ -187,16 +208,22 @@ static int dostring (lua_State *L, const char *s, const char *name) {


/*
-
** Calls 'require(name)' and stores the result in a global variable
-
** with the given name.
+
** Receives 'globname[=modname]' and runs 'globname = require(modname)'.
*/
-
static int dolibrary (lua_State *L, const char *name) {
+
static int dolibrary (lua_State *L, char *globname) {
  int status;
+
  char *modname = strchr(globname, '=');
+
  if (modname == NULL)  /* no explicit name? */
+
    modname = globname;  /* module name is equal to global name */
+
  else {
+
    *modname = '\0';  /* global name ends here */
+
    modname++;  /* module name starts after the '=' */
+
  }
  lua_getglobal(L, "require");
-
  lua_pushstring(L, name);
-
  status = docall(L, 1, 1);  /* call 'require(name)' */
+
  lua_pushstring(L, modname);
+
  status = docall(L, 1, 1);  /* call 'require(modname)' */
  if (status == LUA_OK)
-
    lua_setglobal(L, name);  /* global[name] = require return */
+
    lua_setglobal(L, globname);  /* globname = require(modname) */
  return report(L, status);
}

@@ -307,7 +334,7 @@ static int runargs (lua_State *L, char **argv, int n) {
    switch (option) {
      case 'e':  case 'l': {
        int status;
-
        const char *extra = argv[i] + 2;  /* both options need an argument */
+
        char *extra = argv[i] + 2;  /* both options need an argument */
        if (*extra == '\0') extra = argv[++i];
        lua_assert(extra != NULL);
        status = (option == 'e')
modified external/lua/src/lua.h
@@ -18,14 +18,14 @@

#define LUA_VERSION_MAJOR	"5"
#define LUA_VERSION_MINOR	"4"
-
#define LUA_VERSION_RELEASE	"2"
+
#define LUA_VERSION_RELEASE	"4"

#define LUA_VERSION_NUM			504
-
#define LUA_VERSION_RELEASE_NUM		(LUA_VERSION_NUM * 100 + 0)
+
#define LUA_VERSION_RELEASE_NUM		(LUA_VERSION_NUM * 100 + 4)

#define LUA_VERSION	"Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE	LUA_VERSION "." LUA_VERSION_RELEASE
-
#define LUA_COPYRIGHT	LUA_RELEASE "  Copyright (C) 1994-2020 Lua.org, PUC-Rio"
+
#define LUA_COPYRIGHT	LUA_RELEASE "  Copyright (C) 1994-2022 Lua.org, PUC-Rio"
#define LUA_AUTHORS	"R. Ierusalimschy, L. H. de Figueiredo, W. Celes"


@@ -347,7 +347,8 @@ LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s);
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
LUA_API void      (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);

-
LUA_API void  (lua_toclose) (lua_State *L, int idx);
+
LUA_API void (lua_toclose) (lua_State *L, int idx);
+
LUA_API void (lua_closeslot) (lua_State *L, int idx);


/*
@@ -491,7 +492,7 @@ struct lua_Debug {


/******************************************************************************
-
* Copyright (C) 1994-2020 Lua.org, PUC-Rio.
+
* Copyright (C) 1994-2022 Lua.org, PUC-Rio.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
modified external/lua/src/luac.c
@@ -155,6 +155,7 @@ static const Proto* combine(lua_State* L, int n)
   f->p[i]=toproto(L,i-n-1);
   if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
  }
+
  luaM_freearray(L,f->lineinfo,f->sizelineinfo);
  f->sizelineinfo=0;
  return f;
 }
@@ -600,11 +601,11 @@ static void PrintCode(const Proto* f)
	if (c==0) printf("all out"); else printf("%d out",c-1);
	break;
   case OP_TAILCALL:
-
	printf("%d %d %d",a,b,c);
+
	printf("%d %d %d%s",a,b,c,ISK);
	printf(COMMENT "%d in",b-1);
	break;
   case OP_RETURN:
-
	printf("%d %d %d",a,b,c);
+
	printf("%d %d %d%s",a,b,c,ISK);
	printf(COMMENT);
	if (b==0) printf("all out"); else printf("%d out",b-1);
	break;
@@ -619,7 +620,7 @@ static void PrintCode(const Proto* f)
	break;
   case OP_FORPREP:
	printf("%d %d",a,bx);
-
	printf(COMMENT "to %d",pc+bx+2);
+
	printf(COMMENT "exit to %d",pc+bx+3);
	break;
   case OP_TFORPREP:
	printf("%d %d",a,bx);
modified external/lua/src/luaconf.h
@@ -16,13 +16,13 @@
** ===================================================================
** General Configuration File for Lua
**
-
** Some definitions here can be changed externally, through the
-
** compiler (e.g., with '-D' options). Those are protected by
-
** '#if !defined' guards. However, several other definitions should
-
** be changed directly here, either because they affect the Lua
-
** ABI (by making the changes here, you ensure that all software
-
** connected to Lua, such as C libraries, will be compiled with the
-
** same configuration); or because they are seldom changed.
+
** Some definitions here can be changed externally, through the compiler
+
** (e.g., with '-D' options): They are commented out or protected
+
** by '#if !defined' guards. However, several other definitions
+
** should be changed directly here, either because they affect the
+
** Lua ABI (by making the changes here, you ensure that all software
+
** connected to Lua, such as C libraries, will be compiled with the same
+
** configuration); or because they are seldom changed.
**
** Search for "@@" to find all configurable definitions.
** ===================================================================
@@ -81,27 +81,13 @@

/*
** {==================================================================
-
** Configuration for Number types.
+
** Configuration for Number types. These options should not be
+
** set externally, because any other code connected to Lua must
+
** use the same configuration.
** ===================================================================
*/

/*
-
@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats.
-
*/
-
/* #define LUA_32BITS */
-

-

-
/*
-
@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
-
** C89 ('long' and 'double'); Windows always has '__int64', so it does
-
** not need to use this case.
-
*/
-
#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
-
#define LUA_C89_NUMBERS
-
#endif
-

-

-
/*
@@ LUA_INT_TYPE defines the type for Lua integers.
@@ LUA_FLOAT_TYPE defines the type for Lua floats.
** Lua should work fine with any mix of these options supported
@@ -121,7 +107,31 @@
#define LUA_FLOAT_DOUBLE	2
#define LUA_FLOAT_LONGDOUBLE	3

-
#if defined(LUA_32BITS)		/* { */
+

+
/* Default configuration ('long long' and 'double', for 64-bit Lua) */
+
#define LUA_INT_DEFAULT		LUA_INT_LONGLONG
+
#define LUA_FLOAT_DEFAULT	LUA_FLOAT_DOUBLE
+

+

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

+

+
/*
+
@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
+
** C89 ('long' and 'double'); Windows always has '__int64', so it does
+
** not need to use this case.
+
*/
+
#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
+
#define LUA_C89_NUMBERS		1
+
#else
+
#define LUA_C89_NUMBERS		0
+
#endif
+

+

+
#if LUA_32BITS		/* { */
/*
** 32-bit integers and 'float'
*/
@@ -132,26 +142,21 @@
#endif
#define LUA_FLOAT_TYPE	LUA_FLOAT_FLOAT

-
#elif defined(LUA_C89_NUMBERS)	/* }{ */
+
#elif LUA_C89_NUMBERS	/* }{ */
/*
** largest types available for C89 ('long' and 'double')
*/
#define LUA_INT_TYPE	LUA_INT_LONG
#define LUA_FLOAT_TYPE	LUA_FLOAT_DOUBLE

-
#endif				/* } */
+
#else		/* }{ */
+
/* use defaults */

+
#define LUA_INT_TYPE	LUA_INT_DEFAULT
+
#define LUA_FLOAT_TYPE	LUA_FLOAT_DEFAULT

-
/*
-
** default configuration for 64-bit Lua ('long long' and 'double')
-
*/
-
#if !defined(LUA_INT_TYPE)
-
#define LUA_INT_TYPE	LUA_INT_LONGLONG
-
#endif
+
#endif				/* } */

-
#if !defined(LUA_FLOAT_TYPE)
-
#define LUA_FLOAT_TYPE	LUA_FLOAT_DOUBLE
-
#endif

/* }================================================================== */

@@ -373,14 +378,13 @@

/*
** {==================================================================
-
** Configuration for Numbers.
+
** Configuration for Numbers (low-level part).
** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
** satisfy your needs.
** ===================================================================
*/

/*
-
@@ LUA_NUMBER is the floating-point type used by Lua.
@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
@@ over a floating number.
@@ l_floatatt(x) corrects float attribute 'x' to the proper float type
@@ -473,10 +477,7 @@


/*
-
@@ LUA_INTEGER is the integer type used by Lua.
-
**
@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
-
**
@@ LUAI_UACINT is the result of a 'default argument promotion'
@@ over a LUA_INTEGER.
@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
@@ -484,7 +485,6 @@
@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED.
-
@@ LUA_UNSIGNEDBITS is the number of bits in a LUA_UNSIGNED.
@@ lua_integer2str converts an integer to a string.
*/

@@ -505,9 +505,6 @@
#define LUA_UNSIGNED		unsigned LUAI_UACINT


-
#define LUA_UNSIGNEDBITS	(sizeof(LUA_UNSIGNED) * CHAR_BIT)
-

-

/* now the variable definitions */

#if LUA_INT_TYPE == LUA_INT_INT		/* { int */
@@ -659,6 +656,34 @@
#define lua_getlocaledecpoint()		(localeconv()->decimal_point[0])
#endif

+

+
/*
+
** macros to improve jump prediction, used mostly for error handling
+
** and debug facilities. (Some macros in the Lua API use these macros.
+
** Define LUA_NOBUILTIN if you do not want '__builtin_expect' in your
+
** code.)
+
*/
+
#if !defined(luai_likely)
+

+
#if defined(__GNUC__) && !defined(LUA_NOBUILTIN)
+
#define luai_likely(x)		(__builtin_expect(((x) != 0), 1))
+
#define luai_unlikely(x)	(__builtin_expect(((x) != 0), 0))
+
#else
+
#define luai_likely(x)		(x)
+
#define luai_unlikely(x)	(x)
+
#endif
+

+
#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
+

+

+

/* }================================================================== */


modified external/lua/src/lualib.h
@@ -49,10 +49,4 @@ LUAMOD_API int (luaopen_package) (lua_State *L);
LUALIB_API void (luaL_openlibs) (lua_State *L);


-

-
#if !defined(lua_assert)
-
#define lua_assert(x)	((void)0)
-
#endif
-

-

#endif
modified external/lua/src/lutf8lib.c
@@ -224,14 +224,11 @@ static int byteoffset (lua_State *L) {
static int iter_aux (lua_State *L, int strict) {
  size_t len;
  const char *s = luaL_checklstring(L, 1, &len);
-
  lua_Integer n = lua_tointeger(L, 2) - 1;
-
  if (n < 0)  /* first iteration? */
-
    n = 0;  /* start from here */
-
  else if (n < (lua_Integer)len) {
-
    n++;  /* skip current byte */
-
    while (iscont(s + n)) n++;  /* and its continuations */
+
  lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2);
+
  if (n < len) {
+
    while (iscont(s + n)) n++;  /* skip continuation bytes */
  }
-
  if (n >= (lua_Integer)len)
+
  if (n >= len)  /* (also handles original 'n' being negative) */
    return 0;  /* no more codepoints */
  else {
    utfint code;
modified external/lua/src/lvm.c
@@ -235,11 +235,11 @@ static int forprep (lua_State *L, StkId ra) {
  }
  else {  /* try making all values floats */
    lua_Number init; lua_Number limit; lua_Number step;
-
    if (unlikely(!tonumber(plimit, &limit)))
+
    if (l_unlikely(!tonumber(plimit, &limit)))
      luaG_forerror(L, plimit, "limit");
-
    if (unlikely(!tonumber(pstep, &step)))
+
    if (l_unlikely(!tonumber(pstep, &step)))
      luaG_forerror(L, pstep, "step");
-
    if (unlikely(!tonumber(pinit, &init)))
+
    if (l_unlikely(!tonumber(pinit, &init)))
      luaG_forerror(L, pinit, "initial value");
    if (step == 0)
      luaG_runerror(L, "'for' step is zero");
@@ -292,7 +292,7 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
    if (slot == NULL) {  /* 't' is not a table? */
      lua_assert(!ttistable(t));
      tm = luaT_gettmbyobj(L, t, TM_INDEX);
-
      if (unlikely(notm(tm)))
+
      if (l_unlikely(notm(tm)))
        luaG_typeerror(L, t, "index");  /* no metamethod */
      /* else will try the metamethod */
    }
@@ -337,10 +337,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
      lua_assert(isempty(slot));  /* slot must be empty */
      tm = fasttm(L, h->metatable, TM_NEWINDEX);  /* get metamethod */
      if (tm == NULL) {  /* no metamethod? */
-
        if (isabstkey(slot))  /* no previous entry? */
-
          slot = luaH_newkey(L, h, key);  /* create one */
-
        /* no metamethod and (now) there is an entry with given key */
-
        setobj2t(L, cast(TValue *, slot), val);  /* set its new value */
+
        luaH_finishset(L, h, key, slot, val);  /* set new value */
        invalidateTMcache(h);
        luaC_barrierback(L, obj2gco(h), val);
        return;
@@ -349,7 +346,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
    }
    else {  /* not a table; check metamethod */
      tm = luaT_gettmbyobj(L, t, TM_NEWINDEX);
-
      if (unlikely(notm(tm)))
+
      if (l_unlikely(notm(tm)))
        luaG_typeerror(L, t, "index");
    }
    /* try the metamethod */
@@ -409,7 +406,7 @@ static int l_strcmp (const TString *ls, const TString *rs) {
** from float to int.)
** When 'f' is NaN, comparisons must result in false.
*/
-
static int LTintfloat (lua_Integer i, lua_Number f) {
+
l_sinline int LTintfloat (lua_Integer i, lua_Number f) {
  if (l_intfitsf(i))
    return luai_numlt(cast_num(i), f);  /* compare them as floats */
  else {  /* i < f <=> i < ceil(f) */
@@ -426,7 +423,7 @@ static int LTintfloat (lua_Integer i, lua_Number f) {
** Check whether integer 'i' is less than or equal to float 'f'.
** See comments on previous function.
*/
-
static int LEintfloat (lua_Integer i, lua_Number f) {
+
l_sinline int LEintfloat (lua_Integer i, lua_Number f) {
  if (l_intfitsf(i))
    return luai_numle(cast_num(i), f);  /* compare them as floats */
  else {  /* i <= f <=> i <= floor(f) */
@@ -443,7 +440,7 @@ static int LEintfloat (lua_Integer i, lua_Number f) {
** Check whether float 'f' is less than integer 'i'.
** See comments on previous function.
*/
-
static int LTfloatint (lua_Number f, lua_Integer i) {
+
l_sinline int LTfloatint (lua_Number f, lua_Integer i) {
  if (l_intfitsf(i))
    return luai_numlt(f, cast_num(i));  /* compare them as floats */
  else {  /* f < i <=> floor(f) < i */
@@ -460,7 +457,7 @@ static int LTfloatint (lua_Number f, lua_Integer i) {
** Check whether float 'f' is less than or equal to integer 'i'.
** See comments on previous function.
*/
-
static int LEfloatint (lua_Number f, lua_Integer i) {
+
l_sinline int LEfloatint (lua_Number f, lua_Integer i) {
  if (l_intfitsf(i))
    return luai_numle(f, cast_num(i));  /* compare them as floats */
  else {  /* f <= i <=> ceil(f) <= i */
@@ -476,7 +473,7 @@ static int LEfloatint (lua_Number f, lua_Integer i) {
/*
** Return 'l < r', for numbers.
*/
-
static int LTnum (const TValue *l, const TValue *r) {
+
l_sinline int LTnum (const TValue *l, const TValue *r) {
  lua_assert(ttisnumber(l) && ttisnumber(r));
  if (ttisinteger(l)) {
    lua_Integer li = ivalue(l);
@@ -498,7 +495,7 @@ static int LTnum (const TValue *l, const TValue *r) {
/*
** Return 'l <= r', for numbers.
*/
-
static int LEnum (const TValue *l, const TValue *r) {
+
l_sinline int LEnum (const TValue *l, const TValue *r) {
  lua_assert(ttisnumber(l) && ttisnumber(r));
  if (ttisinteger(l)) {
    lua_Integer li = ivalue(l);
@@ -571,8 +568,13 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
    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 */
-
      lua_Integer i1, i2;  /* compare them as integers */
-
      return (tointegerns(t1, &i1) && tointegerns(t2, &i2) && i1 == i2);
+
      /* 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);
    }
  }
  /* values have same type and same variant */
@@ -654,7 +656,7 @@ void luaV_concat (lua_State *L, int total) {
      /* collect total length and number of strings */
      for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
        size_t l = vslen(s2v(top - n - 1));
-
        if (unlikely(l >= (MAX_SIZE/sizeof(char)) - tl))
+
        if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl))
          luaG_runerror(L, "string length overflow");
        tl += l;
      }
@@ -698,7 +700,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
    }
    default: {  /* try metamethod */
      tm = luaT_gettmbyobj(L, rb, TM_LEN);
-
      if (unlikely(notm(tm)))  /* no metamethod? */
+
      if (l_unlikely(notm(tm)))  /* no metamethod? */
        luaG_typeerror(L, rb, "get length of");
      break;
    }
@@ -714,7 +716,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
** otherwise 'floor(q) == trunc(q) - 1'.
*/
lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) {
-
  if (unlikely(l_castS2U(n) + 1u <= 1u)) {  /* special cases: -1 or 0 */
+
  if (l_unlikely(l_castS2U(n) + 1u <= 1u)) {  /* special cases: -1 or 0 */
    if (n == 0)
      luaG_runerror(L, "attempt to divide by zero");
    return intop(-, 0, m);   /* n==-1; avoid overflow with 0x80000...//-1 */
@@ -734,7 +736,7 @@ lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) {
** about luaV_idiv.)
*/
lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) {
-
  if (unlikely(l_castS2U(n) + 1u <= 1u)) {  /* special cases: -1 or 0 */
+
  if (l_unlikely(l_castS2U(n) + 1u <= 1u)) {  /* special cases: -1 or 0 */
    if (n == 0)
      luaG_runerror(L, "attempt to perform 'n%%0'");
    return 0;   /* m % -1 == 0; avoid overflow with 0x80000...%-1 */
@@ -764,7 +766,8 @@ lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) {
/*
** Shift left operation. (Shift right just negates 'y'.)
*/
-
#define luaV_shiftr(x,y)	luaV_shiftl(x,-(y))
+
#define luaV_shiftr(x,y)	luaV_shiftl(x,intop(-, 0, y))
+


lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
  if (y < 0) {  /* shift right? */
@@ -845,6 +848,19 @@ void luaV_finishOp (lua_State *L) {
      luaV_concat(L, total);  /* concat them (may yield again) */
      break;
    }
+
    case OP_CLOSE: {  /* yielded closing variables */
+
      ci->u.l.savedpc--;  /* repeat instruction to close other vars. */
+
      break;
+
    }
+
    case OP_RETURN: {  /* yielded closing variables */
+
      StkId ra = base + GETARG_A(inst);
+
      /* adjust top to signal correct number of returns, in case the
+
         return is "up to top" ('isIT') */
+
      L->top = ra + ci->u2.nres;
+
      /* repeat instruction to close other vars. and complete the return */
+
      ci->u.l.savedpc--;
+
      break;
+
    }
    default: {
      /* only these other opcodes can yield */
      lua_assert(op == OP_TFORCALL || op == OP_CALL ||
@@ -920,7 +936,7 @@ void luaV_finishOp (lua_State *L) {
*/
#define op_arithfK(L,fop) {  \
  TValue *v1 = vRB(i);  \
-
  TValue *v2 = KC(i);  \
+
  TValue *v2 = KC(i); lua_assert(ttisnumber(v2));  \
  op_arithf_aux(L, v1, v2, fop); }


@@ -949,7 +965,7 @@ void luaV_finishOp (lua_State *L) {
*/
#define op_arithK(L,iop,fop) {  \
  TValue *v1 = vRB(i);  \
-
  TValue *v2 = KC(i);  \
+
  TValue *v2 = KC(i); lua_assert(ttisnumber(v2));  \
  op_arith_aux(L, v1, v2, iop, fop); }


@@ -1048,7 +1064,8 @@ void luaV_finishOp (lua_State *L) {
#define updatebase(ci)	(base = ci->func + 1)


-
#define updatestack(ci) { if (trap) { updatebase(ci); ra = RA(i); } }
+
#define updatestack(ci)  \
+
	{ if (l_unlikely(trap)) { updatebase(ci); ra = RA(i); } }


/*
@@ -1092,7 +1109,7 @@ void luaV_finishOp (lua_State *L) {
#define ProtectNT(exp)  (savepc(L), (exp), updatetrap(ci))

/*
-
** Protect code that can only raise errors. (That is, it cannnot change
+
** Protect code that can only raise errors. (That is, it cannot change
** the stack or hooks.)
*/
#define halfProtect(exp)  (savestate(L,ci), (exp))
@@ -1106,7 +1123,7 @@ void luaV_finishOp (lua_State *L) {

/* fetch an instruction and prepare its execution */
#define vmfetch()	{ \
-
  if (trap) {  /* stack reallocation or hooks? */ \
+
  if (l_unlikely(trap)) {  /* stack reallocation or hooks? */ \
    trap = luaG_traceexec(L, pc);  /* handle hooks */ \
    updatebase(ci);  /* correct stack */ \
  } \
@@ -1134,7 +1151,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
  cl = clLvalue(s2v(ci->func));
  k = cl->p->k;
  pc = ci->u.l.savedpc;
-
  if (trap) {
+
  if (l_unlikely(trap)) {
    if (pc == cl->p->code) {  /* first instruction (not resuming)? */
      if (cl->p->is_vararg)
        trap = 0;  /* hooks will start after VARARGPREP instruction */
@@ -1149,6 +1166,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
    Instruction i;  /* instruction being executed */
    StkId ra;  /* instruction's A register */
    vmfetch();
+
    #if 0
+
      /* low-level line tracing for debugging Lua */
+
      printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
+
    #endif
    lua_assert(base == ci->func + 1);
    lua_assert(base <= L->top && L->top < L->stack_last);
    /* invalidate top for instructions not expecting it */
@@ -1527,7 +1548,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
        vmbreak;
      }
      vmcase(OP_CLOSE) {
-
        Protect(luaF_close(L, ra, LUA_OK));
+
        Protect(luaF_close(L, ra, LUA_OK, 1));
        vmbreak;
      }
      vmcase(OP_TBC) {
@@ -1616,13 +1637,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
          updatetrap(ci);  /* C call; nothing else to be done */
        else {  /* Lua call: run function in this same C frame */
          ci = newci;
-
          ci->callstatus = 0;  /* call re-uses 'luaV_execute' */
          goto startfunc;
        }
        vmbreak;
      }
      vmcase(OP_TAILCALL) {
        int b = GETARG_B(i);  /* number of arguments + 1 (function) */
+
        int n;  /* number of results when calling a C function */
        int nparams1 = GETARG_C(i);
        /* delta is virtual 'func' - real 'func' (vararg functions) */
        int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
@@ -1632,29 +1653,18 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
          b = cast_int(L->top - ra);
        savepc(ci);  /* several calls here can raise errors */
        if (TESTARG_k(i)) {
-
          /* close upvalues from current call; the compiler ensures
-
             that there are no to-be-closed variables here, so this
-
             call cannot change the stack */
-
          luaF_close(L, base, NOCLOSINGMETH);
+
          luaF_closeupval(L, base);  /* close upvalues from current call */
+
          lua_assert(L->tbclist < base);  /* no pending tbc variables */
          lua_assert(base == ci->func + 1);
        }
-
        while (!ttisfunction(s2v(ra))) {  /* not a function? */
-
          luaD_tryfuncTM(L, ra);  /* try '__call' metamethod */
-
          b++;  /* there is now one extra argument */
-
          checkstackGCp(L, 1, ra);
-
        }
-
        if (!ttisLclosure(s2v(ra))) {  /* C function? */
-
          luaD_precall(L, ra, LUA_MULTRET);  /* call it */
-
          updatetrap(ci);
-
          updatestack(ci);  /* stack may have been relocated */
+
        if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0)  /* Lua function? */
+
          goto startfunc;  /* execute the callee */
+
        else {  /* C function? */
          ci->func -= delta;  /* restore 'func' (if vararg) */
-
          luaD_poscall(L, ci, cast_int(L->top - ra));  /* finish caller */
+
          luaD_poscall(L, ci, n);  /* finish caller */
          updatetrap(ci);  /* 'luaD_poscall' can change hooks */
          goto ret;  /* caller returns after the tail call */
        }
-
        ci->func -= delta;  /* restore 'func' (if vararg) */
-
        luaD_pretailcall(L, ci, ra, b);  /* prepare call frame */
-
        goto startfunc;  /* execute the callee */
      }
      vmcase(OP_RETURN) {
        int n = GETARG_B(i) - 1;  /* number of results */
@@ -1663,9 +1673,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
          n = cast_int(L->top - ra);  /* get what is available */
        savepc(ci);
        if (TESTARG_k(i)) {  /* may there be open upvalues? */
+
          ci->u2.nres = n;  /* save number of returns */
          if (L->top < ci->top)
            L->top = ci->top;
-
          luaF_close(L, base, LUA_OK);
+
          luaF_close(L, base, CLOSEKTOP, 1);
          updatetrap(ci);
          updatestack(ci);
        }
@@ -1677,23 +1688,23 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
        goto ret;
      }
      vmcase(OP_RETURN0) {
-
        if (L->hookmask) {
+
        if (l_unlikely(L->hookmask)) {
          L->top = ra;
          savepc(ci);
          luaD_poscall(L, ci, 0);  /* no hurry... */
          trap = 1;
        }
        else {  /* do the 'poscall' here */
-
          int nres = ci->nresults;
+
          int nres;
          L->ci = ci->previous;  /* back to caller */
          L->top = base - 1;
-
          while (nres-- > 0)
+
          for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
            setnilvalue(s2v(L->top++));  /* all results are nil */
        }
        goto ret;
      }
      vmcase(OP_RETURN1) {
-
        if (L->hookmask) {
+
        if (l_unlikely(L->hookmask)) {
          L->top = ra + 1;
          savepc(ci);
          luaD_poscall(L, ci, 1);  /* no hurry... */
@@ -1707,8 +1718,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
          else {
            setobjs2s(L, base - 1, ra);  /* at least this result */
            L->top = base;
-
            while (--nres > 0)  /* complete missing results */
-
              setnilvalue(s2v(L->top++));
+
            for (; l_unlikely(nres > 1); nres--)
+
              setnilvalue(s2v(L->top++));  /* complete missing results */
          }
        }
       ret:  /* return from a Lua function */
@@ -1811,7 +1822,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
      }
      vmcase(OP_VARARGPREP) {
        ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p));
-
        if (trap) {
+
        if (l_unlikely(trap)) {  /* previous "Protect" updated trap */
          luaD_hookcall(L, ci);
          L->oldpc = 1;  /* next opcode will be seen as a "new" line */
        }
modified external/lua/src/lvm.h
@@ -60,12 +60,14 @@ typedef enum {

/* convert an object to an integer (including string coercion) */
#define tointeger(o,i) \
-
  (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))
+
  (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \
+
                          : luaV_tointeger(o,i,LUA_FLOORN2I))


/* convert an object to an integer (without string coercion) */
#define tointegerns(o,i) \
-
  (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointegerns(o,i,LUA_FLOORN2I))
+
  (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \
+
                          : luaV_tointegerns(o,i,LUA_FLOORN2I))


#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))