mirror of
https://github.com/etlegacy/etlegacy-libs.git
synced 2024-11-10 06:42:14 +00:00
libs: updated to Lua 5.3.3
This commit is contained in:
parent
78782033b3
commit
fd1a83ddc5
34 changed files with 1245 additions and 789 deletions
|
@ -46,7 +46,7 @@ TO_MAN= lua.1 luac.1
|
|||
|
||||
# Lua version and release.
|
||||
V= 5.3
|
||||
R= $V.2
|
||||
R= $V.3
|
||||
|
||||
# Targets start here.
|
||||
all: $(PLAT)
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
|
||||
This is Lua 5.3.2, released on 25 Nov 2015.
|
||||
This is Lua 5.3.3, released on 30 May 2016.
|
||||
|
||||
For installation instructions, license details, and
|
||||
further information about Lua, see doc/readme.html.
|
||||
|
||||
This is a slightly modified version for ET: Legacy.
|
||||
The src/Makefile file has been adjusted to fit our
|
||||
posix and posix32bit requirements.
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ For a complete introduction to Lua programming, see the book
|
|||
|
||||
<P>
|
||||
<SMALL>
|
||||
Copyright © 2015 Lua.org, PUC-Rio.
|
||||
Copyright © 2015–2016 Lua.org, PUC-Rio.
|
||||
Freely available under the terms of the
|
||||
<A HREF="http://www.lua.org/license.html">Lua license</A>.
|
||||
</SMALL>
|
||||
|
@ -608,10 +608,10 @@ Freely available under the terms of the
|
|||
|
||||
<P CLASS="footer">
|
||||
Last update:
|
||||
Wed Jun 3 08:27:30 BRT 2015
|
||||
Thu Jan 14 10:14:28 BRST 2016
|
||||
</P>
|
||||
<!--
|
||||
Last change: revised for Lua 5.3.1
|
||||
Last change: revised for Lua 5.3.3
|
||||
-->
|
||||
|
||||
</BODY>
|
||||
|
|
|
@ -92,6 +92,7 @@ table hr {
|
|||
.footer {
|
||||
color: gray ;
|
||||
font-size: x-small ;
|
||||
text-transform: lowercase ;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
|
@ -157,3 +158,7 @@ table.book span {
|
|||
display: block ;
|
||||
margin-top: 0.25em ;
|
||||
}
|
||||
|
||||
img {
|
||||
background-color: white ;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
|
|||
|
||||
<P>
|
||||
<SMALL>
|
||||
Copyright © 2015 Lua.org, PUC-Rio.
|
||||
Copyright © 2015–2016 Lua.org, PUC-Rio.
|
||||
Freely available under the terms of the
|
||||
<a href="http://www.lua.org/license.html">Lua license</a>.
|
||||
</SMALL>
|
||||
|
@ -35,7 +35,7 @@ Freely available under the terms of the
|
|||
<!-- ====================================================================== -->
|
||||
<p>
|
||||
|
||||
<!-- $Id: manual.of,v 1.153 2015/11/25 16:57:42 roberto Exp $ -->
|
||||
<!-- $Id: manual.of,v 1.162 2016/05/30 15:57:03 roberto Exp $ -->
|
||||
|
||||
|
||||
|
||||
|
@ -43,30 +43,47 @@ Freely available under the terms of the
|
|||
<h1>1 – <a name="1">Introduction</a></h1>
|
||||
|
||||
<p>
|
||||
Lua is an extension programming language designed to support
|
||||
general procedural programming with data description
|
||||
facilities.
|
||||
Lua also offers good support for object-oriented programming,
|
||||
functional programming, and data-driven programming.
|
||||
Lua is intended to be used as a powerful, lightweight,
|
||||
embeddable scripting language for any program that needs one.
|
||||
Lua is a powerful, efficient, lightweight, embeddable scripting language.
|
||||
It supports procedural programming,
|
||||
object-oriented programming, functional programming,
|
||||
data-driven programming, and data description.
|
||||
|
||||
|
||||
<p>
|
||||
Lua combines simple procedural syntax with powerful data description
|
||||
constructs based on associative arrays and extensible semantics.
|
||||
Lua is dynamically typed,
|
||||
runs by interpreting bytecode with a register-based
|
||||
virtual machine,
|
||||
and has automatic memory management with
|
||||
incremental garbage collection,
|
||||
making it ideal for configuration, scripting,
|
||||
and rapid prototyping.
|
||||
|
||||
|
||||
<p>
|
||||
Lua is implemented as a library, written in <em>clean C</em>,
|
||||
the common subset of Standard C and C++.
|
||||
The Lua distribution includes a host program called <code>lua</code>,
|
||||
which uses the Lua library to offer a complete,
|
||||
standalone Lua interpreter,
|
||||
for interactive or batch use.
|
||||
Lua is intended to be used both as a powerful, lightweight,
|
||||
embeddable scripting language for any program that needs one,
|
||||
and as a powerful but lightweight and efficient stand-alone language.
|
||||
|
||||
|
||||
<p>
|
||||
As an extension language, Lua has no notion of a "main" program:
|
||||
it only works <em>embedded</em> in a host client,
|
||||
it works <em>embedded</em> in a host client,
|
||||
called the <em>embedding program</em> or simply the <em>host</em>.
|
||||
(Frequently, this host is the stand-alone <code>lua</code> program.)
|
||||
The host program can invoke functions to execute a piece of Lua code,
|
||||
can write and read Lua variables,
|
||||
and can register C functions to be called by Lua code.
|
||||
Through the use of C functions, Lua can be augmented to cope with
|
||||
a wide range of different domains,
|
||||
thus creating customized programming languages sharing a syntactical framework.
|
||||
The Lua distribution includes a sample host program called <code>lua</code>,
|
||||
which uses the Lua library to offer a complete, standalone Lua interpreter,
|
||||
for interactive or batch use.
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -351,8 +368,8 @@ It is up to the Lua program or its host to handle such error objects.
|
|||
When you use <a href="#pdf-xpcall"><code>xpcall</code></a> or <a href="#lua_pcall"><code>lua_pcall</code></a>,
|
||||
you may give a <em>message handler</em>
|
||||
to be called in case of errors.
|
||||
This function is called with the original error message
|
||||
and returns a new error message.
|
||||
This function is called with the original error object
|
||||
and returns a new error object.
|
||||
It is called before the error unwinds the stack,
|
||||
so that it can gather more information about the error,
|
||||
for instance by inspecting the stack and creating a stack traceback.
|
||||
|
@ -382,16 +399,23 @@ Lua calls this function to perform the addition.
|
|||
|
||||
|
||||
<p>
|
||||
The keys in a metatable are derived from the <em>event</em> names;
|
||||
The key for each event in a metatable is a string
|
||||
with the event name prefixed by two underscores;
|
||||
the corresponding values are called <em>metamethods</em>.
|
||||
In the previous example, the event is <code>"add"</code>
|
||||
In the previous example, the key is "<code>__add</code>"
|
||||
and the metamethod is the function that performs the addition.
|
||||
|
||||
|
||||
<p>
|
||||
You can query the metatable of any value
|
||||
using the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function.
|
||||
Lua queries metamethods in metatables using a raw access (see <a href="#pdf-rawget"><code>rawget</code></a>).
|
||||
So, to retrieve the metamethod for event <code>ev</code> in object <code>o</code>,
|
||||
Lua does the equivalent to the following code:
|
||||
|
||||
<pre>
|
||||
rawget(getmetatable(<em>o</em>) or {}, "__<em>ev</em>")
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You can replace the metatable of tables
|
||||
|
@ -420,18 +444,7 @@ when a userdata or a table is garbage collected (<a href="#2.5">§2.5</a>).
|
|||
|
||||
|
||||
<p>
|
||||
A detailed list of events controlled by metatables is given next.
|
||||
Each operation is identified by its corresponding event name.
|
||||
The key for each event is a string with its name prefixed by
|
||||
two underscores, '<code>__</code>';
|
||||
for instance, the key for operation "add" is the
|
||||
string "<code>__add</code>".
|
||||
Note that queries for metamethods are always raw;
|
||||
the access to a metamethod does not invoke other metamethods.
|
||||
|
||||
|
||||
<p>
|
||||
For the unary operators (negation, length, and bitwise not),
|
||||
For the unary operators (negation, length, and bitwise NOT),
|
||||
the metamethod is computed and called with a dummy second operand,
|
||||
equal to the first one.
|
||||
This extra operand is only to simplify Lua's internals
|
||||
|
@ -440,17 +453,21 @@ and may be removed in future versions.
|
|||
(For most uses this extra operand is irrelevant.)
|
||||
|
||||
|
||||
<p>
|
||||
A detailed list of events controlled by metatables is given next.
|
||||
Each operation is identified by its corresponding key.
|
||||
|
||||
|
||||
|
||||
<ul>
|
||||
|
||||
<li><b>"add": </b>
|
||||
the <code>+</code> operation.
|
||||
|
||||
<li><b><code>__add</code>: </b>
|
||||
the addition (<code>+</code>) operation.
|
||||
If any operand for an addition is not a number
|
||||
(nor a string coercible to a number),
|
||||
Lua will try to call a metamethod.
|
||||
First, Lua will check the first operand (even if it is valid).
|
||||
If that operand does not define a metamethod for the "<code>__add</code>" event,
|
||||
If that operand does not define a metamethod for <code>__add</code>,
|
||||
then Lua will check the second operand.
|
||||
If Lua can find a metamethod,
|
||||
it calls the metamethod with the two operands as arguments,
|
||||
|
@ -461,99 +478,84 @@ Otherwise,
|
|||
it raises an error.
|
||||
</li>
|
||||
|
||||
<li><b>"sub": </b>
|
||||
the <code>-</code> operation.
|
||||
|
||||
Behavior similar to the "add" operation.
|
||||
<li><b><code>__sub</code>: </b>
|
||||
the subtraction (<code>-</code>) operation.
|
||||
Behavior similar to the addition operation.
|
||||
</li>
|
||||
|
||||
<li><b>"mul": </b>
|
||||
the <code>*</code> operation.
|
||||
|
||||
Behavior similar to the "add" operation.
|
||||
<li><b><code>__mul</code>: </b>
|
||||
the multiplication (<code>*</code>) operation.
|
||||
Behavior similar to the addition operation.
|
||||
</li>
|
||||
|
||||
<li><b>"div": </b>
|
||||
the <code>/</code> operation.
|
||||
|
||||
Behavior similar to the "add" operation.
|
||||
<li><b><code>__div</code>: </b>
|
||||
the division (<code>/</code>) operation.
|
||||
Behavior similar to the addition operation.
|
||||
</li>
|
||||
|
||||
<li><b>"mod": </b>
|
||||
the <code>%</code> operation.
|
||||
|
||||
Behavior similar to the "add" operation.
|
||||
<li><b><code>__mod</code>: </b>
|
||||
the modulo (<code>%</code>) operation.
|
||||
Behavior similar to the addition operation.
|
||||
</li>
|
||||
|
||||
<li><b>"pow": </b>
|
||||
the <code>^</code> (exponentiation) operation.
|
||||
|
||||
Behavior similar to the "add" operation.
|
||||
<li><b><code>__pow</code>: </b>
|
||||
the exponentiation (<code>^</code>) operation.
|
||||
Behavior similar to the addition operation.
|
||||
</li>
|
||||
|
||||
<li><b>"unm": </b>
|
||||
the <code>-</code> (unary minus) operation.
|
||||
|
||||
Behavior similar to the "add" operation.
|
||||
<li><b><code>__unm</code>: </b>
|
||||
the negation (unary <code>-</code>) operation.
|
||||
Behavior similar to the addition operation.
|
||||
</li>
|
||||
|
||||
<li><b>"idiv": </b>
|
||||
the <code>//</code> (floor division) operation.
|
||||
|
||||
Behavior similar to the "add" operation.
|
||||
<li><b><code>__idiv</code>: </b>
|
||||
the floor division (<code>//</code>) operation.
|
||||
Behavior similar to the addition operation.
|
||||
</li>
|
||||
|
||||
<li><b>"band": </b>
|
||||
the <code>&</code> (bitwise and) operation.
|
||||
|
||||
Behavior similar to the "add" operation,
|
||||
<li><b><code>__band</code>: </b>
|
||||
the bitwise AND (<code>&</code>) operation.
|
||||
Behavior similar to the addition operation,
|
||||
except that Lua will try a metamethod
|
||||
if any operand is neither an integer
|
||||
nor a value coercible to an integer (see <a href="#3.4.3">§3.4.3</a>).
|
||||
</li>
|
||||
|
||||
<li><b>"bor": </b>
|
||||
the <code>|</code> (bitwise or) operation.
|
||||
|
||||
Behavior similar to the "band" operation.
|
||||
<li><b><code>__bor</code>: </b>
|
||||
the bitwise OR (<code>|</code>) operation.
|
||||
Behavior similar to the bitwise AND operation.
|
||||
</li>
|
||||
|
||||
<li><b>"bxor": </b>
|
||||
the <code>~</code> (bitwise exclusive or) operation.
|
||||
|
||||
Behavior similar to the "band" operation.
|
||||
<li><b><code>__bxor</code>: </b>
|
||||
the bitwise exclusive OR (binary <code>~</code>) operation.
|
||||
Behavior similar to the bitwise AND operation.
|
||||
</li>
|
||||
|
||||
<li><b>"bnot": </b>
|
||||
the <code>~</code> (bitwise unary not) operation.
|
||||
|
||||
Behavior similar to the "band" operation.
|
||||
<li><b><code>__bnot</code>: </b>
|
||||
the bitwise NOT (unary <code>~</code>) operation.
|
||||
Behavior similar to the bitwise AND operation.
|
||||
</li>
|
||||
|
||||
<li><b>"shl": </b>
|
||||
the <code><<</code> (bitwise left shift) operation.
|
||||
|
||||
Behavior similar to the "band" operation.
|
||||
<li><b><code>__shl</code>: </b>
|
||||
the bitwise left shift (<code><<</code>) operation.
|
||||
Behavior similar to the bitwise AND operation.
|
||||
</li>
|
||||
|
||||
<li><b>"shr": </b>
|
||||
the <code>>></code> (bitwise right shift) operation.
|
||||
|
||||
Behavior similar to the "band" operation.
|
||||
<li><b><code>__shr</code>: </b>
|
||||
the bitwise right shift (<code>>></code>) operation.
|
||||
Behavior similar to the bitwise AND operation.
|
||||
</li>
|
||||
|
||||
<li><b>"concat": </b>
|
||||
the <code>..</code> (concatenation) operation.
|
||||
|
||||
Behavior similar to the "add" operation,
|
||||
<li><b><code>__concat</code>: </b>
|
||||
the concatenation (<code>..</code>) operation.
|
||||
Behavior similar to the addition operation,
|
||||
except that Lua will try a metamethod
|
||||
if any operand is neither a string nor a number
|
||||
(which is always coercible to a string).
|
||||
</li>
|
||||
|
||||
<li><b>"len": </b>
|
||||
the <code>#</code> (length) operation.
|
||||
|
||||
<li><b><code>__len</code>: </b>
|
||||
the length (<code>#</code>) operation.
|
||||
If the object is not a string,
|
||||
Lua will try its metamethod.
|
||||
If there is a metamethod,
|
||||
|
@ -566,44 +568,40 @@ then Lua uses the table length operation (see <a href="#3.4.7">§3.4.7</a>).
|
|||
Otherwise, Lua raises an error.
|
||||
</li>
|
||||
|
||||
<li><b>"eq": </b>
|
||||
the <code>==</code> (equal) operation.
|
||||
|
||||
Behavior similar to the "add" operation,
|
||||
<li><b><code>__eq</code>: </b>
|
||||
the equal (<code>==</code>) operation.
|
||||
Behavior similar to the addition operation,
|
||||
except that Lua will try a metamethod only when the values
|
||||
being compared are either both tables or both full userdata
|
||||
and they are not primitively equal.
|
||||
The result of the call is always converted to a boolean.
|
||||
</li>
|
||||
|
||||
<li><b>"lt": </b>
|
||||
the <code><</code> (less than) operation.
|
||||
|
||||
Behavior similar to the "add" operation,
|
||||
<li><b><code>__lt</code>: </b>
|
||||
the less than (<code><</code>) operation.
|
||||
Behavior similar to the addition operation,
|
||||
except that Lua will try a metamethod only when the values
|
||||
being compared are neither both numbers nor both strings.
|
||||
The result of the call is always converted to a boolean.
|
||||
</li>
|
||||
|
||||
<li><b>"le": </b>
|
||||
the <code><=</code> (less equal) operation.
|
||||
|
||||
<li><b><code>__le</code>: </b>
|
||||
the less equal (<code><=</code>) operation.
|
||||
Unlike other operations,
|
||||
the less-equal operation can use two different events.
|
||||
First, Lua looks for the "<code>__le</code>" metamethod in both operands,
|
||||
like in the "lt" operation.
|
||||
First, Lua looks for the <code>__le</code> metamethod in both operands,
|
||||
like in the less than operation.
|
||||
If it cannot find such a metamethod,
|
||||
then it will try the "<code>__lt</code>" event,
|
||||
then it will try the <code>__lt</code> metamethod,
|
||||
assuming that <code>a <= b</code> is equivalent to <code>not (b < a)</code>.
|
||||
As with the other comparison operators,
|
||||
the result is always a boolean.
|
||||
(This use of the "<code>__lt</code>" event can be removed in future versions;
|
||||
it is also slower than a real "<code>__le</code>" metamethod.)
|
||||
(This use of the <code>__lt</code> event can be removed in future versions;
|
||||
it is also slower than a real <code>__le</code> metamethod.)
|
||||
</li>
|
||||
|
||||
<li><b>"index": </b>
|
||||
<li><b><code>__index</code>: </b>
|
||||
The indexing access <code>table[key]</code>.
|
||||
|
||||
This event happens when <code>table</code> is not a table or
|
||||
when <code>key</code> is not present in <code>table</code>.
|
||||
The metamethod is looked up in <code>table</code>.
|
||||
|
@ -613,16 +611,18 @@ The metamethod is looked up in <code>table</code>.
|
|||
Despite the name,
|
||||
the metamethod for this event can be either a function or a table.
|
||||
If it is a function,
|
||||
it is called with <code>table</code> and <code>key</code> as arguments.
|
||||
it is called with <code>table</code> and <code>key</code> as arguments,
|
||||
and the result of the call
|
||||
(adjusted to one value)
|
||||
is the result of the operation.
|
||||
If it is a table,
|
||||
the final result is the result of indexing this table with <code>key</code>.
|
||||
(This indexing is regular, not raw,
|
||||
and therefore can trigger another metamethod.)
|
||||
</li>
|
||||
|
||||
<li><b>"newindex": </b>
|
||||
<li><b><code>__newindex</code>: </b>
|
||||
The indexing assignment <code>table[key] = value</code>.
|
||||
|
||||
Like the index event,
|
||||
this event happens when <code>table</code> is not a table or
|
||||
when <code>key</code> is not present in <code>table</code>.
|
||||
|
@ -641,22 +641,24 @@ and therefore can trigger another metamethod.)
|
|||
|
||||
|
||||
<p>
|
||||
Whenever there is a "newindex" metamethod,
|
||||
Whenever there is a <code>__newindex</code> metamethod,
|
||||
Lua does not perform the primitive assignment.
|
||||
(If necessary,
|
||||
the metamethod itself can call <a href="#pdf-rawset"><code>rawset</code></a>
|
||||
to do the assignment.)
|
||||
</li>
|
||||
|
||||
<li><b>"call": </b>
|
||||
<li><b><code>__call</code>: </b>
|
||||
The call operation <code>func(args)</code>.
|
||||
|
||||
This event happens when Lua tries to call a non-function value
|
||||
(that is, <code>func</code> is not a function).
|
||||
The metamethod is looked up in <code>func</code>.
|
||||
If present,
|
||||
the metamethod is called with <code>func</code> as its first argument,
|
||||
followed by the arguments of the original call (<code>args</code>).
|
||||
All results of the call
|
||||
are the result of the operation.
|
||||
(This is the only metamethod that allows multiple results.)
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
@ -664,10 +666,19 @@ followed by the arguments of the original call (<code>args</code>).
|
|||
<p>
|
||||
It is a good practice to add all needed metamethods to a table
|
||||
before setting it as a metatable of some object.
|
||||
In particular, the "<code>__gc</code>" metamethod works only when this order
|
||||
In particular, the <code>__gc</code> metamethod works only when this order
|
||||
is followed (see <a href="#2.5.1">§2.5.1</a>).
|
||||
|
||||
|
||||
<p>
|
||||
Because metatables are regular tables,
|
||||
they can contain arbitrary fields,
|
||||
not only the event names defined above.
|
||||
Some functions in the standard library
|
||||
(e.g., <a href="#pdf-tostring"><code>tostring</code></a>)
|
||||
use other fields in metatables for their own purposes.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -935,7 +946,7 @@ In case of normal termination,
|
|||
<a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>,
|
||||
plus any values returned by the coroutine main function.
|
||||
In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b>
|
||||
plus an error message.
|
||||
plus an error object.
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -1168,7 +1179,7 @@ and the system file functions may have problems with
|
|||
some control characters.
|
||||
So, it is safer to represent
|
||||
non-text data as a quoted literal with
|
||||
explicit escape sequences for non-text characters.
|
||||
explicit escape sequences for the non-text characters.
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -1201,9 +1212,11 @@ which start with <code>0x</code> or <code>0X</code>.
|
|||
Hexadecimal constants also accept an optional fractional part
|
||||
plus an optional binary exponent,
|
||||
marked by a letter '<code>p</code>' or '<code>P</code>'.
|
||||
A numeric constant with a fractional dot or an exponent
|
||||
A numeric constant with a radix point or an exponent
|
||||
denotes a float;
|
||||
otherwise it denotes an integer.
|
||||
otherwise,
|
||||
if its value fits in an integer,
|
||||
it denotes an integer.
|
||||
Examples of valid integer constants are
|
||||
|
||||
<pre>
|
||||
|
@ -1794,7 +1807,7 @@ bitwise operators (see <a href="#3.4.2">§3.4.2</a>),
|
|||
relational operators (see <a href="#3.4.4">§3.4.4</a>), logical operators (see <a href="#3.4.5">§3.4.5</a>),
|
||||
and the concatenation operator (see <a href="#3.4.6">§3.4.6</a>).
|
||||
Unary operators comprise the unary minus (see <a href="#3.4.1">§3.4.1</a>),
|
||||
the unary bitwise not (see <a href="#3.4.2">§3.4.2</a>),
|
||||
the unary bitwise NOT (see <a href="#3.4.2">§3.4.2</a>),
|
||||
the unary logical <b>not</b> (see <a href="#3.4.5">§3.4.5</a>),
|
||||
and the unary <em>length operator</em> (see <a href="#3.4.7">§3.4.7</a>).
|
||||
|
||||
|
@ -1908,12 +1921,12 @@ that is equal modulo <em>2<sup>64</sup></em> to the mathematical result.)
|
|||
Lua supports the following bitwise operators:
|
||||
|
||||
<ul>
|
||||
<li><b><code>&</code>: </b>bitwise and</li>
|
||||
<li><b><code>|</code>: </b>bitwise or</li>
|
||||
<li><b><code>~</code>: </b>bitwise exclusive or</li>
|
||||
<li><b><code>&</code>: </b>bitwise AND</li>
|
||||
<li><b><code>|</code>: </b>bitwise OR</li>
|
||||
<li><b><code>~</code>: </b>bitwise exclusive OR</li>
|
||||
<li><b><code>>></code>: </b>right shift</li>
|
||||
<li><b><code><<</code>: </b>left shift</li>
|
||||
<li><b><code>~</code>: </b>unary bitwise not</li>
|
||||
<li><b><code>~</code>: </b>unary bitwise NOT</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
@ -1983,6 +1996,13 @@ is converted to the type (float or integer) required by the context
|
|||
(e.g., the operation that forced the conversion).
|
||||
|
||||
|
||||
<p>
|
||||
All conversions from strings to numbers
|
||||
accept both a dot and the current locale mark
|
||||
as the radix character.
|
||||
(The Lua lexer, however, accepts only a dot.)
|
||||
|
||||
|
||||
<p>
|
||||
The conversion from numbers to strings uses a
|
||||
non-specified human-readable format.
|
||||
|
@ -2792,7 +2812,7 @@ never returning
|
|||
|
||||
<p>
|
||||
The panic function runs as if it were a message handler (see <a href="#2.3">§2.3</a>);
|
||||
in particular, the error message is at the top of the stack.
|
||||
in particular, the error object is at the top of the stack.
|
||||
However, there is no guarantee about stack space.
|
||||
To push anything on the stack,
|
||||
the panic function must first check the available space (see <a href="#4.2">§4.2</a>).
|
||||
|
@ -2974,8 +2994,11 @@ by looking only at its arguments
|
|||
The third field, <code>x</code>,
|
||||
tells whether the function may raise errors:
|
||||
'<code>-</code>' means the function never raises any error;
|
||||
'<code>m</code>' means the function may raise memory errors;
|
||||
'<code>e</code>' means the function may raise errors;
|
||||
'<code>m</code>' means the function may raise out-of-memory errors
|
||||
and errors running a <code>__gc</code> metamethod;
|
||||
'<code>e</code>' means the function may raise any errors
|
||||
(it can run arbitrary Lua code,
|
||||
either directly or through metamethods);
|
||||
'<code>v</code>' means the function may raise an error on purpose.
|
||||
|
||||
|
||||
|
@ -3102,10 +3125,10 @@ The value of <code>op</code> must be one of the following constants:
|
|||
<li><b><a name="pdf-LUA_OPMOD"><code>LUA_OPMOD</code></a>: </b> performs modulo (<code>%</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPPOW"><code>LUA_OPPOW</code></a>: </b> performs exponentiation (<code>^</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPUNM"><code>LUA_OPUNM</code></a>: </b> performs mathematical negation (unary <code>-</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPBNOT"><code>LUA_OPBNOT</code></a>: </b> performs bitwise negation (<code>~</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPBAND"><code>LUA_OPBAND</code></a>: </b> performs bitwise and (<code>&</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPBOR"><code>LUA_OPBOR</code></a>: </b> performs bitwise or (<code>|</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPBXOR"><code>LUA_OPBXOR</code></a>: </b> performs bitwise exclusive or (<code>~</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPBNOT"><code>LUA_OPBNOT</code></a>: </b> performs bitwise NOT (<code>~</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPBAND"><code>LUA_OPBAND</code></a>: </b> performs bitwise AND (<code>&</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPBOR"><code>LUA_OPBOR</code></a>: </b> performs bitwise OR (<code>|</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPBXOR"><code>LUA_OPBXOR</code></a>: </b> performs bitwise exclusive OR (<code>~</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPSHL"><code>LUA_OPSHL</code></a>: </b> performs left shift (<code><<</code>)</li>
|
||||
<li><b><a name="pdf-LUA_OPSHR"><code>LUA_OPSHR</code></a>: </b> performs right shift (<code>>></code>)</li>
|
||||
|
||||
|
@ -3424,7 +3447,7 @@ and therefore never returns
|
|||
|
||||
|
||||
<hr><h3><a name="lua_gc"><code>lua_gc</code></a></h3><p>
|
||||
<span class="apii">[-0, +0, <em>e</em>]</span>
|
||||
<span class="apii">[-0, +0, <em>m</em>]</span>
|
||||
<pre>int lua_gc (lua_State *L, int what, int data);</pre>
|
||||
|
||||
<p>
|
||||
|
@ -3919,7 +3942,7 @@ The return values of <code>lua_load</code> are:
|
|||
syntax error during precompilation;</li>
|
||||
|
||||
<li><b><a href="#pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>: </b>
|
||||
memory allocation error;</li>
|
||||
memory allocation (out-of-memory) error;</li>
|
||||
|
||||
<li><b><a href="#pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>: </b>
|
||||
error while running a <code>__gc</code> metamethod.
|
||||
|
@ -4128,7 +4151,7 @@ If there are no errors during the call,
|
|||
<a href="#lua_pcall"><code>lua_pcall</code></a> behaves exactly like <a href="#lua_call"><code>lua_call</code></a>.
|
||||
However, if there is any error,
|
||||
<a href="#lua_pcall"><code>lua_pcall</code></a> catches it,
|
||||
pushes a single value on the stack (the error message),
|
||||
pushes a single value on the stack (the error object),
|
||||
and returns an error code.
|
||||
Like <a href="#lua_call"><code>lua_call</code></a>,
|
||||
<a href="#lua_pcall"><code>lua_pcall</code></a> always removes the function
|
||||
|
@ -4137,20 +4160,20 @@ and its arguments from the stack.
|
|||
|
||||
<p>
|
||||
If <code>msgh</code> is 0,
|
||||
then the error message returned on the stack
|
||||
is exactly the original error message.
|
||||
then the error object returned on the stack
|
||||
is exactly the original error object.
|
||||
Otherwise, <code>msgh</code> is the stack index of a
|
||||
<em>message handler</em>.
|
||||
(This index cannot be a pseudo-index.)
|
||||
In case of runtime errors,
|
||||
this function will be called with the error message
|
||||
and its return value will be the message
|
||||
this function will be called with the error object
|
||||
and its return value will be the object
|
||||
returned on the stack by <a href="#lua_pcall"><code>lua_pcall</code></a>.
|
||||
|
||||
|
||||
<p>
|
||||
Typically, the message handler is used to add more debug
|
||||
information to the error message, such as a stack traceback.
|
||||
information to the error object, such as a stack traceback.
|
||||
Such information cannot be gathered after the return of <a href="#lua_pcall"><code>lua_pcall</code></a>,
|
||||
since by then the stack has unwound.
|
||||
|
||||
|
@ -4284,7 +4307,7 @@ and return its results (see <a href="#lua_CFunction"><code>lua_CFunction</code><
|
|||
|
||||
|
||||
<hr><h3><a name="lua_pushfstring"><code>lua_pushfstring</code></a></h3><p>
|
||||
<span class="apii">[-0, +1, <em>m</em>]</span>
|
||||
<span class="apii">[-0, +1, <em>e</em>]</span>
|
||||
<pre>const char *lua_pushfstring (lua_State *L, const char *fmt, ...);</pre>
|
||||
|
||||
<p>
|
||||
|
@ -4317,6 +4340,12 @@ The conversion specifiers can only be
|
|||
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Unlike other push functions,
|
||||
this function checks for the stack space it needs,
|
||||
including the slot for its result.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -4486,7 +4515,7 @@ instead of a variable number of arguments.
|
|||
<p>
|
||||
Returns 1 if the two values in indices <code>index1</code> and
|
||||
<code>index2</code> are primitively equal
|
||||
(that is, without calling metamethods).
|
||||
(that is, without calling the <code>__eq</code> metamethod).
|
||||
Otherwise returns 0.
|
||||
Also returns 0 if any of the indices are not valid.
|
||||
|
||||
|
@ -4513,8 +4542,8 @@ Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw
|
|||
<p>
|
||||
Pushes onto the stack the value <code>t[n]</code>,
|
||||
where <code>t</code> is the table at the given index.
|
||||
The access is raw;
|
||||
that is, it does not invoke metamethods.
|
||||
The access is raw,
|
||||
that is, it does not invoke the <code>__index</code> metamethod.
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -4533,7 +4562,7 @@ Pushes onto the stack the value <code>t[k]</code>,
|
|||
where <code>t</code> is the table at the given index and
|
||||
<code>k</code> is the pointer <code>p</code> represented as a light userdata.
|
||||
The access is raw;
|
||||
that is, it does not invoke metamethods.
|
||||
that is, it does not invoke the <code>__index</code> metamethod.
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -4584,8 +4613,8 @@ and <code>v</code> is the value at the top of the stack.
|
|||
|
||||
<p>
|
||||
This function pops the value from the stack.
|
||||
The assignment is raw;
|
||||
that is, it does not invoke metamethods.
|
||||
The assignment is raw,
|
||||
that is, it does not invoke the <code>__newindex</code> metamethod.
|
||||
|
||||
|
||||
|
||||
|
@ -4604,8 +4633,8 @@ and <code>v</code> is the value at the top of the stack.
|
|||
|
||||
<p>
|
||||
This function pops the value from the stack.
|
||||
The assignment is raw;
|
||||
that is, it does not invoke metamethods.
|
||||
The assignment is raw,
|
||||
that is, it does not invoke <code>__newindex</code> metamethod.
|
||||
|
||||
|
||||
|
||||
|
@ -4704,7 +4733,7 @@ or an error code in case of errors (see <a href="#lua_pcall"><code>lua_pcall</co
|
|||
In case of errors,
|
||||
the stack is not unwound,
|
||||
so you can use the debug API over it.
|
||||
The error message is on the top of the stack.
|
||||
The error object is on the top of the stack.
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -5179,11 +5208,13 @@ the running function (see <a href="#4.4">§4.4</a>).
|
|||
|
||||
|
||||
<hr><h3><a name="lua_version"><code>lua_version</code></a></h3><p>
|
||||
<span class="apii">[-0, +0, <em>v</em>]</span>
|
||||
<span class="apii">[-0, +0, –]</span>
|
||||
<pre>const lua_Number *lua_version (lua_State *L);</pre>
|
||||
|
||||
<p>
|
||||
Returns the address of the version number stored in the Lua core.
|
||||
Returns the address of the version number
|
||||
(a C static variable)
|
||||
stored in the Lua core.
|
||||
When called with a valid <a href="#lua_State"><code>lua_State</code></a>,
|
||||
returns the address of the version used to create that state.
|
||||
When called with <code>NULL</code>,
|
||||
|
@ -5287,9 +5318,9 @@ when the coroutine eventually resumes,
|
|||
it continues executing the continuation function.
|
||||
However, there is one special case,
|
||||
which is when this function is called
|
||||
from inside a line hook (see <a href="#4.9">§4.9</a>).
|
||||
from inside a line or a count hook (see <a href="#4.9">§4.9</a>).
|
||||
In that case, <code>lua_yieldk</code> should be called with no continuation
|
||||
(probably in the form of <a href="#lua_yield"><code>lua_yield</code></a>),
|
||||
(probably in the form of <a href="#lua_yield"><code>lua_yield</code></a>) and no results,
|
||||
and the hook should return immediately after the call.
|
||||
Lua will yield and,
|
||||
when the coroutine resumes again,
|
||||
|
@ -5704,7 +5735,7 @@ Sets the debugging hook function.
|
|||
<p>
|
||||
Argument <code>f</code> is the hook function.
|
||||
<code>mask</code> specifies on which events the hook will be called:
|
||||
it is formed by a bitwise or of the constants
|
||||
it is formed by a bitwise OR of the constants
|
||||
<a name="pdf-LUA_MASKCALL"><code>LUA_MASKCALL</code></a>,
|
||||
<a name="pdf-LUA_MASKRET"><code>LUA_MASKRET</code></a>,
|
||||
<a name="pdf-LUA_MASKLINE"><code>LUA_MASKLINE</code></a>,
|
||||
|
@ -6256,7 +6287,7 @@ returns the userdata address (see <a href="#lua_touserdata"><code>lua_touserdata
|
|||
|
||||
|
||||
<hr><h3><a name="luaL_checkversion"><code>luaL_checkversion</code></a></h3><p>
|
||||
<span class="apii">[-0, +0, –]</span>
|
||||
<span class="apii">[-0, +0, <em>v</em>]</span>
|
||||
<pre>void luaL_checkversion (lua_State *L);</pre>
|
||||
|
||||
<p>
|
||||
|
@ -6472,7 +6503,7 @@ The string <code>mode</code> works as in function <a href="#lua_load"><code>lua_
|
|||
|
||||
|
||||
<hr><h3><a name="luaL_loadfile"><code>luaL_loadfile</code></a></h3><p>
|
||||
<span class="apii">[-0, +1, <em>e</em>]</span>
|
||||
<span class="apii">[-0, +1, <em>m</em>]</span>
|
||||
<pre>int luaL_loadfile (lua_State *L, const char *filename);</pre>
|
||||
|
||||
<p>
|
||||
|
@ -6483,7 +6514,7 @@ Equivalent to <a href="#luaL_loadfilex"><code>luaL_loadfilex</code></a> with <co
|
|||
|
||||
|
||||
<hr><h3><a name="luaL_loadfilex"><code>luaL_loadfilex</code></a></h3><p>
|
||||
<span class="apii">[-0, +1, <em>e</em>]</span>
|
||||
<span class="apii">[-0, +1, <em>m</em>]</span>
|
||||
<pre>int luaL_loadfilex (lua_State *L, const char *filename,
|
||||
const char *mode);</pre>
|
||||
|
||||
|
@ -6634,6 +6665,27 @@ Opens all standard Lua libraries into the given state.
|
|||
|
||||
|
||||
|
||||
<hr><h3><a name="luaL_opt"><code>luaL_opt</code></a></h3><p>
|
||||
<span class="apii">[-0, +0, <em>e</em>]</span>
|
||||
<pre>T luaL_opt (L, func, arg, dflt);</pre>
|
||||
|
||||
<p>
|
||||
This macro is defined as follows:
|
||||
|
||||
<pre>
|
||||
(lua_isnoneornil(L,(arg)) ? (dflt) : func(L,(arg)))
|
||||
</pre><p>
|
||||
In words, if the argument <code>arg</code> is nil or absent,
|
||||
the macro results in the default <code>dflt</code>.
|
||||
Otherwise, it results in the result of calling <code>func</code>
|
||||
with the state <code>L</code> and the argument index <code>arg</code> as
|
||||
parameters.
|
||||
Note that it evaluates the expression <code>dflt</code> only if needed.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<hr><h3><a name="luaL_optinteger"><code>luaL_optinteger</code></a></h3><p>
|
||||
<span class="apii">[-0, +0, <em>v</em>]</span>
|
||||
<pre>lua_Integer luaL_optinteger (lua_State *L,
|
||||
|
@ -6931,7 +6983,7 @@ the function also sets <code>*len</code> with the string length.
|
|||
|
||||
|
||||
<p>
|
||||
If the value has a metatable with a <code>"__tostring"</code> field,
|
||||
If the value has a metatable with a <code>__tostring</code> field,
|
||||
then <code>luaL_tolstring</code> calls the corresponding metamethod
|
||||
with the value as argument,
|
||||
and uses the result of the call as its result.
|
||||
|
@ -7220,7 +7272,7 @@ nor vice versa.
|
|||
<p>
|
||||
If <code>object</code> does not have a metatable, returns <b>nil</b>.
|
||||
Otherwise,
|
||||
if the object's metatable has a <code>"__metatable"</code> field,
|
||||
if the object's metatable has a <code>__metatable</code> field,
|
||||
returns the associated value.
|
||||
Otherwise, returns the metatable of the given object.
|
||||
|
||||
|
@ -7424,7 +7476,7 @@ use <a href="#pdf-string.format"><code>string.format</code></a> and <a href="#pd
|
|||
<p>
|
||||
<hr><h3><a name="pdf-rawequal"><code>rawequal (v1, v2)</code></a></h3>
|
||||
Checks whether <code>v1</code> is equal to <code>v2</code>,
|
||||
without invoking any metamethod.
|
||||
without invoking the <code>__eq</code> metamethod.
|
||||
Returns a boolean.
|
||||
|
||||
|
||||
|
@ -7433,7 +7485,7 @@ Returns a boolean.
|
|||
<p>
|
||||
<hr><h3><a name="pdf-rawget"><code>rawget (table, index)</code></a></h3>
|
||||
Gets the real value of <code>table[index]</code>,
|
||||
without invoking any metamethod.
|
||||
without invoking the <code>__index</code> metamethod.
|
||||
<code>table</code> must be a table;
|
||||
<code>index</code> may be any value.
|
||||
|
||||
|
@ -7444,7 +7496,7 @@ without invoking any metamethod.
|
|||
<hr><h3><a name="pdf-rawlen"><code>rawlen (v)</code></a></h3>
|
||||
Returns the length of the object <code>v</code>,
|
||||
which must be a table or a string,
|
||||
without invoking any metamethod.
|
||||
without invoking the <code>__len</code> metamethod.
|
||||
Returns an integer.
|
||||
|
||||
|
||||
|
@ -7453,7 +7505,7 @@ Returns an integer.
|
|||
<p>
|
||||
<hr><h3><a name="pdf-rawset"><code>rawset (table, index, value)</code></a></h3>
|
||||
Sets the real value of <code>table[index]</code> to <code>value</code>,
|
||||
without invoking any metamethod.
|
||||
without invoking the <code>__newindex</code> metamethod.
|
||||
<code>table</code> must be a table,
|
||||
<code>index</code> any value different from <b>nil</b> and NaN,
|
||||
and <code>value</code> any Lua value.
|
||||
|
@ -7489,7 +7541,7 @@ Sets the metatable for the given table.
|
|||
you must use the debug library (<a href="#6.10">§6.10</a>).)
|
||||
If <code>metatable</code> is <b>nil</b>,
|
||||
removes the metatable of the given table.
|
||||
If the original metatable has a <code>"__metatable"</code> field,
|
||||
If the original metatable has a <code>__metatable</code> field,
|
||||
raises an error.
|
||||
|
||||
|
||||
|
@ -7541,7 +7593,7 @@ use <a href="#pdf-string.format"><code>string.format</code></a>.)
|
|||
|
||||
|
||||
<p>
|
||||
If the metatable of <code>v</code> has a <code>"__tostring"</code> field,
|
||||
If the metatable of <code>v</code> has a <code>__tostring</code> field,
|
||||
then <code>tostring</code> calls the corresponding value
|
||||
with <code>v</code> as argument,
|
||||
and uses the result of the call as its result.
|
||||
|
@ -8184,6 +8236,9 @@ The only differences are that the options/modifiers
|
|||
<code>*</code>, <code>h</code>, <code>L</code>, <code>l</code>, <code>n</code>,
|
||||
and <code>p</code> are not supported
|
||||
and that there is an extra option, <code>q</code>.
|
||||
|
||||
|
||||
<p>
|
||||
The <code>q</code> option formats a string between double quotes,
|
||||
using escape sequences when necessary to ensure that
|
||||
it can safely be read back by the Lua interpreter.
|
||||
|
@ -8206,7 +8261,12 @@ Options
|
|||
Options <code>c</code>, <code>d</code>,
|
||||
<code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code>
|
||||
expect an integer.
|
||||
Option <code>q</code> expects a string.
|
||||
When Lua is compiled with a C89 compiler,
|
||||
options <code>A</code> and <code>a</code> (hexadecimal floats)
|
||||
do not support any modifier (flags, width, length).
|
||||
|
||||
|
||||
<p>
|
||||
Option <code>s</code> expects a string;
|
||||
if its argument is not a string,
|
||||
it is converted to one following the same rules of <a href="#pdf-tostring"><code>tostring</code></a>.
|
||||
|
@ -8214,12 +8274,6 @@ If the option has any modifier (flags, width, length),
|
|||
the string argument should not contain embedded zeros.
|
||||
|
||||
|
||||
<p>
|
||||
When Lua is compiled with a non-C99 compiler,
|
||||
options <code>A</code> and <code>a</code> (hexadecimal floats)
|
||||
do not support any modifier (flags, width, length).
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -8547,6 +8601,14 @@ and <code>[0-7%l%-]</code> represents the octal digits plus
|
|||
the lowercase letters plus the '<code>-</code>' character.
|
||||
|
||||
|
||||
<p>
|
||||
You can put a closing square bracket in a set
|
||||
by positioning it as the first character in the set.
|
||||
You can put an hyphen in a set
|
||||
by positioning it as the first or the last character in the set.
|
||||
(You can also use an escape for both cases.)
|
||||
|
||||
|
||||
<p>
|
||||
The interaction between ranges and classes is not defined.
|
||||
Therefore, patterns like <code>[%a-z]</code> or <code>[a-%%]</code>
|
||||
|
@ -8925,8 +8987,8 @@ of list <code>t</code>.
|
|||
|
||||
|
||||
<p>
|
||||
Moves elements from table <code>a1</code> to table <code>a2</code>.
|
||||
This function performs the equivalent to the following
|
||||
Moves elements from table <code>a1</code> to table <code>a2</code>,
|
||||
performing the equivalent to the following
|
||||
multiple assignment:
|
||||
<code>a2[t],··· = a1[f],···,a1[e]</code>.
|
||||
The default for <code>a2</code> is <code>a1</code>.
|
||||
|
@ -8934,6 +8996,10 @@ The destination range can overlap with the source range.
|
|||
The number of elements to be moved must fit in a Lua integer.
|
||||
|
||||
|
||||
<p>
|
||||
Returns the destination table <code>a2</code>.
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -9457,8 +9523,8 @@ instead of returning an error code.
|
|||
<p>
|
||||
This function opens a file,
|
||||
in the mode specified in the string <code>mode</code>.
|
||||
It returns a new file handle,
|
||||
or, in case of errors, <b>nil</b> plus an error message.
|
||||
In case of success,
|
||||
it returns a new file handle.
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -9523,7 +9589,8 @@ Equivalent to <code>io.input():read(···)</code>.
|
|||
|
||||
|
||||
<p>
|
||||
Returns a handle for a temporary file.
|
||||
In case of success,
|
||||
returns a handle for a temporary file.
|
||||
This file is opened in update mode
|
||||
and it is automatically removed when the program ends.
|
||||
|
||||
|
@ -9801,8 +9868,8 @@ if <code>format</code> is the string "<code>*t</code>",
|
|||
then <code>date</code> returns a table with the following fields:
|
||||
<code>year</code>, <code>month</code> (1–12), <code>day</code> (1–31),
|
||||
<code>hour</code> (0–23), <code>min</code> (0–59), <code>sec</code> (0–61),
|
||||
<code>wday</code> (weekday, Sunday is 1),
|
||||
<code>yday</code> (day of the year),
|
||||
<code>wday</code> (weekday, 1–7, Sunday is 1),
|
||||
<code>yday</code> (day of the year, 1–366),
|
||||
and <code>isdst</code> (daylight saving flag, a boolean).
|
||||
This last field may be absent
|
||||
if the information is not available.
|
||||
|
@ -10504,6 +10571,14 @@ the interpreter waits for its completion
|
|||
by issuing a different prompt.
|
||||
|
||||
|
||||
<p>
|
||||
If the global variable <a name="pdf-_PROMPT"><code>_PROMPT</code></a> contains a string,
|
||||
then its value is used as the prompt.
|
||||
Similarly, if the global variable <a name="pdf-_PROMPT2"><code>_PROMPT2</code></a> contains a string,
|
||||
its value is used as the secondary prompt
|
||||
(issued during incomplete statements).
|
||||
|
||||
|
||||
<p>
|
||||
In case of unprotected errors in the script,
|
||||
the interpreter reports the error to the standard error stream.
|
||||
|
@ -10825,10 +10900,10 @@ and LiteralString, see <a href="#3.1">§3.1</a>.)
|
|||
|
||||
<P CLASS="footer">
|
||||
Last update:
|
||||
Wed Nov 25 15:19:10 BRST 2015
|
||||
Mon May 30 13:11:08 BRT 2016
|
||||
</P>
|
||||
<!--
|
||||
Last change: revised for Lua 5.3.2
|
||||
Last change: revised for Lua 5.3.3
|
||||
-->
|
||||
|
||||
</body></html>
|
||||
|
|
|
@ -276,7 +276,7 @@ Here are the other changes introduced in Lua 5.3:
|
|||
<H3>Language</H3>
|
||||
<UL>
|
||||
<LI> userdata can have any Lua value as uservalue
|
||||
<LI> integer division
|
||||
<LI> floor division
|
||||
<LI> more flexible rules for some metamethods
|
||||
</UL>
|
||||
|
||||
|
@ -328,7 +328,7 @@ For details, see
|
|||
<A HREF="http://www.lua.org/license.html">this</A>.
|
||||
|
||||
<BLOCKQUOTE STYLE="padding-bottom: 0em">
|
||||
Copyright © 1994–2015 Lua.org, PUC-Rio.
|
||||
Copyright © 1994–2016 Lua.org, PUC-Rio.
|
||||
|
||||
<P>
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
@ -355,10 +355,10 @@ THE SOFTWARE.
|
|||
|
||||
<P CLASS="footer">
|
||||
Last update:
|
||||
Mon Jun 1 21:48:24 BRT 2015
|
||||
Tue Feb 2 22:25:27 BRST 2016
|
||||
</P>
|
||||
<!--
|
||||
Last change: revised for Lua 5.3.1
|
||||
Last change: revised for Lua 5.3.3
|
||||
-->
|
||||
|
||||
</BODY>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
PLAT= none
|
||||
|
||||
CC= gcc -std=gnu99
|
||||
CFLAGS= -O2 -Wall -Wextra $(SYSCFLAGS) $(MYCFLAGS)
|
||||
CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS)
|
||||
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
|
||||
LIBS= -lm $(SYSLIBS) $(MYLIBS)
|
||||
|
||||
|
@ -26,7 +26,7 @@ MYOBJS=
|
|||
|
||||
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
|
||||
|
||||
PLATS= aix bsd c89 freebsd generic linux macosx mingw posix posix32bit solaris
|
||||
PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
|
||||
|
||||
LUA_A= liblua.a
|
||||
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
|
||||
|
@ -119,10 +119,7 @@ mingw:
|
|||
$(MAKE) "LUAC_T=luac.exe" luac.exe
|
||||
|
||||
posix:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -fPIC -DLUA_USE_DLOPEN" SYSLIBS="-ldl"
|
||||
|
||||
posix32bit:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-m32 -DLUA_USE_POSIX -fPIC -DLUA_USE_DLOPEN" SYSLDFLAGS="-m32" SYSLIBS="-ldl"
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
|
||||
|
||||
solaris:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -D_REENTRANT" SYSLIBS="-ldl"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lapi.c,v 2.257 2015/11/02 18:48:07 roberto Exp $
|
||||
** $Id: lapi.c,v 2.259 2016/02/29 14:27:14 roberto Exp $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -378,9 +378,9 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
|
|||
return NULL;
|
||||
}
|
||||
lua_lock(L); /* 'luaO_tostring' may create a new string */
|
||||
luaO_tostring(L, o);
|
||||
luaC_checkGC(L);
|
||||
o = index2addr(L, idx); /* previous call may reallocate the stack */
|
||||
luaO_tostring(L, o);
|
||||
lua_unlock(L);
|
||||
}
|
||||
if (len != NULL)
|
||||
|
@ -479,10 +479,10 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
|
|||
LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
||||
TString *ts;
|
||||
lua_lock(L);
|
||||
luaC_checkGC(L);
|
||||
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
|
||||
setsvalue2s(L, L->top, ts);
|
||||
api_incr_top(L);
|
||||
luaC_checkGC(L);
|
||||
lua_unlock(L);
|
||||
return getstr(ts);
|
||||
}
|
||||
|
@ -494,12 +494,12 @@ LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
|
|||
setnilvalue(L->top);
|
||||
else {
|
||||
TString *ts;
|
||||
luaC_checkGC(L);
|
||||
ts = luaS_new(L, s);
|
||||
setsvalue2s(L, L->top, ts);
|
||||
s = getstr(ts); /* internal copy's address */
|
||||
}
|
||||
api_incr_top(L);
|
||||
luaC_checkGC(L);
|
||||
lua_unlock(L);
|
||||
return s;
|
||||
}
|
||||
|
@ -509,8 +509,8 @@ LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
|
|||
va_list argp) {
|
||||
const char *ret;
|
||||
lua_lock(L);
|
||||
luaC_checkGC(L);
|
||||
ret = luaO_pushvfstring(L, fmt, argp);
|
||||
luaC_checkGC(L);
|
||||
lua_unlock(L);
|
||||
return ret;
|
||||
}
|
||||
|
@ -520,10 +520,10 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
|
|||
const char *ret;
|
||||
va_list argp;
|
||||
lua_lock(L);
|
||||
luaC_checkGC(L);
|
||||
va_start(argp, fmt);
|
||||
ret = luaO_pushvfstring(L, fmt, argp);
|
||||
va_end(argp);
|
||||
luaC_checkGC(L);
|
||||
lua_unlock(L);
|
||||
return ret;
|
||||
}
|
||||
|
@ -538,7 +538,6 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
|||
CClosure *cl;
|
||||
api_checknelems(L, n);
|
||||
api_check(L, n <= MAXUPVAL, "upvalue index too large");
|
||||
luaC_checkGC(L);
|
||||
cl = luaF_newCclosure(L, n);
|
||||
cl->f = fn;
|
||||
L->top -= n;
|
||||
|
@ -549,6 +548,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
|||
setclCvalue(L, L->top, cl);
|
||||
}
|
||||
api_incr_top(L);
|
||||
luaC_checkGC(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
@ -585,16 +585,16 @@ LUA_API int lua_pushthread (lua_State *L) {
|
|||
|
||||
|
||||
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
||||
const TValue *aux;
|
||||
const TValue *slot;
|
||||
TString *str = luaS_new(L, k);
|
||||
if (luaV_fastget(L, t, str, aux, luaH_getstr)) {
|
||||
setobj2s(L, L->top, aux);
|
||||
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
||||
setobj2s(L, L->top, slot);
|
||||
api_incr_top(L);
|
||||
}
|
||||
else {
|
||||
setsvalue2s(L, L->top, str);
|
||||
api_incr_top(L);
|
||||
luaV_finishget(L, t, L->top - 1, L->top - 1, aux);
|
||||
luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
|
||||
}
|
||||
lua_unlock(L);
|
||||
return ttnov(L->top - 1);
|
||||
|
@ -626,17 +626,17 @@ LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
|
|||
|
||||
LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
|
||||
StkId t;
|
||||
const TValue *aux;
|
||||
const TValue *slot;
|
||||
lua_lock(L);
|
||||
t = index2addr(L, idx);
|
||||
if (luaV_fastget(L, t, n, aux, luaH_getint)) {
|
||||
setobj2s(L, L->top, aux);
|
||||
if (luaV_fastget(L, t, n, slot, luaH_getint)) {
|
||||
setobj2s(L, L->top, slot);
|
||||
api_incr_top(L);
|
||||
}
|
||||
else {
|
||||
setivalue(L->top, n);
|
||||
api_incr_top(L);
|
||||
luaV_finishget(L, t, L->top - 1, L->top - 1, aux);
|
||||
luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
|
||||
}
|
||||
lua_unlock(L);
|
||||
return ttnov(L->top - 1);
|
||||
|
@ -683,12 +683,12 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
|
|||
LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
|
||||
Table *t;
|
||||
lua_lock(L);
|
||||
luaC_checkGC(L);
|
||||
t = luaH_new(L);
|
||||
sethvalue(L, L->top, t);
|
||||
api_incr_top(L);
|
||||
if (narray > 0 || nrec > 0)
|
||||
luaH_resize(L, t, narray, nrec);
|
||||
luaC_checkGC(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
@ -740,15 +740,15 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) {
|
|||
** t[k] = value at the top of the stack (where 'k' is a string)
|
||||
*/
|
||||
static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
|
||||
const TValue *aux;
|
||||
const TValue *slot;
|
||||
TString *str = luaS_new(L, k);
|
||||
api_checknelems(L, 1);
|
||||
if (luaV_fastset(L, t, str, aux, luaH_getstr, L->top - 1))
|
||||
if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1))
|
||||
L->top--; /* pop value */
|
||||
else {
|
||||
setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
|
||||
api_incr_top(L);
|
||||
luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
|
||||
luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
|
||||
L->top -= 2; /* pop value and key */
|
||||
}
|
||||
lua_unlock(L); /* lock done by caller */
|
||||
|
@ -781,16 +781,16 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
|
|||
|
||||
LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
|
||||
StkId t;
|
||||
const TValue *aux;
|
||||
const TValue *slot;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
t = index2addr(L, idx);
|
||||
if (luaV_fastset(L, t, n, aux, luaH_getint, L->top - 1))
|
||||
if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1))
|
||||
L->top--; /* pop value */
|
||||
else {
|
||||
setivalue(L->top, n);
|
||||
api_incr_top(L);
|
||||
luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
|
||||
luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
|
||||
L->top -= 2; /* pop value and key */
|
||||
}
|
||||
lua_unlock(L);
|
||||
|
@ -1140,7 +1140,6 @@ LUA_API void lua_concat (lua_State *L, int n) {
|
|||
lua_lock(L);
|
||||
api_checknelems(L, n);
|
||||
if (n >= 2) {
|
||||
luaC_checkGC(L);
|
||||
luaV_concat(L, n);
|
||||
}
|
||||
else if (n == 0) { /* push empty string */
|
||||
|
@ -1148,6 +1147,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
|
|||
api_incr_top(L);
|
||||
}
|
||||
/* else n == 1; nothing to do */
|
||||
luaC_checkGC(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
@ -1183,10 +1183,10 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
|
|||
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
|
||||
Udata *u;
|
||||
lua_lock(L);
|
||||
luaC_checkGC(L);
|
||||
u = luaS_newudata(L, size);
|
||||
setuvalue(L, L->top, u);
|
||||
api_incr_top(L);
|
||||
luaC_checkGC(L);
|
||||
lua_unlock(L);
|
||||
return getudatamem(u);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lauxlib.c,v 1.284 2015/11/19 19:16:22 roberto Exp $
|
||||
** $Id: lauxlib.c,v 1.286 2016/01/08 15:33:09 roberto Exp $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -17,7 +17,8 @@
|
|||
#include <string.h>
|
||||
|
||||
|
||||
/* This file uses only the official API of Lua.
|
||||
/*
|
||||
** This file uses only the official API of Lua.
|
||||
** Any function declared here could be written as an application function.
|
||||
*/
|
||||
|
||||
|
@ -198,6 +199,10 @@ static void tag_error (lua_State *L, int arg, int tag) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
** The use of 'lua_pushfstring' ensures this function does not
|
||||
** need reserved stack space when called.
|
||||
*/
|
||||
LUALIB_API void luaL_where (lua_State *L, int level) {
|
||||
lua_Debug ar;
|
||||
if (lua_getstack(L, level, &ar)) { /* check function at level */
|
||||
|
@ -207,10 +212,15 @@ LUALIB_API void luaL_where (lua_State *L, int level) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
lua_pushliteral(L, ""); /* else, no information available... */
|
||||
lua_pushfstring(L, ""); /* else, no information available... */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Again, the use of 'lua_pushvfstring' ensures this function does
|
||||
** not need reserved stack space when called. (At worst, it generates
|
||||
** an error with "stack overflow" instead of the given message.)
|
||||
*/
|
||||
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
|
@ -349,10 +359,15 @@ LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
** Ensures the stack has at least 'space' extra slots, raising an error
|
||||
** if it cannot fulfill the request. (The error handling needs a few
|
||||
** extra slots to format the error message. In case of an error without
|
||||
** this extra space, Lua will generate the same 'stack overflow' error,
|
||||
** but without 'msg'.)
|
||||
*/
|
||||
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
|
||||
/* keep some extra space to run error routines, if needed */
|
||||
const int extra = LUA_MINSTACK;
|
||||
if (!lua_checkstack(L, space + extra)) {
|
||||
if (!lua_checkstack(L, space)) {
|
||||
if (msg)
|
||||
luaL_error(L, "stack overflow (%s)", msg);
|
||||
else
|
||||
|
@ -678,7 +693,7 @@ static int skipcomment (LoadF *lf, int *cp) {
|
|||
if (c == '#') { /* first line is a comment (Unix exec. file)? */
|
||||
do { /* skip first line */
|
||||
c = getc(lf->f);
|
||||
} while (c != EOF && c != '\n') ;
|
||||
} while (c != EOF && c != '\n');
|
||||
*cp = getc(lf->f); /* skip end-of-line, if present */
|
||||
return 1; /* there was a comment */
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lbaselib.c,v 1.312 2015/10/29 15:21:04 roberto Exp $
|
||||
** $Id: lbaselib.c,v 1.313 2016/04/11 19:18:40 roberto Exp $
|
||||
** Basic library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -102,8 +102,8 @@ static int luaB_tonumber (lua_State *L) {
|
|||
static int luaB_error (lua_State *L) {
|
||||
int level = (int)luaL_optinteger(L, 2, 1);
|
||||
lua_settop(L, 1);
|
||||
if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
|
||||
luaL_where(L, level);
|
||||
if (lua_type(L, 1) == LUA_TSTRING && level > 0) {
|
||||
luaL_where(L, level); /* add extra information */
|
||||
lua_pushvalue(L, 1);
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
|
@ -251,9 +251,8 @@ static int ipairsaux (lua_State *L) {
|
|||
|
||||
|
||||
/*
|
||||
** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
|
||||
** traverse a table, depending on whether the table has metamethods
|
||||
** that can affect the traversal.
|
||||
** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
|
||||
** (The given "table" may not be a table.)
|
||||
*/
|
||||
static int luaB_ipairs (lua_State *L) {
|
||||
#if defined(LUA_COMPAT_IPAIRS)
|
||||
|
|
694
lua/src/lcode.c
694
lua/src/lcode.c
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $
|
||||
** $Id: lcode.h,v 1.64 2016/01/05 16:22:37 roberto Exp $
|
||||
** Code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -40,7 +40,8 @@ typedef enum BinOpr {
|
|||
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
|
||||
|
||||
|
||||
#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
|
||||
/* get (pointer to) instruction of given 'expdesc' */
|
||||
#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info])
|
||||
|
||||
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp $
|
||||
** $Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 roberto Exp $
|
||||
** Coroutine Library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -75,7 +75,7 @@ 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) {
|
||||
if (lua_isstring(L, -1)) { /* error object is a string? */
|
||||
if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */
|
||||
luaL_where(L, 1); /* add extra info */
|
||||
lua_insert(L, -2);
|
||||
lua_concat(L, 2);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ldebug.c,v 2.117 2015/11/02 18:48:07 roberto Exp $
|
||||
** $Id: ldebug.c,v 2.120 2016/03/31 19:01:21 roberto Exp $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -69,7 +69,13 @@ static void swapextra (lua_State *L) {
|
|||
|
||||
|
||||
/*
|
||||
** this function can be called asynchronous (e.g. during a signal)
|
||||
** This function can be called asynchronously (e.g. during a signal).
|
||||
** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
|
||||
** 'resethookcount') are for debug only, and it is no problem if they
|
||||
** get arbitrary values (causes at most one wrong hook call). 'hookmask'
|
||||
** is an atomic value. We assume that pointers are atomic too (e.g., gcc
|
||||
** ensures that for all platforms where it runs). Moreover, 'hook' is
|
||||
** always checked before being called (see 'luaD_hook').
|
||||
*/
|
||||
LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
|
||||
if (func == NULL || mask == 0) { /* turn off hooks? */
|
||||
|
@ -558,7 +564,7 @@ static const char *varinfo (lua_State *L, const TValue *o) {
|
|||
|
||||
|
||||
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
|
||||
const char *t = objtypename(o);
|
||||
const char *t = luaT_objtypename(L, o);
|
||||
luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
|
||||
}
|
||||
|
||||
|
@ -590,9 +596,9 @@ l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
|
|||
|
||||
|
||||
l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
|
||||
const char *t1 = objtypename(p1);
|
||||
const char *t2 = objtypename(p2);
|
||||
if (t1 == t2)
|
||||
const char *t1 = luaT_objtypename(L, p1);
|
||||
const char *t2 = luaT_objtypename(L, p2);
|
||||
if (strcmp(t1, t2) == 0)
|
||||
luaG_runerror(L, "attempt to compare two %s values", t1);
|
||||
else
|
||||
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ldo.c,v 2.150 2015/11/19 19:16:22 roberto Exp $
|
||||
** $Id: ldo.c,v 2.151 2015/12/16 16:40:07 roberto Exp $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -242,9 +242,14 @@ void luaD_inctop (lua_State *L) {
|
|||
/* }================================================================== */
|
||||
|
||||
|
||||
/*
|
||||
** Call a hook for the given event. Make sure there is a hook to be
|
||||
** called. (Both 'L->hook' and 'L->hookmask', which triggers this
|
||||
** function, can be changed asynchronously by signals.)
|
||||
*/
|
||||
void luaD_hook (lua_State *L, int event, int line) {
|
||||
lua_Hook hook = L->hook;
|
||||
if (hook && L->allowhook) {
|
||||
if (hook && L->allowhook) { /* make sure there is a hook */
|
||||
CallInfo *ci = L->ci;
|
||||
ptrdiff_t top = savestack(L, L->top);
|
||||
ptrdiff_t ci_top = savestack(L, ci->top);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ldo.h,v 2.28 2015/11/23 11:29:43 roberto Exp $
|
||||
** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -25,7 +25,7 @@
|
|||
{ pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); }
|
||||
|
||||
/* In general, 'pre'/'pos' are empty (nothing to save) */
|
||||
#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,,)
|
||||
#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lgc.c,v 2.210 2015/11/03 18:10:44 roberto Exp $
|
||||
** $Id: lgc.c,v 2.212 2016/03/31 19:02:03 roberto Exp $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -754,14 +754,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
|
|||
/*
|
||||
** sweep a list until a live object (or end of list)
|
||||
*/
|
||||
static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
|
||||
static GCObject **sweeptolive (lua_State *L, GCObject **p) {
|
||||
GCObject **old = p;
|
||||
int i = 0;
|
||||
do {
|
||||
i++;
|
||||
p = sweeplist(L, p, 1);
|
||||
} while (p == old);
|
||||
if (n) *n += i;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -856,10 +853,10 @@ static int runafewfinalizers (lua_State *L) {
|
|||
/*
|
||||
** call all pending finalizers
|
||||
*/
|
||||
static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
|
||||
static void callallpendingfinalizers (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
while (g->tobefnz)
|
||||
GCTM(L, propagateerrors);
|
||||
GCTM(L, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -909,7 +906,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
|
|||
if (issweepphase(g)) {
|
||||
makewhite(g, o); /* "sweep" object 'o' */
|
||||
if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
|
||||
g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */
|
||||
g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */
|
||||
}
|
||||
/* search for pointer pointing to 'o' */
|
||||
for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
|
||||
|
@ -951,19 +948,16 @@ static void setpause (global_State *g) {
|
|||
|
||||
/*
|
||||
** Enter first sweep phase.
|
||||
** The call to 'sweeptolive' makes pointer point to an object inside
|
||||
** the list (instead of to the header), so that the real sweep do not
|
||||
** need to skip objects created between "now" and the start of the real
|
||||
** sweep.
|
||||
** Returns how many objects it swept.
|
||||
** The call to 'sweeplist' tries to make pointer point to an object
|
||||
** inside the list (instead of to the header), so that the real sweep do
|
||||
** not need to skip objects created between "now" and the start of the
|
||||
** real sweep.
|
||||
*/
|
||||
static int entersweep (lua_State *L) {
|
||||
static void entersweep (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
int n = 0;
|
||||
g->gcstate = GCSswpallgc;
|
||||
lua_assert(g->sweepgc == NULL);
|
||||
g->sweepgc = sweeptolive(L, &g->allgc, &n);
|
||||
return n;
|
||||
g->sweepgc = sweeplist(L, &g->allgc, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -971,7 +965,7 @@ void luaC_freeallobjects (lua_State *L) {
|
|||
global_State *g = G(L);
|
||||
separatetobefnz(g, 1); /* separate all objects with finalizers */
|
||||
lua_assert(g->finobj == NULL);
|
||||
callallpendingfinalizers(L, 0);
|
||||
callallpendingfinalizers(L);
|
||||
lua_assert(g->tobefnz == NULL);
|
||||
g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
|
||||
g->gckind = KGC_NORMAL;
|
||||
|
@ -1064,12 +1058,11 @@ static lu_mem singlestep (lua_State *L) {
|
|||
}
|
||||
case GCSatomic: {
|
||||
lu_mem work;
|
||||
int sw;
|
||||
propagateall(g); /* make sure gray list is empty */
|
||||
work = atomic(L); /* work is what was traversed by 'atomic' */
|
||||
sw = entersweep(L);
|
||||
entersweep(L);
|
||||
g->GCestimate = gettotalbytes(g); /* first estimate */;
|
||||
return work + sw * GCSWEEPCOST;
|
||||
return work;
|
||||
}
|
||||
case GCSswpallgc: { /* sweep "regular" objects */
|
||||
return sweepstep(L, g, GCSswpfinobj, &g->finobj);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lgc.h,v 2.90 2015/10/21 18:15:15 roberto Exp $
|
||||
** $Id: lgc.h,v 2.91 2015/12/21 13:02:14 roberto Exp $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -112,7 +112,7 @@
|
|||
condchangemem(L,pre,pos); }
|
||||
|
||||
/* more often than not, 'pre'/'pos' are empty */
|
||||
#define luaC_checkGC(L) luaC_condGC(L,,)
|
||||
#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
|
||||
|
||||
|
||||
#define luaC_barrier(L,p,v) ( \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: liolib.c,v 2.148 2015/11/23 11:36:11 roberto Exp $
|
||||
** $Id: liolib.c,v 2.149 2016/05/02 14:03:19 roberto Exp $
|
||||
** Standard I/O (and system) library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -375,14 +375,17 @@ static int io_lines (lua_State *L) {
|
|||
|
||||
|
||||
/* maximum length of a numeral */
|
||||
#define MAXRN 200
|
||||
#if !defined (L_MAXLENNUM)
|
||||
#define L_MAXLENNUM 200
|
||||
#endif
|
||||
|
||||
|
||||
/* auxiliary structure used by 'read_number' */
|
||||
typedef struct {
|
||||
FILE *f; /* file being read */
|
||||
int c; /* current character (look ahead) */
|
||||
int n; /* number of elements in buffer 'buff' */
|
||||
char buff[MAXRN + 1]; /* +1 for ending '\0' */
|
||||
char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */
|
||||
} RN;
|
||||
|
||||
|
||||
|
@ -390,7 +393,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 >= MAXRN) { /* buffer overflow? */
|
||||
if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */
|
||||
rn->buff[0] = '\0'; /* invalidate result */
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
@ -403,10 +406,10 @@ static int nextc (RN *rn) {
|
|||
|
||||
|
||||
/*
|
||||
** Accept current char if it is in 'set' (of size 1 or 2)
|
||||
** Accept current char if it is in 'set' (of size 2)
|
||||
*/
|
||||
static int test2 (RN *rn, const char *set) {
|
||||
if (rn->c == set[0] || (rn->c == set[1] && rn->c != '\0'))
|
||||
if (rn->c == set[0] || rn->c == set[1])
|
||||
return nextc(rn);
|
||||
else return 0;
|
||||
}
|
||||
|
@ -435,11 +438,11 @@ static int read_number (lua_State *L, FILE *f) {
|
|||
char decp[2];
|
||||
rn.f = f; rn.n = 0;
|
||||
decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
|
||||
decp[1] = '\0';
|
||||
decp[1] = '.'; /* always accept a dot */
|
||||
l_lockfile(rn.f);
|
||||
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
|
||||
test2(&rn, "-+"); /* optional signal */
|
||||
if (test2(&rn, "0")) {
|
||||
if (test2(&rn, "00")) {
|
||||
if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
|
||||
else count = 1; /* count initial '0' as a valid digit */
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: llex.c,v 2.95 2015/11/19 19:16:22 roberto Exp $
|
||||
** $Id: llex.c,v 2.96 2016/05/02 14:02:12 roberto Exp $
|
||||
** Lexical Analyzer
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -162,7 +162,6 @@ static void inclinenumber (LexState *ls) {
|
|||
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
|
||||
int firstchar) {
|
||||
ls->t.token = 0;
|
||||
ls->decpoint = '.';
|
||||
ls->L = L;
|
||||
ls->current = firstchar;
|
||||
ls->lookahead.token = TK_EOS; /* no look-ahead token */
|
||||
|
@ -207,35 +206,6 @@ static int check_next2 (LexState *ls, const char *set) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
** change all characters 'from' in buffer to 'to'
|
||||
*/
|
||||
static void buffreplace (LexState *ls, char from, char to) {
|
||||
if (from != to) {
|
||||
size_t n = luaZ_bufflen(ls->buff);
|
||||
char *p = luaZ_buffer(ls->buff);
|
||||
while (n--)
|
||||
if (p[n] == from) p[n] = to;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** in case of format error, try to change decimal point separator to
|
||||
** the one defined in the current locale and check again
|
||||
*/
|
||||
static void trydecpoint (LexState *ls, TValue *o) {
|
||||
char old = ls->decpoint;
|
||||
ls->decpoint = lua_getlocaledecpoint();
|
||||
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
|
||||
if (luaO_str2num(luaZ_buffer(ls->buff), o) == 0) {
|
||||
/* format error with correct decimal point: no more options */
|
||||
buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
|
||||
lexerror(ls, "malformed number", TK_FLT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* LUA_NUMBER */
|
||||
/*
|
||||
** this function is quite liberal in what it accepts, as 'luaO_str2num'
|
||||
|
@ -259,9 +229,8 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
|
|||
else break;
|
||||
}
|
||||
save(ls, '\0');
|
||||
buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
|
||||
if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */
|
||||
trydecpoint(ls, &obj); /* try to update decimal point separator */
|
||||
lexerror(ls, "malformed number", TK_FLT);
|
||||
if (ttisinteger(&obj)) {
|
||||
seminfo->i = ivalue(&obj);
|
||||
return TK_INT;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: llex.h,v 1.78 2014/10/29 15:38:24 roberto Exp $
|
||||
** $Id: llex.h,v 1.79 2016/05/02 14:02:12 roberto Exp $
|
||||
** Lexical Analyzer
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -69,7 +69,6 @@ typedef struct LexState {
|
|||
struct Dyndata *dyd; /* dynamic structures used by the parser */
|
||||
TString *source; /* current source name */
|
||||
TString *envn; /* environment variable name */
|
||||
char decpoint; /* locale decimal point */
|
||||
} LexState;
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lobject.c,v 2.108 2015/11/02 16:09:30 roberto Exp $
|
||||
** $Id: lobject.c,v 2.111 2016/05/20 14:07:48 roberto Exp $
|
||||
** Some generic functions over Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -243,20 +243,59 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
|
|||
/* }====================================================== */
|
||||
|
||||
|
||||
static const char *l_str2d (const char *s, lua_Number *result) {
|
||||
/* maximum length of a numeral */
|
||||
#if !defined (L_MAXLENNUM)
|
||||
#define L_MAXLENNUM 200
|
||||
#endif
|
||||
|
||||
static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
|
||||
char *endptr;
|
||||
if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
|
||||
return NULL;
|
||||
else if (strpbrk(s, "xX")) /* hex? */
|
||||
*result = lua_strx2number(s, &endptr);
|
||||
else
|
||||
*result = lua_str2number(s, &endptr);
|
||||
if (endptr == s) return NULL; /* nothing recognized */
|
||||
while (lisspace(cast_uchar(*endptr))) endptr++;
|
||||
return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
|
||||
*result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
|
||||
: lua_str2number(s, &endptr);
|
||||
if (endptr == s) return NULL; /* nothing recognized? */
|
||||
while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
|
||||
return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Convert string 's' to a Lua number (put in 'result'). Return NULL
|
||||
** on fail or the address of the ending '\0' on success.
|
||||
** 'pmode' points to (and 'mode' contains) special things in the string:
|
||||
** - 'x'/'X' means an hexadecimal numeral
|
||||
** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
|
||||
** - '.' just optimizes the search for the common case (nothing special)
|
||||
** This function accepts both the current locale or a dot as the radix
|
||||
** mark. If the convertion fails, it may mean number has a dot but
|
||||
** locale accepts something else. In that case, the code copies 's'
|
||||
** to a buffer (because 's' is read-only), changes the dot to the
|
||||
** current locale radix mark, and tries to convert again.
|
||||
*/
|
||||
static const char *l_str2d (const char *s, lua_Number *result) {
|
||||
const char *endptr;
|
||||
const char *pmode = strpbrk(s, ".xXnN");
|
||||
int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
|
||||
if (mode == 'n') /* reject 'inf' and 'nan' */
|
||||
return NULL;
|
||||
endptr = l_str2dloc(s, result, mode); /* try to convert */
|
||||
if (endptr == NULL) { /* failed? may be a different locale */
|
||||
char buff[L_MAXLENNUM + 1];
|
||||
char *pdot = strchr(s, '.');
|
||||
if (strlen(s) > L_MAXLENNUM || pdot == NULL)
|
||||
return NULL; /* string too long or no dot; fail */
|
||||
strcpy(buff, s); /* copy string to buffer */
|
||||
buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
|
||||
endptr = l_str2dloc(buff, result, mode); /* try again */
|
||||
if (endptr != NULL)
|
||||
endptr = s + (endptr - buff); /* make relative to 's' */
|
||||
}
|
||||
return endptr;
|
||||
}
|
||||
|
||||
|
||||
#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10)
|
||||
#define MAXLASTD cast_int(LUA_MAXINTEGER % 10)
|
||||
|
||||
static const char *l_str2int (const char *s, lua_Integer *result) {
|
||||
lua_Unsigned a = 0;
|
||||
int empty = 1;
|
||||
|
@ -273,7 +312,10 @@ static const char *l_str2int (const char *s, lua_Integer *result) {
|
|||
}
|
||||
else { /* decimal */
|
||||
for (; lisdigit(cast_uchar(*s)); s++) {
|
||||
a = a * 10 + *s - '0';
|
||||
int d = *s - '0';
|
||||
if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
|
||||
return NULL; /* do not accept it (as integer) */
|
||||
a = a * 10 + d;
|
||||
empty = 0;
|
||||
}
|
||||
}
|
||||
|
@ -351,8 +393,10 @@ static void pushstr (lua_State *L, const char *str, size_t l) {
|
|||
}
|
||||
|
||||
|
||||
/* this function handles only '%d', '%c', '%f', '%p', and '%s'
|
||||
conventional formats, plus Lua-specific '%I' and '%U' */
|
||||
/*
|
||||
** this function handles only '%d', '%c', '%f', '%p', and '%s'
|
||||
conventional formats, plus Lua-specific '%I' and '%U'
|
||||
*/
|
||||
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
||||
int n = 0;
|
||||
for (;;) {
|
||||
|
@ -360,13 +404,13 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
|||
if (e == NULL) break;
|
||||
pushstr(L, fmt, e - fmt);
|
||||
switch (*(e+1)) {
|
||||
case 's': {
|
||||
case 's': { /* zero-terminated string */
|
||||
const char *s = va_arg(argp, char *);
|
||||
if (s == NULL) s = "(null)";
|
||||
pushstr(L, s, strlen(s));
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
case 'c': { /* an 'int' as a character */
|
||||
char buff = cast(char, va_arg(argp, int));
|
||||
if (lisprint(cast_uchar(buff)))
|
||||
pushstr(L, &buff, 1);
|
||||
|
@ -374,28 +418,28 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
|||
luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
case 'd': { /* an 'int' */
|
||||
setivalue(L->top, va_arg(argp, int));
|
||||
goto top2str;
|
||||
}
|
||||
case 'I': {
|
||||
case 'I': { /* a 'lua_Integer' */
|
||||
setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
|
||||
goto top2str;
|
||||
}
|
||||
case 'f': {
|
||||
case 'f': { /* a 'lua_Number' */
|
||||
setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
|
||||
top2str:
|
||||
top2str: /* convert the top element to a string */
|
||||
luaD_inctop(L);
|
||||
luaO_tostring(L, L->top - 1);
|
||||
break;
|
||||
}
|
||||
case 'p': {
|
||||
case 'p': { /* a pointer */
|
||||
char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
|
||||
int l = l_sprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
|
||||
pushstr(L, buff, l);
|
||||
break;
|
||||
}
|
||||
case 'U': {
|
||||
case 'U': { /* an 'int' as a UTF-8 sequence */
|
||||
char buff[UTF8BUFFSZ];
|
||||
int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
|
||||
pushstr(L, buff + UTF8BUFFSZ - l, l);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: loslib.c,v 1.60 2015/11/19 19:16:22 roberto Exp $
|
||||
** $Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp $
|
||||
** Standard Operating System library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -24,18 +24,29 @@
|
|||
|
||||
/*
|
||||
** {==================================================================
|
||||
** list of valid conversion specifiers for the 'strftime' function
|
||||
** List of valid conversion specifiers for the 'strftime' function;
|
||||
** options are grouped by length; group of length 2 start with '||'.
|
||||
** ===================================================================
|
||||
*/
|
||||
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
|
||||
|
||||
#if defined(LUA_USE_C89)
|
||||
#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
|
||||
/* options for ANSI C 89 */
|
||||
#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
|
||||
|
||||
/* options for ISO C 99 and POSIX */
|
||||
#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
|
||||
"||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy"
|
||||
|
||||
/* options for Windows */
|
||||
#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
|
||||
"||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"
|
||||
|
||||
#if defined(LUA_USE_WINDOWS)
|
||||
#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
|
||||
#elif defined(LUA_USE_C89)
|
||||
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
|
||||
#else /* C99 specification */
|
||||
#define LUA_STRFTIMEOPTIONS \
|
||||
{ "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \
|
||||
"E", "cCxXyY", \
|
||||
"O", "deHImMSuUVwWy" }
|
||||
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
|
||||
#endif
|
||||
|
||||
#endif /* } */
|
||||
|
@ -195,6 +206,23 @@ static void setboolfield (lua_State *L, const char *key, int value) {
|
|||
lua_setfield(L, -2, key);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Set all fields from structure 'tm' in the table on top of the stack
|
||||
*/
|
||||
static void setallfields (lua_State *L, struct tm *stm) {
|
||||
setfield(L, "sec", stm->tm_sec);
|
||||
setfield(L, "min", stm->tm_min);
|
||||
setfield(L, "hour", stm->tm_hour);
|
||||
setfield(L, "day", stm->tm_mday);
|
||||
setfield(L, "month", stm->tm_mon + 1);
|
||||
setfield(L, "year", stm->tm_year + 1900);
|
||||
setfield(L, "wday", stm->tm_wday + 1);
|
||||
setfield(L, "yday", stm->tm_yday + 1);
|
||||
setboolfield(L, "isdst", stm->tm_isdst);
|
||||
}
|
||||
|
||||
|
||||
static int getboolfield (lua_State *L, const char *key) {
|
||||
int res;
|
||||
res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
|
||||
|
@ -210,18 +238,18 @@ static int getboolfield (lua_State *L, const char *key) {
|
|||
|
||||
static int getfield (lua_State *L, const char *key, int d, int delta) {
|
||||
int isnum;
|
||||
int t = lua_getfield(L, -1, key);
|
||||
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 a number? */
|
||||
if (!isnum) { /* field is not an integer? */
|
||||
if (t != LUA_TNIL) /* some other value? */
|
||||
return luaL_error(L, "field '%s' not an integer", key);
|
||||
return luaL_error(L, "field '%s' is not an integer", key);
|
||||
else if (d < 0) /* absent field; no default? */
|
||||
return luaL_error(L, "field '%s' missing in date table", key);
|
||||
res = d;
|
||||
}
|
||||
else {
|
||||
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
|
||||
return luaL_error(L, "field '%s' out-of-bounds", key);
|
||||
return luaL_error(L, "field '%s' is out-of-bound", key);
|
||||
res -= delta;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
@ -230,21 +258,15 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
|
|||
|
||||
|
||||
static const char *checkoption (lua_State *L, const char *conv, char *buff) {
|
||||
static const char *const options[] = LUA_STRFTIMEOPTIONS;
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) {
|
||||
if (*conv != '\0' && strchr(options[i], *conv) != NULL) {
|
||||
buff[1] = *conv;
|
||||
if (*options[i + 1] == '\0') { /* one-char conversion specifier? */
|
||||
buff[2] = '\0'; /* end buffer */
|
||||
return conv + 1;
|
||||
}
|
||||
else if (*(conv + 1) != '\0' &&
|
||||
strchr(options[i + 1], *(conv + 1)) != NULL) {
|
||||
buff[2] = *(conv + 1); /* valid two-char conversion specifier */
|
||||
buff[3] = '\0'; /* end buffer */
|
||||
return conv + 2;
|
||||
}
|
||||
const char *option;
|
||||
int oplen = 1;
|
||||
for (option = LUA_STRFTIMEOPTIONS; *option != '\0'; option += oplen) {
|
||||
if (*option == '|') /* next block? */
|
||||
oplen++; /* next length */
|
||||
else if (memcmp(conv, option, oplen) == 0) { /* match? */
|
||||
memcpy(buff, conv, oplen); /* copy valid option to buffer */
|
||||
buff[oplen] = '\0';
|
||||
return conv + oplen; /* return next item */
|
||||
}
|
||||
}
|
||||
luaL_argerror(L, 1,
|
||||
|
@ -271,18 +293,10 @@ static int os_date (lua_State *L) {
|
|||
luaL_error(L, "time result cannot be represented in this installation");
|
||||
if (strcmp(s, "*t") == 0) {
|
||||
lua_createtable(L, 0, 9); /* 9 = number of fields */
|
||||
setfield(L, "sec", stm->tm_sec);
|
||||
setfield(L, "min", stm->tm_min);
|
||||
setfield(L, "hour", stm->tm_hour);
|
||||
setfield(L, "day", stm->tm_mday);
|
||||
setfield(L, "month", stm->tm_mon+1);
|
||||
setfield(L, "year", stm->tm_year+1900);
|
||||
setfield(L, "wday", stm->tm_wday+1);
|
||||
setfield(L, "yday", stm->tm_yday+1);
|
||||
setboolfield(L, "isdst", stm->tm_isdst);
|
||||
setallfields(L, stm);
|
||||
}
|
||||
else {
|
||||
char cc[4];
|
||||
char cc[4]; /* buffer for individual conversion specifiers */
|
||||
luaL_Buffer b;
|
||||
cc[0] = '%';
|
||||
luaL_buffinit(L, &b);
|
||||
|
@ -292,7 +306,7 @@ static int os_date (lua_State *L) {
|
|||
else {
|
||||
size_t reslen;
|
||||
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
|
||||
s = checkoption(L, s + 1, cc);
|
||||
s = checkoption(L, s + 1, cc + 1); /* copy specifier to 'cc' */
|
||||
reslen = strftime(buff, SIZETIMEFMT, cc, stm);
|
||||
luaL_addsize(&b, reslen);
|
||||
}
|
||||
|
@ -319,6 +333,7 @@ static int os_time (lua_State *L) {
|
|||
ts.tm_year = getfield(L, "year", -1, 1900);
|
||||
ts.tm_isdst = getboolfield(L, "isdst");
|
||||
t = mktime(&ts);
|
||||
setallfields(L, &ts); /* update fields with normalized values */
|
||||
}
|
||||
if (t != (time_t)(l_timet)t || t == (time_t)(-1))
|
||||
luaL_error(L, "time result cannot be represented in this installation");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lparser.c,v 2.149 2015/11/02 16:09:30 roberto Exp $
|
||||
** $Id: lparser.c,v 2.153 2016/05/13 19:10:16 roberto Exp $
|
||||
** Lua Parser
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -164,7 +164,8 @@ static int registerlocalvar (LexState *ls, TString *varname) {
|
|||
int oldsize = f->sizelocvars;
|
||||
luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
|
||||
LocVar, SHRT_MAX, "local variables");
|
||||
while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
|
||||
while (oldsize < f->sizelocvars)
|
||||
f->locvars[oldsize++].varname = NULL;
|
||||
f->locvars[fs->nlocvars].varname = varname;
|
||||
luaC_objbarrier(ls->L, f, varname);
|
||||
return fs->nlocvars++;
|
||||
|
@ -230,7 +231,8 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
|
|||
checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
|
||||
luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
|
||||
Upvaldesc, MAXUPVAL, "upvalues");
|
||||
while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
|
||||
while (oldsize < f->sizeupvalues)
|
||||
f->upvalues[oldsize++].name = NULL;
|
||||
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
|
||||
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
|
||||
f->upvalues[fs->nups].name = name;
|
||||
|
@ -255,7 +257,8 @@ static int searchvar (FuncState *fs, TString *n) {
|
|||
*/
|
||||
static void markupval (FuncState *fs, int level) {
|
||||
BlockCnt *bl = fs->bl;
|
||||
while (bl->nactvar > level) bl = bl->previous;
|
||||
while (bl->nactvar > level)
|
||||
bl = bl->previous;
|
||||
bl->upval = 1;
|
||||
}
|
||||
|
||||
|
@ -264,27 +267,26 @@ static void markupval (FuncState *fs, int level) {
|
|||
Find variable with given name 'n'. If it is an upvalue, add this
|
||||
upvalue into all intermediate functions.
|
||||
*/
|
||||
static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
|
||||
static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
|
||||
if (fs == NULL) /* no more levels? */
|
||||
return VVOID; /* default is global */
|
||||
init_exp(var, VVOID, 0); /* default is global */
|
||||
else {
|
||||
int v = searchvar(fs, n); /* look up locals at current level */
|
||||
if (v >= 0) { /* found? */
|
||||
init_exp(var, VLOCAL, v); /* variable is local */
|
||||
if (!base)
|
||||
markupval(fs, v); /* local will be used as an upval */
|
||||
return VLOCAL;
|
||||
}
|
||||
else { /* not found as local at current level; try upvalues */
|
||||
int idx = searchupvalue(fs, n); /* try existing upvalues */
|
||||
if (idx < 0) { /* not found? */
|
||||
if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
|
||||
return VVOID; /* not found; is a global */
|
||||
singlevaraux(fs->prev, n, var, 0); /* try upper levels */
|
||||
if (var->k == VVOID) /* not found? */
|
||||
return; /* it is a global */
|
||||
/* else was LOCAL or UPVAL */
|
||||
idx = newupvalue(fs, n, var); /* will be a new upvalue */
|
||||
}
|
||||
init_exp(var, VUPVAL, idx);
|
||||
return VUPVAL;
|
||||
init_exp(var, VUPVAL, idx); /* new or old upvalue */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -293,10 +295,11 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
|
|||
static void singlevar (LexState *ls, expdesc *var) {
|
||||
TString *varname = str_checkname(ls);
|
||||
FuncState *fs = ls->fs;
|
||||
if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */
|
||||
singlevaraux(fs, varname, var, 1);
|
||||
if (var->k == VVOID) { /* global name? */
|
||||
expdesc key;
|
||||
singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
|
||||
lua_assert(var->k == VLOCAL || var->k == VUPVAL);
|
||||
lua_assert(var->k != VVOID); /* this one must exist */
|
||||
codestring(ls, &key, varname); /* key is variable name */
|
||||
luaK_indexed(fs, var, &key); /* env[varname] */
|
||||
}
|
||||
|
@ -499,7 +502,8 @@ static Proto *addprototype (LexState *ls) {
|
|||
if (fs->np >= f->sizep) {
|
||||
int oldsize = f->sizep;
|
||||
luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
|
||||
while (oldsize < f->sizep) f->p[oldsize++] = NULL;
|
||||
while (oldsize < f->sizep)
|
||||
f->p[oldsize++] = NULL;
|
||||
}
|
||||
f->p[fs->np++] = clp = luaF_newproto(L);
|
||||
luaC_objbarrier(L, f, clp);
|
||||
|
@ -1226,7 +1230,7 @@ static void labelstat (LexState *ls, TString *label, int line) {
|
|||
checkrepeated(fs, ll, label); /* check for repeated labels */
|
||||
checknext(ls, TK_DBCOLON); /* skip double colon */
|
||||
/* create new entry for this label */
|
||||
l = newlabelentry(ls, ll, label, line, fs->pc);
|
||||
l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
|
||||
skipnoopstat(ls); /* skip other no-op statements */
|
||||
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
|
||||
/* assume that locals are already out of scope */
|
||||
|
@ -1494,7 +1498,7 @@ static void exprstat (LexState *ls) {
|
|||
}
|
||||
else { /* stat -> func */
|
||||
check_condition(ls, v.v.k == VCALL, "syntax error");
|
||||
SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
|
||||
SETARG_C(getinstruction(fs, &v.v), 1); /* call statement uses no results */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1511,8 +1515,8 @@ static void retstat (LexState *ls) {
|
|||
if (hasmultret(e.k)) {
|
||||
luaK_setmultret(fs, &e);
|
||||
if (e.k == VCALL && nret == 1) { /* tail call? */
|
||||
SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
|
||||
lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
|
||||
SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL);
|
||||
lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar);
|
||||
}
|
||||
first = fs->nactvar;
|
||||
nret = LUA_MULTRET; /* return all values */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lparser.h,v 1.74 2014/10/25 11:50:46 roberto Exp $
|
||||
** $Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp $
|
||||
** Lua Parser
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -13,25 +13,38 @@
|
|||
|
||||
|
||||
/*
|
||||
** Expression descriptor
|
||||
** Expression and variable descriptor.
|
||||
** Code generation for variables and expressions can be delayed to allow
|
||||
** optimizations; An 'expdesc' structure describes a potentially-delayed
|
||||
** variable/expression. It has a description of its "main" value plus a
|
||||
** list of conditional jumps that can also produce its value (generated
|
||||
** by short-circuit operators 'and'/'or').
|
||||
*/
|
||||
|
||||
/* kinds of variables/expressions */
|
||||
typedef enum {
|
||||
VVOID, /* no value */
|
||||
VNIL,
|
||||
VTRUE,
|
||||
VFALSE,
|
||||
VK, /* info = index of constant in 'k' */
|
||||
VKFLT, /* nval = numerical float value */
|
||||
VKINT, /* nval = numerical integer value */
|
||||
VNONRELOC, /* info = result register */
|
||||
VLOCAL, /* info = local register */
|
||||
VUPVAL, /* info = index of upvalue in 'upvalues' */
|
||||
VINDEXED, /* t = table register/upvalue; idx = index R/K */
|
||||
VJMP, /* info = instruction pc */
|
||||
VRELOCABLE, /* info = instruction pc */
|
||||
VCALL, /* info = instruction pc */
|
||||
VVARARG /* info = instruction pc */
|
||||
VVOID, /* when 'expdesc' describes the last expression a list,
|
||||
this kind means an empty list (so, no expression) */
|
||||
VNIL, /* constant nil */
|
||||
VTRUE, /* constant true */
|
||||
VFALSE, /* constant false */
|
||||
VK, /* constant in 'k'; info = index of constant in 'k' */
|
||||
VKFLT, /* floating constant; nval = numerical float value */
|
||||
VKINT, /* integer constant; nval = numerical integer value */
|
||||
VNONRELOC, /* expression has its value in a fixed register;
|
||||
info = result register */
|
||||
VLOCAL, /* local variable; info = local register */
|
||||
VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
|
||||
VINDEXED, /* indexed variable;
|
||||
ind.vt = whether 't' is register or upvalue;
|
||||
ind.t = table register or upvalue;
|
||||
ind.idx = key's R/K index */
|
||||
VJMP, /* expression is a test/comparison;
|
||||
info = pc of corresponding jump instruction */
|
||||
VRELOCABLE, /* expression can put result in any register;
|
||||
info = instruction pc */
|
||||
VCALL, /* expression is a function call; info = instruction pc */
|
||||
VVARARG /* vararg expression; info = instruction pc */
|
||||
} expkind;
|
||||
|
||||
|
||||
|
@ -41,14 +54,14 @@ typedef enum {
|
|||
typedef struct expdesc {
|
||||
expkind k;
|
||||
union {
|
||||
lua_Integer ival; /* for VKINT */
|
||||
lua_Number nval; /* for VKFLT */
|
||||
int info; /* for generic use */
|
||||
struct { /* for indexed variables (VINDEXED) */
|
||||
short idx; /* index (R/K) */
|
||||
lu_byte t; /* table (register or upvalue) */
|
||||
lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
|
||||
} ind;
|
||||
int info; /* for generic use */
|
||||
lua_Number nval; /* for VKFLT */
|
||||
lua_Integer ival; /* for VKINT */
|
||||
} u;
|
||||
int t; /* patch list of 'exit when true' */
|
||||
int f; /* patch list of 'exit when false' */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lstate.h,v 2.128 2015/11/13 12:16:51 roberto Exp $
|
||||
** $Id: lstate.h,v 2.130 2015/12/16 16:39:38 roberto Exp $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -33,6 +33,15 @@
|
|||
struct lua_longjmp; /* defined in ldo.c */
|
||||
|
||||
|
||||
/*
|
||||
** Atomic type (relative to signals) to better ensure that 'lua_sethook'
|
||||
** is thread safe
|
||||
*/
|
||||
#if !defined(l_signalT)
|
||||
#include <signal.h>
|
||||
#define l_signalT sig_atomic_t
|
||||
#endif
|
||||
|
||||
|
||||
/* extra stack space to handle TM calls and some other extras */
|
||||
#define EXTRA_STACK 5
|
||||
|
@ -162,14 +171,14 @@ struct lua_State {
|
|||
struct lua_State *twups; /* list of threads with open upvalues */
|
||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
|
||||
lua_Hook hook;
|
||||
volatile lua_Hook hook;
|
||||
ptrdiff_t errfunc; /* current error handling function (stack index) */
|
||||
int stacksize;
|
||||
int basehookcount;
|
||||
int hookcount;
|
||||
unsigned short nny; /* number of non-yieldable calls in stack */
|
||||
unsigned short nCcalls; /* number of nested C calls */
|
||||
lu_byte hookmask;
|
||||
l_signalT hookmask;
|
||||
lu_byte allowhook;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lstrlib.c,v 1.239 2015/11/25 16:28:17 roberto Exp $
|
||||
** $Id: lstrlib.c,v 1.251 2016/05/20 14:13:21 roberto Exp $
|
||||
** Standard library for string operations and pattern-matching
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -13,6 +13,7 @@
|
|||
#include <ctype.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -26,7 +27,8 @@
|
|||
|
||||
/*
|
||||
** maximum number of captures that a pattern can do during
|
||||
** pattern-matching. This limit is arbitrary.
|
||||
** pattern-matching. This limit is arbitrary, but must fit in
|
||||
** an unsigned char.
|
||||
*/
|
||||
#if !defined(LUA_MAXCAPTURES)
|
||||
#define LUA_MAXCAPTURES 32
|
||||
|
@ -214,9 +216,8 @@ typedef struct MatchState {
|
|||
const char *src_end; /* end ('\0') of source string */
|
||||
const char *p_end; /* end ('\0') of pattern */
|
||||
lua_State *L;
|
||||
size_t nrep; /* limit to avoid non-linear complexity */
|
||||
int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
|
||||
int level; /* total number of captures (finished or unfinished) */
|
||||
unsigned char level; /* total number of captures (finished or unfinished) */
|
||||
struct {
|
||||
const char *init;
|
||||
ptrdiff_t len;
|
||||
|
@ -234,17 +235,6 @@ static const char *match (MatchState *ms, const char *s, const char *p);
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** parameters to control the maximum number of operators handled in
|
||||
** a match (to avoid non-linear complexity). The maximum will be:
|
||||
** (subject length) * A_REPS + B_REPS
|
||||
*/
|
||||
#if !defined(A_REPS)
|
||||
#define A_REPS 4
|
||||
#define B_REPS 100000
|
||||
#endif
|
||||
|
||||
|
||||
#define L_ESC '%'
|
||||
#define SPECIALS "^$*+?.([%-"
|
||||
|
||||
|
@ -502,8 +492,6 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
|
|||
s = NULL; /* fail */
|
||||
}
|
||||
else { /* matched once */
|
||||
if (ms->nrep-- == 0)
|
||||
luaL_error(ms->L, "pattern too complex");
|
||||
switch (*ep) { /* handle optional suffix */
|
||||
case '?': { /* optional */
|
||||
const char *res;
|
||||
|
@ -607,10 +595,6 @@ static void prepstate (MatchState *ms, lua_State *L,
|
|||
ms->src_init = s;
|
||||
ms->src_end = s + ls;
|
||||
ms->p_end = p + lp;
|
||||
if (ls < (MAX_SIZET - B_REPS) / A_REPS)
|
||||
ms->nrep = A_REPS * ls + B_REPS;
|
||||
else /* overflow (very long subject) */
|
||||
ms->nrep = MAX_SIZET; /* no limit */
|
||||
}
|
||||
|
||||
|
||||
|
@ -681,6 +665,7 @@ static int str_match (lua_State *L) {
|
|||
typedef struct GMatchState {
|
||||
const char *src; /* current position */
|
||||
const char *p; /* pattern */
|
||||
const char *lastmatch; /* end of last match */
|
||||
MatchState ms; /* match state */
|
||||
} GMatchState;
|
||||
|
||||
|
@ -688,14 +673,12 @@ typedef struct GMatchState {
|
|||
static int gmatch_aux (lua_State *L) {
|
||||
GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
|
||||
const char *src;
|
||||
gm->ms.L = L;
|
||||
for (src = gm->src; src <= gm->ms.src_end; src++) {
|
||||
const char *e;
|
||||
reprepstate(&gm->ms);
|
||||
if ((e = match(&gm->ms, src, gm->p)) != NULL) {
|
||||
if (e == src) /* empty match? */
|
||||
gm->src =src + 1; /* go at least one position */
|
||||
else
|
||||
gm->src = e;
|
||||
if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) {
|
||||
gm->src = gm->lastmatch = e;
|
||||
return push_captures(&gm->ms, src, e);
|
||||
}
|
||||
}
|
||||
|
@ -711,7 +694,7 @@ static int gmatch (lua_State *L) {
|
|||
lua_settop(L, 2); /* keep them on closure to avoid being collected */
|
||||
gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState));
|
||||
prepstate(&gm->ms, L, s, ls, p, lp);
|
||||
gm->src = s; gm->p = p;
|
||||
gm->src = s; gm->p = p; gm->lastmatch = NULL;
|
||||
lua_pushcclosure(L, gmatch_aux, 3);
|
||||
return 1;
|
||||
}
|
||||
|
@ -778,12 +761,13 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
|
|||
|
||||
static int str_gsub (lua_State *L) {
|
||||
size_t srcl, lp;
|
||||
const char *src = luaL_checklstring(L, 1, &srcl);
|
||||
const char *p = luaL_checklstring(L, 2, &lp);
|
||||
int tr = lua_type(L, 3);
|
||||
lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1);
|
||||
const char *src = luaL_checklstring(L, 1, &srcl); /* subject */
|
||||
const char *p = luaL_checklstring(L, 2, &lp); /* pattern */
|
||||
const char *lastmatch = NULL; /* end of last match */
|
||||
int tr = lua_type(L, 3); /* replacement type */
|
||||
lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */
|
||||
int anchor = (*p == '^');
|
||||
lua_Integer n = 0;
|
||||
lua_Integer n = 0; /* replacement count */
|
||||
MatchState ms;
|
||||
luaL_Buffer b;
|
||||
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
|
||||
|
@ -796,16 +780,15 @@ static int str_gsub (lua_State *L) {
|
|||
prepstate(&ms, L, src, srcl, p, lp);
|
||||
while (n < max_s) {
|
||||
const char *e;
|
||||
reprepstate(&ms);
|
||||
if ((e = match(&ms, src, p)) != NULL) {
|
||||
reprepstate(&ms); /* (re)prepare state for new match */
|
||||
if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */
|
||||
n++;
|
||||
add_value(&ms, &b, src, e, tr);
|
||||
add_value(&ms, &b, src, e, tr); /* add replacement to buffer */
|
||||
src = lastmatch = e;
|
||||
}
|
||||
if (e && e>src) /* non empty match? */
|
||||
src = e; /* skip it */
|
||||
else if (src < ms.src_end)
|
||||
else if (src < ms.src_end) /* otherwise, skip one character */
|
||||
luaL_addchar(&b, *src++);
|
||||
else break;
|
||||
else break; /* end of subject */
|
||||
if (anchor) break;
|
||||
}
|
||||
luaL_addlstring(&b, src, ms.src_end-src);
|
||||
|
@ -830,7 +813,6 @@ static int str_gsub (lua_State *L) {
|
|||
** Hexadecimal floating-point formatter
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
|
||||
#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
|
||||
|
@ -922,16 +904,14 @@ static int lua_number2strx (lua_State *L, char *buff, int sz,
|
|||
#define MAX_FORMAT 32
|
||||
|
||||
|
||||
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
|
||||
size_t l;
|
||||
const char *s = luaL_checklstring(L, arg, &l);
|
||||
static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
|
||||
luaL_addchar(b, '"');
|
||||
while (l--) {
|
||||
while (len--) {
|
||||
if (*s == '"' || *s == '\\' || *s == '\n') {
|
||||
luaL_addchar(b, '\\');
|
||||
luaL_addchar(b, *s);
|
||||
}
|
||||
else if (*s == '\0' || iscntrl(uchar(*s))) {
|
||||
else if (iscntrl(uchar(*s))) {
|
||||
char buff[10];
|
||||
if (!isdigit(uchar(*(s+1))))
|
||||
l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
|
||||
|
@ -946,6 +926,57 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
|
|||
luaL_addchar(b, '"');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Ensures the 'buff' string uses a dot as the radix character.
|
||||
*/
|
||||
static void checkdp (char *buff, int nb) {
|
||||
if (memchr(buff, '.', nb) == NULL) { /* no dot? */
|
||||
char point = lua_getlocaledecpoint(); /* try locale point */
|
||||
char *ppoint = memchr(buff, point, nb);
|
||||
if (ppoint) *ppoint = '.'; /* change it to a dot */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
|
||||
switch (lua_type(L, arg)) {
|
||||
case LUA_TSTRING: {
|
||||
size_t len;
|
||||
const char *s = lua_tolstring(L, arg, &len);
|
||||
addquoted(b, s, len);
|
||||
break;
|
||||
}
|
||||
case LUA_TNUMBER: {
|
||||
char *buff = luaL_prepbuffsize(b, MAX_ITEM);
|
||||
int nb;
|
||||
if (!lua_isinteger(L, arg)) { /* float? */
|
||||
lua_Number n = lua_tonumber(L, arg); /* write as hexa ('%a') */
|
||||
nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n);
|
||||
checkdp(buff, nb); /* ensure it uses a dot */
|
||||
}
|
||||
else { /* integers */
|
||||
lua_Integer n = lua_tointeger(L, arg);
|
||||
const char *format = (n == LUA_MININTEGER) /* corner case? */
|
||||
? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */
|
||||
: LUA_INTEGER_FMT; /* else use default format */
|
||||
nb = l_sprintf(buff, MAX_ITEM, format, n);
|
||||
}
|
||||
luaL_addsize(b, nb);
|
||||
break;
|
||||
}
|
||||
case LUA_TNIL: case LUA_TBOOLEAN: {
|
||||
luaL_tolstring(L, arg, NULL);
|
||||
luaL_addvalue(b);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
luaL_argerror(L, arg, "value has no literal form");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
|
||||
const char *p = strfrmt;
|
||||
while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
|
||||
|
@ -1025,7 +1056,7 @@ static int str_format (lua_State *L) {
|
|||
break;
|
||||
}
|
||||
case 'q': {
|
||||
addquoted(L, &b, arg);
|
||||
addliteral(L, &b, arg);
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
|
@ -1070,8 +1101,8 @@ static int str_format (lua_State *L) {
|
|||
|
||||
|
||||
/* value used for padding */
|
||||
#if !defined(LUA_PACKPADBYTE)
|
||||
#define LUA_PACKPADBYTE 0x00
|
||||
#if !defined(LUAL_PACKPADBYTE)
|
||||
#define LUAL_PACKPADBYTE 0x00
|
||||
#endif
|
||||
|
||||
/* maximum size for the binary representation of an integer */
|
||||
|
@ -1308,7 +1339,7 @@ static int str_pack (lua_State *L) {
|
|||
KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
|
||||
totalsize += ntoalign + size;
|
||||
while (ntoalign-- > 0)
|
||||
luaL_addchar(&b, LUA_PACKPADBYTE); /* fill alignment */
|
||||
luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */
|
||||
arg++;
|
||||
switch (opt) {
|
||||
case Kint: { /* signed integers */
|
||||
|
@ -1343,13 +1374,11 @@ static int str_pack (lua_State *L) {
|
|||
case Kchar: { /* fixed-size string */
|
||||
size_t len;
|
||||
const char *s = luaL_checklstring(L, arg, &len);
|
||||
if ((size_t)size <= len) /* string larger than (or equal to) needed? */
|
||||
luaL_addlstring(&b, s, size); /* truncate string to asked size */
|
||||
else { /* string smaller than needed */
|
||||
luaL_addlstring(&b, s, len); /* add it all */
|
||||
while (len++ < (size_t)size) /* pad extra space */
|
||||
luaL_addchar(&b, LUA_PACKPADBYTE);
|
||||
}
|
||||
luaL_argcheck(L, len <= (size_t)size, arg,
|
||||
"string longer than given size");
|
||||
luaL_addlstring(&b, s, len); /* add string */
|
||||
while (len++ < (size_t)size) /* pad extra space */
|
||||
luaL_addchar(&b, LUAL_PACKPADBYTE);
|
||||
break;
|
||||
}
|
||||
case Kstring: { /* strings with length count */
|
||||
|
@ -1372,7 +1401,7 @@ static int str_pack (lua_State *L) {
|
|||
totalsize += len + 1;
|
||||
break;
|
||||
}
|
||||
case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */
|
||||
case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */
|
||||
case Kpaddalign: case Knop:
|
||||
arg--; /* undo increment */
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltablib.c,v 1.90 2015/11/25 12:48:57 roberto Exp $
|
||||
** $Id: ltablib.c,v 1.93 2016/02/25 19:41:54 roberto Exp $
|
||||
** Library for Table Manipulation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -53,7 +53,7 @@ static void checktab (lua_State *L, int arg, int what) {
|
|||
lua_pop(L, n); /* pop metatable and tested metamethods */
|
||||
}
|
||||
else
|
||||
luaL_argerror(L, arg, "table expected"); /* force an error */
|
||||
luaL_checktype(L, arg, LUA_TTABLE); /* force an error */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ static int tmove (lua_State *L) {
|
|||
n = e - f + 1; /* number of elements to move */
|
||||
luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
|
||||
"destination wrap around");
|
||||
if (t > e || t <= f || tt != 1) {
|
||||
if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) {
|
||||
for (i = 0; i < n; i++) {
|
||||
lua_geti(L, 1, f + i);
|
||||
lua_seti(L, tt, t + i);
|
||||
|
@ -152,7 +152,7 @@ static int tmove (lua_State *L) {
|
|||
}
|
||||
}
|
||||
}
|
||||
lua_pushvalue(L, tt); /* return "to table" */
|
||||
lua_pushvalue(L, tt); /* return destination table */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ static int tconcat (lua_State *L) {
|
|||
size_t lsep;
|
||||
const char *sep = luaL_optlstring(L, 2, "", &lsep);
|
||||
lua_Integer i = luaL_optinteger(L, 3, 1);
|
||||
last = luaL_opt(L, luaL_checkinteger, 4, last);
|
||||
last = luaL_optinteger(L, 4, last);
|
||||
luaL_buffinit(L, &b);
|
||||
for (; i < last; i++) {
|
||||
addfield(L, &b, i);
|
||||
|
@ -232,6 +232,10 @@ static int unpack (lua_State *L) {
|
|||
*/
|
||||
|
||||
|
||||
/* type for array indices */
|
||||
typedef unsigned int IdxT;
|
||||
|
||||
|
||||
/*
|
||||
** Produce a "random" 'unsigned int' to randomize pivot choice. This
|
||||
** macro is used only when 'sort' detects a big imbalance in the result
|
||||
|
@ -270,7 +274,7 @@ static unsigned int l_randomizePivot (void) {
|
|||
#define RANLIMIT 100u
|
||||
|
||||
|
||||
static void set2 (lua_State *L, unsigned int i, unsigned int j) {
|
||||
static void set2 (lua_State *L, IdxT i, IdxT j) {
|
||||
lua_seti(L, 1, i);
|
||||
lua_seti(L, 1, j);
|
||||
}
|
||||
|
@ -303,10 +307,9 @@ static int sort_comp (lua_State *L, int a, int b) {
|
|||
** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up]
|
||||
** returns 'i'.
|
||||
*/
|
||||
static unsigned int partition (lua_State *L, unsigned int lo,
|
||||
unsigned int up) {
|
||||
unsigned int i = lo; /* will be incremented before first use */
|
||||
unsigned int j = up - 1; /* will be decremented before first use */
|
||||
static IdxT partition (lua_State *L, IdxT lo, IdxT up) {
|
||||
IdxT i = lo; /* will be incremented before first use */
|
||||
IdxT j = up - 1; /* will be decremented before first use */
|
||||
/* loop invariant: a[lo .. i] <= P <= a[j .. up] */
|
||||
for (;;) {
|
||||
/* next loop: repeat ++i while a[i] < P */
|
||||
|
@ -340,10 +343,9 @@ static unsigned int partition (lua_State *L, unsigned int lo,
|
|||
** Choose an element in the middle (2nd-3th quarters) of [lo,up]
|
||||
** "randomized" by 'rnd'
|
||||
*/
|
||||
static unsigned int choosePivot (unsigned int lo, unsigned int up,
|
||||
unsigned int rnd) {
|
||||
unsigned int r4 = (unsigned int)(up - lo) / 4u; /* range/4 */
|
||||
unsigned int p = rnd % (r4 * 2) + (lo + r4);
|
||||
static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) {
|
||||
IdxT r4 = (up - lo) / 4; /* range/4 */
|
||||
IdxT p = rnd % (r4 * 2) + (lo + r4);
|
||||
lua_assert(lo + r4 <= p && p <= up - r4);
|
||||
return p;
|
||||
}
|
||||
|
@ -352,11 +354,11 @@ static unsigned int choosePivot (unsigned int lo, unsigned int up,
|
|||
/*
|
||||
** QuickSort algorithm (recursive function)
|
||||
*/
|
||||
static void auxsort (lua_State *L, unsigned int lo, unsigned int up,
|
||||
static void auxsort (lua_State *L, IdxT lo, IdxT up,
|
||||
unsigned int rnd) {
|
||||
while (lo < up) { /* loop for tail recursion */
|
||||
unsigned int p; /* Pivot index */
|
||||
unsigned int n; /* to be used later */
|
||||
IdxT p; /* Pivot index */
|
||||
IdxT n; /* to be used later */
|
||||
/* sort elements 'lo', 'p', and 'up' */
|
||||
lua_geti(L, 1, lo);
|
||||
lua_geti(L, 1, up);
|
||||
|
@ -400,7 +402,7 @@ static void auxsort (lua_State *L, unsigned int lo, unsigned int up,
|
|||
n = up - p; /* size of smaller interval */
|
||||
up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */
|
||||
}
|
||||
if ((up - lo) / 128u > n) /* partition too imbalanced? */
|
||||
if ((up - lo) / 128 > n) /* partition too imbalanced? */
|
||||
rnd = l_randomizePivot(); /* try a new randomization */
|
||||
} /* tail call auxsort(L, lo, up, rnd) */
|
||||
}
|
||||
|
@ -410,11 +412,10 @@ static int sort (lua_State *L) {
|
|||
lua_Integer n = aux_getn(L, 1, TAB_RW);
|
||||
if (n > 1) { /* non-trivial interval? */
|
||||
luaL_argcheck(L, n < INT_MAX, 1, "array too big");
|
||||
luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
|
||||
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */
|
||||
lua_settop(L, 2); /* make sure there are two arguments */
|
||||
auxsort(L, 1, (unsigned int)n, 0u);
|
||||
auxsort(L, 1, (IdxT)n, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltm.c,v 2.36 2015/11/03 15:47:30 roberto Exp $
|
||||
** $Id: ltm.c,v 2.37 2016/02/26 19:20:15 roberto Exp $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -83,6 +83,22 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
** Return the name of the type of an object. For tables and userdata
|
||||
** with metatable, use their '__name' metafield, if present.
|
||||
*/
|
||||
const char *luaT_objtypename (lua_State *L, const TValue *o) {
|
||||
Table *mt;
|
||||
if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
|
||||
(ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
|
||||
const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
|
||||
if (ttisstring(name)) /* is '__name' a string? */
|
||||
return getstr(tsvalue(name)); /* use it as type name */
|
||||
}
|
||||
return ttypename(ttnov(o)); /* else use standard type name */
|
||||
}
|
||||
|
||||
|
||||
void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
|
||||
const TValue *p2, TValue *p3, int hasres) {
|
||||
ptrdiff_t result = savestack(L, p3);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltm.h,v 2.21 2014/10/25 11:50:46 roberto Exp $
|
||||
** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -51,11 +51,12 @@ typedef enum {
|
|||
#define fasttm(l,et,e) gfasttm(G(l), et, e)
|
||||
|
||||
#define ttypename(x) luaT_typenames_[(x) + 1]
|
||||
#define objtypename(x) ttypename(ttnov(x))
|
||||
|
||||
LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
|
||||
|
||||
|
||||
LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o);
|
||||
|
||||
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
|
||||
LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
|
||||
TMS event);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lua.h,v 1.329 2015/11/13 17:18:42 roberto Exp $
|
||||
** $Id: lua.h,v 1.331 2016/05/30 15:53:28 roberto Exp $
|
||||
** Lua - A Scripting Language
|
||||
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
||||
** See Copyright Notice at the end of this file
|
||||
|
@ -19,11 +19,11 @@
|
|||
#define LUA_VERSION_MAJOR "5"
|
||||
#define LUA_VERSION_MINOR "3"
|
||||
#define LUA_VERSION_NUM 503
|
||||
#define LUA_VERSION_RELEASE "2"
|
||||
#define LUA_VERSION_RELEASE "3"
|
||||
|
||||
#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-2015 Lua.org, PUC-Rio"
|
||||
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2016 Lua.org, PUC-Rio"
|
||||
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
|
||||
|
||||
|
||||
|
@ -361,7 +361,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
|
|||
#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
|
||||
|
||||
#define lua_pushglobaltable(L) \
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
|
||||
((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
|
||||
|
||||
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
|
||||
|
||||
|
@ -460,7 +460,7 @@ struct lua_Debug {
|
|||
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2015 Lua.org, PUC-Rio.
|
||||
* Copyright (C) 1994-2016 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: luaconf.h,v 1.254 2015/10/21 18:17:40 roberto Exp $
|
||||
** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $
|
||||
** Configuration file for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -612,7 +612,7 @@
|
|||
** provide its own implementation.
|
||||
*/
|
||||
#if !defined(LUA_USE_C89)
|
||||
#define lua_number2strx(L,b,sz,f,n) l_sprintf(b,sz,f,n)
|
||||
#define lua_number2strx(L,b,sz,f,n) ((void)L, l_sprintf(b,sz,f,n))
|
||||
#endif
|
||||
|
||||
|
||||
|
|
100
lua/src/lvm.c
100
lua/src/lvm.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lvm.c,v 2.265 2015/11/23 11:30:45 roberto Exp $
|
||||
** $Id: lvm.c,v 2.268 2016/02/05 19:59:14 roberto Exp $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -153,54 +153,67 @@ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
|
|||
|
||||
|
||||
/*
|
||||
** Complete a table access: if 't' is a table, 'tm' has its metamethod;
|
||||
** otherwise, 'tm' is NULL.
|
||||
** Finish the table access 'val = t[key]'.
|
||||
** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
|
||||
** t[k] entry (which must be nil).
|
||||
*/
|
||||
void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
|
||||
const TValue *tm) {
|
||||
const TValue *slot) {
|
||||
int loop; /* counter to avoid infinite loops */
|
||||
lua_assert(tm != NULL || !ttistable(t));
|
||||
const TValue *tm; /* metamethod */
|
||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||
if (tm == NULL) { /* no metamethod (from a table)? */
|
||||
if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
|
||||
if (slot == NULL) { /* 't' is not a table? */
|
||||
lua_assert(!ttistable(t));
|
||||
tm = luaT_gettmbyobj(L, t, TM_INDEX);
|
||||
if (ttisnil(tm))
|
||||
luaG_typeerror(L, t, "index"); /* no metamethod */
|
||||
/* else will try the metamethod */
|
||||
}
|
||||
if (ttisfunction(tm)) { /* metamethod is a function */
|
||||
else { /* 't' is a table */
|
||||
lua_assert(ttisnil(slot));
|
||||
tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
|
||||
if (tm == NULL) { /* no metamethod? */
|
||||
setnilvalue(val); /* result is nil */
|
||||
return;
|
||||
}
|
||||
/* else will try the metamethod */
|
||||
}
|
||||
if (ttisfunction(tm)) { /* is metamethod a function? */
|
||||
luaT_callTM(L, tm, t, key, val, 1); /* call it */
|
||||
return;
|
||||
}
|
||||
t = tm; /* else repeat access over 'tm' */
|
||||
if (luaV_fastget(L,t,key,tm,luaH_get)) { /* try fast track */
|
||||
setobj2s(L, val, tm); /* done */
|
||||
t = tm; /* else try to access 'tm[key]' */
|
||||
if (luaV_fastget(L,t,key,slot,luaH_get)) { /* fast track? */
|
||||
setobj2s(L, val, slot); /* done */
|
||||
return;
|
||||
}
|
||||
/* else repeat */
|
||||
/* else repeat (tail call 'luaV_finishget') */
|
||||
}
|
||||
luaG_runerror(L, "gettable chain too long; possible loop");
|
||||
luaG_runerror(L, "'__index' chain too long; possible loop");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Main function for table assignment (invoking metamethods if needed).
|
||||
** Compute 't[key] = val'
|
||||
** Finish a table assignment 't[key] = val'.
|
||||
** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
|
||||
** to the entry 't[key]', or to 'luaO_nilobject' if there is no such
|
||||
** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastset'
|
||||
** would have done the job.)
|
||||
*/
|
||||
void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
||||
StkId val, const TValue *oldval) {
|
||||
StkId val, const TValue *slot) {
|
||||
int loop; /* counter to avoid infinite loops */
|
||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||
const TValue *tm;
|
||||
if (oldval != NULL) {
|
||||
const TValue *tm; /* '__newindex' metamethod */
|
||||
if (slot != NULL) { /* is 't' a table? */
|
||||
Table *h = hvalue(t); /* save 't' table */
|
||||
lua_assert(ttisnil(oldval));
|
||||
/* must check the metamethod */
|
||||
if ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
|
||||
/* no metamethod; is there a previous entry in the table? */
|
||||
(oldval != luaO_nilobject ||
|
||||
/* no previous entry; must create one. (The next test is
|
||||
always true; we only need the assignment.) */
|
||||
(oldval = luaH_newkey(L, h, key), 1))) {
|
||||
lua_assert(ttisnil(slot)); /* old value must be nil */
|
||||
tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
|
||||
if (tm == NULL) { /* no metamethod? */
|
||||
if (slot == luaO_nilobject) /* 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 *, oldval), val);
|
||||
setobj2t(L, cast(TValue *, slot), val); /* set its new value */
|
||||
invalidateTMcache(h);
|
||||
luaC_barrierback(L, h, val);
|
||||
return;
|
||||
|
@ -217,11 +230,11 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
|||
return;
|
||||
}
|
||||
t = tm; /* else repeat assignment over 'tm' */
|
||||
if (luaV_fastset(L, t, key, oldval, luaH_get, val))
|
||||
if (luaV_fastset(L, t, key, slot, luaH_get, val))
|
||||
return; /* done */
|
||||
/* else loop */
|
||||
}
|
||||
luaG_runerror(L, "settable chain too long; possible loop");
|
||||
luaG_runerror(L, "'__newindex' chain too long; possible loop");
|
||||
}
|
||||
|
||||
|
||||
|
@ -739,18 +752,28 @@ void luaV_finishOp (lua_State *L) {
|
|||
luai_threadyield(L); }
|
||||
|
||||
|
||||
/* fetch an instruction and prepare its execution */
|
||||
#define vmfetch() { \
|
||||
i = *(ci->u.l.savedpc++); \
|
||||
if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) \
|
||||
Protect(luaG_traceexec(L)); \
|
||||
ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \
|
||||
lua_assert(base == ci->u.l.base); \
|
||||
lua_assert(base <= L->top && L->top < L->stack + L->stacksize); \
|
||||
}
|
||||
|
||||
#define vmdispatch(o) switch(o)
|
||||
#define vmcase(l) case l:
|
||||
#define vmbreak break
|
||||
|
||||
|
||||
/*
|
||||
** copy of 'luaV_gettable', but protecting call to potential metamethod
|
||||
** (which can reallocate the stack)
|
||||
** copy of 'luaV_gettable', but protecting the call to potential
|
||||
** metamethod (which can reallocate the stack)
|
||||
*/
|
||||
#define gettableProtected(L,t,k,v) { const TValue *aux; \
|
||||
if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \
|
||||
else Protect(luaV_finishget(L,t,k,v,aux)); }
|
||||
#define gettableProtected(L,t,k,v) { const TValue *slot; \
|
||||
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
|
||||
else Protect(luaV_finishget(L,t,k,v,slot)); }
|
||||
|
||||
|
||||
/* same for 'luaV_settable' */
|
||||
|
@ -773,14 +796,9 @@ void luaV_execute (lua_State *L) {
|
|||
base = ci->u.l.base; /* local copy of function's base */
|
||||
/* main loop of interpreter */
|
||||
for (;;) {
|
||||
Instruction i = *(ci->u.l.savedpc++);
|
||||
Instruction i;
|
||||
StkId ra;
|
||||
if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT))
|
||||
Protect(luaG_traceexec(L));
|
||||
/* WARNING: several calls may realloc the stack and invalidate 'ra' */
|
||||
ra = RA(i);
|
||||
lua_assert(base == ci->u.l.base);
|
||||
lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
|
||||
vmfetch();
|
||||
vmdispatch (GET_OPCODE(i)) {
|
||||
vmcase(OP_MOVE) {
|
||||
setobjs2s(L, ra, RB(i));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lvm.h,v 2.39 2015/09/09 13:44:07 roberto Exp $
|
||||
** $Id: lvm.h,v 2.40 2016/01/05 16:07:21 roberto Exp $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -49,25 +49,24 @@
|
|||
|
||||
|
||||
/*
|
||||
** fast track for 'gettable': 1 means 'aux' points to resulted value;
|
||||
** 0 means 'aux' is metamethod (if 't' is a table) or NULL. 'f' is
|
||||
** the raw get function to use.
|
||||
** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
|
||||
** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise,
|
||||
** return 0 (meaning it will have to check metamethod) with 'slot'
|
||||
** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
|
||||
** 'f' is the raw get function to use.
|
||||
*/
|
||||
#define luaV_fastget(L,t,k,aux,f) \
|
||||
#define luaV_fastget(L,t,k,slot,f) \
|
||||
(!ttistable(t) \
|
||||
? (aux = NULL, 0) /* not a table; 'aux' is NULL and result is 0 */ \
|
||||
: (aux = f(hvalue(t), k), /* else, do raw access */ \
|
||||
!ttisnil(aux) ? 1 /* result not nil? 'aux' has it */ \
|
||||
: (aux = fasttm(L, hvalue(t)->metatable, TM_INDEX), /* get metamethod */\
|
||||
aux != NULL ? 0 /* has metamethod? must call it */ \
|
||||
: (aux = luaO_nilobject, 1)))) /* else, final result is nil */
|
||||
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
|
||||
: (slot = f(hvalue(t), k), /* else, do raw access */ \
|
||||
!ttisnil(slot))) /* result not nil? */
|
||||
|
||||
/*
|
||||
** standard implementation for 'gettable'
|
||||
*/
|
||||
#define luaV_gettable(L,t,k,v) { const TValue *aux; \
|
||||
if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \
|
||||
else luaV_finishget(L,t,k,v,aux); }
|
||||
#define luaV_gettable(L,t,k,v) { const TValue *slot; \
|
||||
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
|
||||
else luaV_finishget(L,t,k,v,slot); }
|
||||
|
||||
|
||||
/*
|
||||
|
@ -100,9 +99,9 @@ LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
|
|||
LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
|
||||
LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
|
||||
LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
|
||||
StkId val, const TValue *tm);
|
||||
StkId val, const TValue *slot);
|
||||
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
||||
StkId val, const TValue *oldval);
|
||||
StkId val, const TValue *slot);
|
||||
LUAI_FUNC void luaV_finishOp (lua_State *L);
|
||||
LUAI_FUNC void luaV_execute (lua_State *L);
|
||||
LUAI_FUNC void luaV_concat (lua_State *L, int total);
|
||||
|
|
Loading…
Reference in a new issue