summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--README6
-rw-r--r--doc/Makefile9
-rw-r--r--doc/contents.html30
-rw-r--r--doc/manual.html490
-rw-r--r--doc/readme.html128
-rw-r--r--src/Makefile14
-rw-r--r--src/lapi.c50
-rw-r--r--src/lauxlib.c75
-rw-r--r--src/lauxlib.h5
-rw-r--r--src/lbaselib.c18
-rw-r--r--src/lbitlib.c82
-rw-r--r--src/ldebug.c18
-rw-r--r--src/ldo.c9
-rw-r--r--src/ldump.c15
-rw-r--r--src/lgc.c6
-rw-r--r--src/linit.c4
-rw-r--r--src/liolib.c4
-rw-r--r--src/llex.c14
-rw-r--r--src/lmathlib.c4
-rw-r--r--src/loadlib.c10
-rw-r--r--src/lobject.c19
-rw-r--r--src/lopcodes.c6
-rw-r--r--src/lopcodes.h9
-rw-r--r--src/loslib.c8
-rw-r--r--src/lparser.c27
-rw-r--r--src/lstate.c7
-rw-r--r--src/lstate.h7
-rw-r--r--src/lstrlib.c8
-rw-r--r--src/ltablib.c5
-rw-r--r--src/lua.c13
-rw-r--r--src/lua.h17
-rw-r--r--src/luac.c312
-rw-r--r--src/luaconf.h115
-rw-r--r--src/lualib.h6
-rw-r--r--src/lundump.c59
-rw-r--r--src/lundump.h15
-rw-r--r--src/lvm.c6
-rw-r--r--src/print.c229
-rw-r--r--test/hello.lua3
40 files changed, 1099 insertions, 765 deletions
diff --git a/Makefile b/Makefile
index cbc945d7..da62ab94 100644
--- a/Makefile
+++ b/Makefile
@@ -55,7 +55,7 @@ $(PLATS) clean:
cd src && $(MAKE) $@
test: dummy
- src/lua test/hello.lua
+ src/lua -v
install: dummy
cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD)
diff --git a/README b/README
index 78c83965..37c89345 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
-This is Lua 5.2 (work4), released on 30 July 2010.
+This is Lua 5.2 (work5), released on 30 Oct 2010.
-For information about Lua, including installation instructions and
-license details, see doc/readme.html.
+For installation instructions, license details, and
+further information about Lua, see doc/readme.html.
diff --git a/doc/Makefile b/doc/Makefile
deleted file mode 100644
index c9e98b55..00000000
--- a/doc/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-R= readme
-T= $R.txt
-H= $R.html
-
-$T: $H
- lynx -dump $? >$@
-
-clean:
- -rm -f $T
diff --git a/doc/contents.html b/doc/contents.html
index 397c6566..35b51d02 100644
--- a/doc/contents.html
+++ b/doc/contents.html
@@ -126,7 +126,7 @@ Freely available under the terms of the
<LI><A HREF="manual.html#6.10">6.10 &ndash; The Debug Library</A>
</UL>
<P>
-<LI><A HREF="manual.html#7">7 &ndash; Lua Stand-alone</A>
+<LI><A HREF="manual.html#7">7 &ndash; Lua Standalone</A>
<P>
<LI><A HREF="manual.html#8">8 &ndash; Incompatibilities with the Previous Version</A>
<UL>
@@ -172,15 +172,16 @@ Freely available under the terms of the
<A HREF="manual.html#pdf-xpcall">xpcall</A><BR>
<P>
-<A HREF="manual.html#pdf-bit.band">bit.band</A><BR>
-<A HREF="manual.html#pdf-bit.bnot">bit.bnot</A><BR>
-<A HREF="manual.html#pdf-bit.bor">bit.bor</A><BR>
-<A HREF="manual.html#pdf-bit.btest">bit.btest</A><BR>
-<A HREF="manual.html#pdf-bit.bxor">bit.bxor</A><BR>
-<A HREF="manual.html#pdf-bit.lshift">bit.lshift</A><BR>
-<A HREF="manual.html#pdf-bit.rol">bit.rol</A><BR>
-<A HREF="manual.html#pdf-bit.ror">bit.ror</A><BR>
-<A HREF="manual.html#pdf-bit.rshift">bit.rshift</A><BR>
+<A HREF="manual.html#pdf-bit32.AND">bit32.AND</A><BR>
+<A HREF="manual.html#pdf-bit32.NOT">bit32.NOT</A><BR>
+<A HREF="manual.html#pdf-bit32.OR">bit32.OR</A><BR>
+<A HREF="manual.html#pdf-bit32.ROL">bit32.ROL</A><BR>
+<A HREF="manual.html#pdf-bit32.ROR">bit32.ROR</A><BR>
+<A HREF="manual.html#pdf-bit32.SAR">bit32.SAR</A><BR>
+<A HREF="manual.html#pdf-bit32.SHL">bit32.SHL</A><BR>
+<A HREF="manual.html#pdf-bit32.SHR">bit32.SHR</A><BR>
+<A HREF="manual.html#pdf-bit32.TEST">bit32.TEST</A><BR>
+<A HREF="manual.html#pdf-bit32.XOR">bit32.XOR</A><BR>
<P>
<A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR>
@@ -326,6 +327,7 @@ Freely available under the terms of the
<A HREF="manual.html#lua_Number">lua_Number</A><BR>
<A HREF="manual.html#lua_Reader">lua_Reader</A><BR>
<A HREF="manual.html#lua_State">lua_State</A><BR>
+<A HREF="manual.html#lua_Unsigned">lua_Unsigned</A><BR>
<A HREF="manual.html#lua_Writer">lua_Writer</A><BR>
<P>
@@ -426,6 +428,8 @@ Freely available under the terms of the
<A HREF="manual.html#lua_topointer">lua_topointer</A><BR>
<A HREF="manual.html#lua_tostring">lua_tostring</A><BR>
<A HREF="manual.html#lua_tothread">lua_tothread</A><BR>
+<A HREF="manual.html#lua_tounsigned">lua_tounsigned</A><BR>
+<A HREF="manual.html#lua_tounsignedx">lua_tounsignedx</A><BR>
<A HREF="manual.html#lua_touserdata">lua_touserdata</A><BR>
<A HREF="manual.html#lua_type">lua_type</A><BR>
<A HREF="manual.html#lua_typename">lua_typename</A><BR>
@@ -465,6 +469,7 @@ Freely available under the terms of the
<A HREF="manual.html#luaL_checkstring">luaL_checkstring</A><BR>
<A HREF="manual.html#luaL_checktype">luaL_checktype</A><BR>
<A HREF="manual.html#luaL_checkudata">luaL_checkudata</A><BR>
+<A HREF="manual.html#luaL_checkunsigned">luaL_checkunsigned</A><BR>
<A HREF="manual.html#luaL_checkversion">luaL_checkversion</A><BR>
<A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR>
<A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR>
@@ -487,6 +492,7 @@ Freely available under the terms of the
<A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR>
<A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR>
<A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR>
+<A HREF="manual.html#luaL_optunsigned">luaL_optunsigned</A><BR>
<A HREF="manual.html#luaL_prepbuffer">luaL_prepbuffer</A><BR>
<A HREF="manual.html#luaL_pushresult">luaL_pushresult</A><BR>
<A HREF="manual.html#luaL_ref">luaL_ref</A><BR>
@@ -506,10 +512,10 @@ Freely available under the terms of the
<HR>
<SMALL>
Last update:
-Fri Jul 30 15:13:14 BRT 2010
+Sat Oct 30 21:34:44 BRST 2010
</SMALL>
<!--
-Last change: revised for Lua 5.2.0 (work4)
+Last change: revised for Lua 5.2.0 (work5)
-->
</BODY>
diff --git a/doc/manual.html b/doc/manual.html
index d5220c11..c97b88c1 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -38,12 +38,12 @@ Freely available under the terms of the
<!-- ====================================================================== -->
<p>
-<!-- $Id: manual.of,v 1.58 2010/07/30 19:05:32 roberto Exp $ -->
+<!-- $Id: manual.of,v 1.61 2010/10/29 12:51:39 roberto Exp $ -->
-<h1>1 - <a name="1">Introduction</a></h1>
+<h1>1 &ndash; <a name="1">Introduction</a></h1>
<p>
Lua is an extension programming language designed to support
@@ -68,7 +68,7 @@ Through the use of C&nbsp;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, stand-alone Lua interpreter.
+which uses the Lua library to offer a complete, standalone Lua interpreter.
<p>
@@ -89,14 +89,14 @@ see Roberto's book, <em>Programming in Lua (Second Edition)</em>.
-<h1>2 - <a name="2">Basic Concepts</a></h1>
+<h1>2 &ndash; <a name="2">Basic Concepts</a></h1>
<p>
This section describes some basic concepts of the language.
-<h2>2.1 - <a name="2.1">Values and Types</a></h2>
+<h2>2.1 &ndash; <a name="2.1">Values and Types</a></h2>
<p>
Lua is a <em>dynamically typed language</em>.
@@ -205,14 +205,29 @@ of a given value.
-<h2>2.2 - <a name="2.2">Environments and the Global Environment</a></h2>
+<h2>2.2 &ndash; <a name="2.2">Environments and the Global Environment</a></h2>
<p>
As discussed in <a href="#3.2">&sect;3.2</a> and <a href="#3.3.3">&sect;3.3.3</a>,
any reference to a global name <code>var</code> is syntactically translated
to <code>_ENV.var</code>.
Moreover, any chunk is compiled in the scope of an external
-variable called <code>_ENV</code> (see <a href="#3.3.2">&sect;3.3.2</a>).
+variable called <code>_ENV</code> (see <a href="#3.3.2">&sect;3.3.2</a>),
+so <code>_ENV</code> itself is never a global name in a chunk.
+
+
+<p>
+Despite the existence of this external <code>_ENV</code> variable and
+the translation of global names,
+<code>_ENV</code> is a completely regular name.
+In particular,
+you can define new variables and parameters with that name.
+Each reference to a global name uses the <code>_ENV</code> that is
+visible at that point in the program,
+following the usual visibility rules of Lua.
+
+
+<p>
Any table used as the value of <code>_ENV</code> is usually called
an <em>environment</em>.
@@ -250,7 +265,7 @@ is never updated by Lua.
-<h2>2.3 - <a name="2.3">Error Handling</a></h2>
+<h2>2.3 &ndash; <a name="2.3">Error Handling</a></h2>
<p>
Because Lua is an embedded extension language,
@@ -272,7 +287,7 @@ you can use the <a href="#pdf-pcall"><code>pcall</code></a> function.
-<h2>2.4 - <a name="2.4">Metatables</a></h2>
+<h2>2.4 &ndash; <a name="2.4">Metatables</a></h2>
<p>
Every value in Lua can have a <em>metatable</em>.
@@ -282,7 +297,7 @@ under certain special operations.
You can change several aspects of the behavior
of operations over a value by setting specific fields in its metatable.
For instance, when a non-numeric value is the operand of an addition,
-Lua checks for a function in the field <code>"__add"</code> in its metatable.
+Lua checks for a function in the field "<code>__add</code>" in its metatable.
If it finds one,
Lua calls this function to perform the addition.
@@ -337,7 +352,7 @@ Each operation is identified by its corresponding name.
The key for each operation 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>.
+string "<code>__add</code>".
The semantics of these operations is better explained by a Lua function
describing how the interpreter executes the operation.
@@ -684,7 +699,7 @@ called when Lua calls a value.
-<h2>2.5 - <a name="2.5">Garbage Collection</a></h2>
+<h2>2.5 &ndash; <a name="2.5">Garbage Collection</a></h2>
<p>
Lua performs automatic memory management.
@@ -748,7 +763,7 @@ the collector directly (e.g., stop and restart it).
-<h3>2.5.1 - <a name="2.5.1">Garbage-Collection Metamethods</a></h3>
+<h3>2.5.1 &ndash; <a name="2.5.1">Garbage-Collection Metamethods</a></h3>
<p>
Using the C&nbsp;API,
@@ -761,9 +776,22 @@ or freeing your own memory).
<p>
-Garbage userdata with a field <code>__gc</code> in their metatables are not
-collected immediately by the garbage collector.
-Instead, Lua puts them in a list.
+For a userdata to be finalized when collected,
+you must <em>mark</em> it first.
+
+You mark a userdata for finalization when you set its metatable
+and the metatable has a field indexed by the string "<code>__gc</code>".
+Note that if you set a metatable without a <code>__gc</code> field
+and later create that field,
+the userdata will not be marked for finalization.
+However, after a userdata is marked,
+you can freely change the <code>__gc</code> field of its metatable.
+
+
+<p>
+When a marked userdata becomes garbage,
+it is not collected immediately by the garbage collector.
+Instead, Lua puts it in a list.
After the collection,
Lua does the equivalent of the following function
for each userdata in that list:
@@ -771,7 +799,7 @@ for each userdata in that list:
<pre>
function gc_event (udata)
local h = metatable(udata).__gc
- if h then
+ if type(h) == "function" then
h(udata)
end
end
@@ -779,18 +807,18 @@ for each userdata in that list:
<p>
At the end of each garbage-collection cycle,
-the finalizers for userdata are called in <em>reverse</em>
-order of their creation,
-among those collected in that cycle.
-That is, the first finalizer to be called is the one associated
-with the userdata created last in the program.
-The userdata itself is freed only in the next garbage-collection cycle.
+the finalizers for userdata are called in
+the reverse order that they were marked for collection,
+among those collected in that cycle;
+that is, the first finalizer to be called is the one associated
+with the userdata marked last in the program.
+The userdata memory is freed only in the next garbage-collection cycle.
-<h3>2.5.2 - <a name="2.5.2">Weak Tables</a></h3>
+<h3>2.5.2 &ndash; <a name="2.5.2">Weak Tables</a></h3>
<p>
A <em>weak table</em> is a table whose elements are
@@ -823,7 +851,7 @@ is also called an <em>ephemeron table</em>.
In an ephemeron table,
a value is considered reachable only if its key is reachable.
In particular,
-if the only reference to a key comes from its value,
+if the only reference to a key comes through its value,
the pair is removed.
@@ -845,8 +873,8 @@ Lua treats strings and light C functions as non-object values.
<p>
-Userdata with finalizers has a special behavior in weak tables.
-When a userdata is a value in a weak table,
+Userdata marked for finalization has a special behavior in weak tables.
+When a marked userdata is a value in a weak table,
it is removed from the table the first time it is collected,
before running its finalizer.
When it is a key, however,
@@ -861,7 +889,7 @@ associated with the userdata through weak tables.
-<h2>2.6 - <a name="2.6">Coroutines</a></h2>
+<h2>2.6 &ndash; <a name="2.6">Coroutines</a></h2>
<p>
Lua supports coroutines,
@@ -980,7 +1008,7 @@ and <a href="#lua_yield"><code>lua_yield</code></a>.
-<h1>3 - <a name="3">The Language</a></h1>
+<h1>3 &ndash; <a name="3">The Language</a></h1>
<p>
This section describes the lexis, the syntax, and the semantics of Lua.
@@ -1004,7 +1032,7 @@ at the end of this manual.
-<h2>3.1 - <a name="3.1">Lexical Conventions</a></h2>
+<h2>3.1 &ndash; <a name="3.1">Lexical Conventions</a></h2>
<p>
Lua is a free-form language.
@@ -1073,7 +1101,7 @@ results in a newline in the string.
The escape sequence '<code>\*</code>' skips the following span
of white-space characters,
including line breaks;
-it is particularly useful to break and ident a string
+it is particularly useful to break and indent a long string
into multiple lines without adding the newlines and spaces
into the string contents.
@@ -1161,7 +1189,7 @@ Long comments are frequently used to disable code temporarily.
-<h2>3.2 - <a name="3.2">Variables</a></h2>
+<h2>3.2 &ndash; <a name="3.2">Variables</a></h2>
<p>
Variables are places that store values.
@@ -1226,7 +1254,7 @@ Due to the way that chunks are compiled,
-<h2>3.3 - <a name="3.3">Statements</a></h2>
+<h2>3.3 &ndash; <a name="3.3">Statements</a></h2>
<p>
Lua supports an almost conventional set of statements,
@@ -1237,7 +1265,7 @@ and variable declarations.
-<h3>3.3.1 - <a name="3.3.1">Blocks</a></h3>
+<h3>3.3.1 &ndash; <a name="3.3.1">Blocks</a></h3>
<p>
A block is a list of statements,
@@ -1271,7 +1299,7 @@ of another block (see <a href="#3.3.4">&sect;3.3.4</a>).
-<h3>3.3.2 - <a name="3.3.2">Chunks</a></h3>
+<h3>3.3.2 &ndash; <a name="3.3.2">Chunks</a></h3>
<p>
The unit of execution of Lua is called a <em>chunk</em>.
@@ -1290,6 +1318,8 @@ As such, chunks can define local variables,
receive arguments, and return values.
Moreover, such anonymous function is compiled as in the
scope of an external local variable called <code>_ENV</code> (see <a href="#2.2">&sect;2.2</a>).
+The resulting function always has <code>_ENV</code> as its only upvalue,
+even if it does not use that variable.
<p>
@@ -1311,7 +1341,7 @@ Lua automatically detects the file type and acts accordingly.
-<h3>3.3.3 - <a name="3.3.3">Assignment</a></h3>
+<h3>3.3.3 &ndash; <a name="3.3.3">Assignment</a></h3>
<p>
Lua allows multiple assignments.
@@ -1388,7 +1418,7 @@ is equivalent to the assignment
-<h3>3.3.4 - <a name="3.3.4">Control Structures</a></h3><p>
+<h3>3.3.4 &ndash; <a name="3.3.4">Control Structures</a></h3><p>
The control structures
<b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and
familiar syntax:
@@ -1458,7 +1488,7 @@ their (inner) blocks.
-<h3>3.3.5 - <a name="3.3.5">For Statement</a></h3>
+<h3>3.3.5 &ndash; <a name="3.3.5">For Statement</a></h3>
<p>
@@ -1589,7 +1619,7 @@ then assign them to other variables before breaking or exiting the loop.
-<h3>3.3.6 - <a name="3.3.6">Function Calls as Statements</a></h3><p>
+<h3>3.3.6 &ndash; <a name="3.3.6">Function Calls as Statements</a></h3><p>
To allow possible side-effects,
function calls can be executed as statements:
@@ -1603,7 +1633,7 @@ Function calls are explained in <a href="#3.4.9">&sect;3.4.9</a>.
-<h3>3.3.7 - <a name="3.3.7">Local Declarations</a></h3><p>
+<h3>3.3.7 &ndash; <a name="3.3.7">Local Declarations</a></h3><p>
Local variables can be declared anywhere inside a block.
The declaration can include an initial assignment:
@@ -1630,7 +1660,7 @@ The visibility rules for local variables are explained in <a href="#3.5">&sect;3
-<h2>3.4 - <a name="3.4">Expressions</a></h2>
+<h2>3.4 &ndash; <a name="3.4">Expressions</a></h2>
<p>
The basic expressions in Lua are the following:
@@ -1716,7 +1746,7 @@ or <b>nil</b> if <code>f</code> does not return any values.)
-<h3>3.4.1 - <a name="3.4.1">Arithmetic Operators</a></h3><p>
+<h3>3.4.1 &ndash; <a name="3.4.1">Arithmetic Operators</a></h3><p>
Lua supports the usual arithmetic operators:
the binary <code>+</code> (addition),
<code>-</code> (subtraction), <code>*</code> (multiplication),
@@ -1739,7 +1769,7 @@ the quotient towards minus infinity.
-<h3>3.4.2 - <a name="3.4.2">Coercion</a></h3>
+<h3>3.4.2 &ndash; <a name="3.4.2">Coercion</a></h3>
<p>
Lua provides automatic conversion between
@@ -1756,7 +1786,7 @@ use the <code>format</code> function from the string library
-<h3>3.4.3 - <a name="3.4.3">Relational Operators</a></h3><p>
+<h3>3.4.3 &ndash; <a name="3.4.3">Relational Operators</a></h3><p>
The relational operators in Lua are
<pre>
@@ -1812,7 +1842,7 @@ and <code>a &gt;= b</code> is translated to <code>b &lt;= a</code>.
-<h3>3.4.4 - <a name="3.4.4">Logical Operators</a></h3><p>
+<h3>3.4.4 &ndash; <a name="3.4.4">Logical Operators</a></h3><p>
The logical operators in Lua are
<b>and</b>, <b>or</b>, and <b>not</b>.
Like the control structures (see <a href="#3.3.4">&sect;3.3.4</a>),
@@ -1850,7 +1880,7 @@ Here are some examples:
-<h3>3.4.5 - <a name="3.4.5">Concatenation</a></h3><p>
+<h3>3.4.5 &ndash; <a name="3.4.5">Concatenation</a></h3><p>
The string concatenation operator in Lua is
denoted by two dots ('<code>..</code>').
If both operands are strings or numbers, then they are converted to
@@ -1861,7 +1891,7 @@ Otherwise, the "concat" metamethod is called (see <a href="#2.4">&sect;2.4</a>).
-<h3>3.4.6 - <a name="3.4.6">The Length Operator</a></h3>
+<h3>3.4.6 &ndash; <a name="3.4.6">The Length Operator</a></h3>
<p>
The length operator is denoted by the unary prefix operator <code>#</code>.
@@ -1895,7 +1925,7 @@ any value but strings through metamethods (see <a href="#2.4">&sect;2.4</a>).
-<h3>3.4.7 - <a name="3.4.7">Precedence</a></h3><p>
+<h3>3.4.7 &ndash; <a name="3.4.7">Precedence</a></h3><p>
Operator precedence in Lua follows the table below,
from lower to higher priority:
@@ -1919,7 +1949,7 @@ All other binary operators are left associative.
-<h3>3.4.8 - <a name="3.4.8">Table Constructors</a></h3><p>
+<h3>3.4.8 &ndash; <a name="3.4.8">Table Constructors</a></h3><p>
Table constructors are expressions that create tables.
Every time a constructor is evaluated, a new table is created.
A constructor can be used to create an empty table
@@ -1981,7 +2011,7 @@ as a convenience for machine-generated code.
-<h3>3.4.9 - <a name="3.4.9">Function Calls</a></h3><p>
+<h3>3.4.9 &ndash; <a name="3.4.9">Function Calls</a></h3><p>
A function call in Lua has the following syntax:
<pre>
@@ -2056,7 +2086,7 @@ So, none of the following examples are tail calls:
-<h3>3.4.10 - <a name="3.4.10">Function Definitions</a></h3>
+<h3>3.4.10 &ndash; <a name="3.4.10">Function Definitions</a></h3>
<p>
The syntax for function definition is
@@ -2206,7 +2236,7 @@ is syntactic sugar for
-<h2>3.5 - <a name="3.5">Visibility Rules</a></h2>
+<h2>3.5 &ndash; <a name="3.5">Visibility Rules</a></h2>
<p>
@@ -2268,7 +2298,7 @@ while all of them share the same <code>x</code>.
-<h1>4 - <a name="4">The Application Program Interface</a></h1>
+<h1>4 &ndash; <a name="4">The Application Program Interface</a></h1>
<p>
@@ -2296,7 +2326,7 @@ in file <code>luaconf.h</code>.
-<h2>4.1 - <a name="4.1">The Stack</a></h2>
+<h2>4.1 &ndash; <a name="4.1">The Stack</a></h2>
<p>
Lua uses a <em>virtual stack</em> to pass values to and from C.
@@ -2338,10 +2368,10 @@ if it lies between&nbsp;1 and the stack top
-<h2>4.2 - <a name="4.2">Stack Size</a></h2>
+<h2>4.2 &ndash; <a name="4.2">Stack Size</a></h2>
<p>
-When you interact with Lua API,
+When you interact with the Lua API,
you are responsible for ensuring consistency.
In particular,
<em>you are responsible for controlling stack overflow</em>.
@@ -2384,7 +2414,7 @@ Note that 0 is never an acceptable index.
-<h2>4.3 - <a name="4.3">Pseudo-Indices</a></h2>
+<h2>4.3 &ndash; <a name="4.3">Pseudo-Indices</a></h2>
<p>
Unless otherwise noted,
@@ -2399,7 +2429,7 @@ and the upvalues of a C&nbsp;function (see <a href="#4.4">&sect;4.4</a>).
-<h2>4.4 - <a name="4.4">C Closures</a></h2>
+<h2>4.4 &ndash; <a name="4.4">C Closures</a></h2>
<p>
When a C&nbsp;function is created,
@@ -2426,7 +2456,7 @@ produces an acceptable (but invalid) index.
-<h2>4.5 - <a name="4.5">Registry</a></h2>
+<h2>4.5 &ndash; <a name="4.5">Registry</a></h2>
<p>
Lua provides a <em>registry</em>,
@@ -2437,8 +2467,12 @@ This table is always located at pseudo-index
Any C&nbsp;library can store data into this table,
but it should take care to choose keys different from those used
by other libraries, to avoid collisions.
-Typically, you should use as key a string containing your library name
-or a light userdata with the address of a C&nbsp;object in your code.
+Typically, you should use as key a string containing your library name,
+or a light userdata with the address of a C&nbsp;object in your code,
+or any Lua object created by your code.
+As with global names,
+string keys starting with an underscore followed by
+uppercase letters are reserved for Lua.
<p>
@@ -2470,7 +2504,7 @@ This is the C&nbsp;equivalent to the <a href="#pdf-_G"><code>_G</code></a> globa
-<h2>4.6 - <a name="4.6">Error Handling in C</a></h2>
+<h2>4.6 &ndash; <a name="4.6">Error Handling in C</a></h2>
<p>
Internally, Lua uses the C <code>longjmp</code> facility to handle errors.
@@ -2509,7 +2543,7 @@ Inside a C&nbsp;function you can throw an error by calling <a href="#lua_error">
-<h2>4.7 - <a name="4.7">Handling Yields in C</a></h2>
+<h2>4.7 &ndash; <a name="4.7">Handling Yields in C</a></h2>
<p>
Internally, Lua uses the C <code>longjmp</code> facility to yield a coroutine.
@@ -2522,7 +2556,7 @@ because the <code>longjmp</code> removes its frame from the C stack.
<p>
To avoid this kind of problem,
-Lua raises an error whenever it tries to yield accross an API call,
+Lua raises an error whenever it tries to yield across an API call,
except for three functions:
<a href="#lua_yieldk"><code>lua_yieldk</code></a>, <a href="#lua_callk"><code>lua_callk</code></a>, and <a href="#lua_pcallk"><code>lua_pcallk</code></a>.
All those functions receive a <em>continuation function</em>
@@ -2577,7 +2611,7 @@ and its continuation is the result of a call to <a href="#lua_getctx"><code>lua_
-<h2>4.8 - <a name="4.8">Functions and Types</a></h2>
+<h2>4.8 &ndash; <a name="4.8">Functions and Types</a></h2>
<p>
Here we list all functions and types from the C&nbsp;API in
@@ -2731,7 +2765,7 @@ The value of <code>op</code> must be one of the following constants:
<li><b><a name="pdf-LUA_OPMUL"><code>LUA_OPMUL</code></a>:</b>performs multiplication (<code>*</code>)</li>
<li><b><a name="pdf-LUA_OPDIV"><code>LUA_OPDIV</code></a>:</b>performs division (<code>/</code>)</li>
<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_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>
</ul>
@@ -3264,7 +3298,7 @@ because a pseudo-index is not an actual stack position.
<pre>typedef ptrdiff_t lua_Integer;</pre>
<p>
-The type used by the Lua API to represent integral values.
+The type used by the Lua API to represent signed integral values.
<p>
@@ -3493,8 +3527,8 @@ which is used for error messages and in debug information (see <a href="#4.9">&s
<p>
-If the resulting function has upvalues,
-the first upvalue is set to the value of the global environment
+If the resulting function has one upvalue,
+this upvalue is set to the value of the global environment
stored at index <code>LUA_RIDX_GLOBALS</code> in the registry (see <a href="#4.5">&sect;4.5</a>).
(When loading main chunks,
this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).)
@@ -4334,7 +4368,7 @@ or <a name="pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the thread is suspended
You can only call functions in threads with status <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>.
You can resume threads with status <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>
(to start a new coroutine) or <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a>
-(to resume a corotine).
+(to resume a coroutine).
@@ -4517,6 +4551,46 @@ otherwise, the function returns <code>NULL</code>.
+<hr><h3><a name="lua_tounsigned"><code>lua_tounsigned</code></a></h3><p>
+<span class="apii">[-0, +0, <em>-</em>]</span>
+<pre>lua_Unsigned lua_tounsigned (lua_State *L, int index);</pre>
+
+<p>
+A macro equivalent to <code>lua_tounsignedx(L, index, NULL)</code>.
+
+
+
+
+
+<hr><h3><a name="lua_tounsignedx"><code>lua_tounsignedx</code></a></h3><p>
+<span class="apii">[-0, +0, <em>-</em>]</span>
+<pre>lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);</pre>
+
+<p>
+Converts the Lua value at the given acceptable index
+to the unsigned integral type <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
+The Lua value must be a number or a string convertible to a number
+(see <a href="#3.4.2">&sect;3.4.2</a>);
+otherwise, <a href="#lua_tounsignedx"><code>lua_tounsignedx</code></a> returns&nbsp;0.
+
+
+<p>
+If the number is not an integer,
+it is truncated in some non-specified way.
+If the number is outside the range of representable values,
+it is normalized to the remainder of its division by
+one more than the maximum representable value.
+
+
+<p>
+If <code>isnum</code> is different from <code>NULL</code>,
+its referent is assigned a boolean value that
+indicates whether the operation succeeded.
+
+
+
+
+
<hr><h3><a name="lua_touserdata"><code>lua_touserdata</code></a></h3><p>
<span class="apii">[-0, +0, <em>-</em>]</span>
<pre>void *lua_touserdata (lua_State *L, int index);</pre>
@@ -4569,6 +4643,22 @@ which must be one the values returned by <a href="#lua_type"><code>lua_type</cod
+<hr><h3><a name="lua_Unsigned"><code>lua_Unsigned</code></a></h3>
+<pre>typedef unsigned long lua_Unsigned;</pre>
+
+<p>
+The type used by the Lua API to represent unsigned integral values.
+It must have at least 32 bits.
+
+
+<p>
+By default it is an <code>unsigned int</code> or an <code>unsigned long</code>,
+whichever can hold 32-bit values.
+
+
+
+
+
<hr><h3><a name="lua_version"><code>lua_version</code></a></h3><p>
<span class="apii">[-0, +0, <em>v</em>]</span>
<pre>const lua_Number *lua_version (lua_State *L);</pre>
@@ -4681,7 +4771,7 @@ by calling <a href="#lua_getctx"><code>lua_getctx</code></a>.
-<h2>4.9 - <a name="4.9">The Debug Interface</a></h2>
+<h2>4.9 &ndash; <a name="4.9">The Debug Interface</a></h2>
<p>
Lua has no built-in debugging facilities.
@@ -5165,16 +5255,19 @@ will return identical ids for those upvalue indices.
<hr><h3><a name="lua_upvaluejoin"><code>lua_upvaluejoin</code></a></h3>
<pre>void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
- int fidx2, int n2);</pre><p>
-TO BE DONE!!
+ int fidx2, int n2);</pre>
+<p>
+Make the <code>n1</code>-th upvalue of the Lua closure at index <code>fidx1</code>
+refer to the <code>n2</code>-th upvalue of the Lua closure at index <code>fidx2</code>.
-<h1>5 - <a name="5">The Auxiliary Library</a></h1>
+
+<h1>5 &ndash; <a name="5">The Auxiliary Library</a></h1>
<p>
@@ -5220,7 +5313,7 @@ always throw an error if the check is not satisfied.
-<h2>5.1 - <a name="5.1">Functions and Types</a></h2>
+<h2>5.1 &ndash; <a name="5.1">Functions and Types</a></h2>
<p>
Here we list all functions and types from the auxiliary library
@@ -5591,6 +5684,18 @@ returns the userdata address (see <a href="#lua_touserdata"><code>lua_touserdata
+<hr><h3><a name="luaL_checkunsigned"><code>luaL_checkunsigned</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>lua_Unsigned luaL_checkunsigned (lua_State *L, int narg);</pre>
+
+<p>
+Checks whether the function argument <code>narg</code> is a number
+and returns this number cast to a <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
+
+
+
+
+
<hr><h3><a name="luaL_checkversion"><code>luaL_checkversion</code></a></h3><p>
<span class="apii">[-0, +0, <em>-</em>]</span>
<pre>void *luaL_checkversion (lua_State *L);</pre>
@@ -5959,7 +6064,7 @@ Otherwise, raises an error.
<p>
If <code>l</code> is not <code>NULL</code>,
-fills the position <code>*l</code> with the results's length.
+fills the position <code>*l</code> with the result's length.
@@ -5997,6 +6102,23 @@ Otherwise, raises an error.
+<hr><h3><a name="luaL_optunsigned"><code>luaL_optunsigned</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>lua_Unsigned luaL_optunsigned (lua_State *L,
+ int narg,
+ lua_Unsigned u);</pre>
+
+<p>
+If the function argument <code>narg</code> is a number,
+returns this number cast to a <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
+If this argument is absent or is <b>nil</b>,
+returns <code>u</code>.
+Otherwise, raises an error.
+
+
+
+
+
<hr><h3><a name="luaL_prepbuffer"><code>luaL_prepbuffer</code></a></h3><p>
<span class="apii">[-0, +0, <em>-</em>]</span>
<pre>char *luaL_prepbuffer (luaL_Buffer *B);</pre>
@@ -6222,7 +6344,7 @@ This function is used to build a prefix for error messages.
-<h1>6 - <a name="6">Standard Libraries</a></h1>
+<h1>6 &ndash; <a name="6">Standard Libraries</a></h1>
<p>
The standard Lua libraries provide useful functions
@@ -6291,7 +6413,7 @@ e.g., by using <a href="#lua_call"><code>lua_call</code></a>.
-<h2>6.1 - <a name="6.1">Basic Functions</a></h2>
+<h2>6.1 &ndash; <a name="6.1">Basic Functions</a></h2>
<p>
The basic library provides some core functions to Lua.
@@ -6513,7 +6635,8 @@ The default is "<code>bt</code>".
This function is similar to <a href="#pdf-load"><code>load</code></a>,
but sets <code>env</code> as the value of the first upvalue
of the created function in case of success.
-(Usually this first upvalue will be <code>_ENV</code> (see <a href="#2.2">&sect;2.2</a>).)
+(When loading main chunks,
+this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).)
The parameters after <code>env</code> are similar to those of <a href="#pdf-load"><code>load</code></a>, too.
@@ -6797,7 +6920,7 @@ except that it sets a new error handler <code>err</code>.
-<h2>6.2 - <a name="6.2">Coroutine Manipulation</a></h2>
+<h2>6.2 &ndash; <a name="6.2">Coroutine Manipulation</a></h2>
<p>
The operations related to coroutines comprise a sub-library of
@@ -6907,7 +7030,7 @@ Any arguments to <code>yield</code> are passed as extra results to <code>resume<
-<h2>6.3 - <a name="6.3">Modules</a></h2>
+<h2>6.3 &ndash; <a name="6.3">Modules</a></h2>
<p>
The package library provides basic
@@ -6954,9 +7077,9 @@ it tries an <em>all-in-one</em> loader (see <a href="#pdf-package.loaders"><code
<p>
Once a loader is found,
<code>require</code> calls the loader with a single argument, <code>modname</code>.
-If the loader returns any value,
+If the loader returns any non-nil value,
<code>require</code> assigns the returned value to <code>package.loaded[modname]</code>.
-If the loader returns no value and
+If the loader does not return a non-nil value and
has not assigned any value to <code>package.loaded[modname]</code>,
then <code>require</code> assigns <b>true</b> to this entry.
In any case, <code>require</code> returns the
@@ -6995,7 +7118,7 @@ Default is '<code>?</code>'.</li>
is replaced by the executable's directory.
Default is '<code>!</code>'.</li>
-<li>The fifth line is a mark to ignore all before it when bulding the
+<li>The fifth line is a mark to ignore all before it when building the
<code>luaopen_</code> function name.
Default is '<code>-</code>'.</li>
@@ -7227,7 +7350,7 @@ or <b>nil</b> plus an error message if none succeeds.
-<h2>6.4 - <a name="6.4">String Manipulation</a></h2>
+<h2>6.4 &ndash; <a name="6.4">String Manipulation</a></h2>
<p>
This library provides generic functions for string manipulation,
@@ -7556,7 +7679,7 @@ The definition of what a lowercase letter is depends on the current locale.
-<h3>6.4.1 - <a name="6.4.1">Patterns</a></h3>
+<h3>6.4.1 &ndash; <a name="6.4.1">Patterns</a></h3>
<h4>Character Class:</h4><p>
@@ -7605,7 +7728,8 @@ when used to represent itself in a pattern.
represents the class which is the union of all
characters in <em>set</em>.
A range of characters can be specified by
-separating the end characters of the range with a '<code>-</code>'.
+separating the end characters of the range,
+in ascending order, with a '<code>-</code>',
All classes <code>%</code><em>x</em> described above can also be used as
components in <em>set</em>.
All other characters in <em>set</em> represent themselves.
@@ -7699,7 +7823,7 @@ such item matches an empty string at any position such that
the next character belongs to <em>set</em>
and the previous character does not belong to <em>set</em>.
The set <em>set</em> is interpreted as previously described.
-The beggining and the end of the subject are handled as if
+The beginning and the end of the subject are handled as if
they were the character '<code>\0</code>'.
</li>
@@ -7750,7 +7874,7 @@ string <code>"flaaap"</code>, there will be two captures: 3&nbsp;and&nbsp;5.
-<h2>6.5 - <a name="6.5">Table Manipulation</a></h2><p>
+<h2>6.5 &ndash; <a name="6.5">Table Manipulation</a></h2><p>
This library provides generic functions for table manipulation.
It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>.
@@ -7858,7 +7982,7 @@ as defined by the length operator (see <a href="#3.4.6">&sect;3.4.6</a>).
-<h2>6.6 - <a name="6.6">Mathematical Functions</a></h2>
+<h2>6.6 &ndash; <a name="6.6">Mathematical Functions</a></h2>
<p>
This library is an interface to the standard C&nbsp;math library.
@@ -8187,22 +8311,30 @@ Returns the hyperbolic tangent of <code>x</code>.
-<h2>6.7 - <a name="6.7">Bitwise operations</a></h2>
+<h2>6.7 &ndash; <a name="6.7">Bitwise operations</a></h2>
<p>
This library provides bitwise operations.
-It provides all its functions inside the table <a name="pdf-bit"><code>bit</code></a>.
+It provides all its functions inside the table <a name="pdf-bit32"><code>bit32</code></a>.
+It uses upper case for function names to avoid collision with
+some reserved words (<b>and</b>, <b>or</b>, and <b>not</b>).
+
+
+<p>
Unless otherwise stated,
-all functions accept as arguments and return numbers
-in the range <em>[0,2^32 - 1]</em>.
-Standard Lua does not use 2-complement representation for numbers,
-so in standard Lua (that is, with floating-point numbers) you
-cannot use negative numbers with this library.
-In particular, -1 is not the same as 0xffffffff.
+all functions accept numeric arguments in the range
+<em>(-2<sup>51</sup>,+2<sup>51</sup>)</em>;
+each argument is normalized to
+the remainder of its division by <em>2<sup>32</sup></em>
+and truncated to an integer (in some unspecified way),
+so that its final value falls in the range <em>[0,2<sup>32</sup> - 1]</em>.
+Similarly, all results are in the range <em>[0,2<sup>32</sup> - 1]</em>.
+Note that <code>bit32.NOT(0)</code> is <code>0xFFFFFFFF</code>,
+which is different from <code>-1</code>.
<p>
-<hr><h3><a name="pdf-bit.band"><code>bit.band (&middot;&middot;&middot;)</code></a></h3>
+<hr><h3><a name="pdf-bit32.AND"><code>bit32.AND (&middot;&middot;&middot;)</code></a></h3>
<p>
@@ -8212,22 +8344,22 @@ Returns the bitwise and of its operands.
<p>
-<hr><h3><a name="pdf-bit.bnot"><code>bit.bnot (x)</code></a></h3>
+<hr><h3><a name="pdf-bit32.NOT"><code>bit32.NOT (x)</code></a></h3>
<p>
Returns the bitwise negation of <code>x</code>.
-For any valid <code>x</code>,
+For any integer <code>x</code>,
the following identity holds:
<pre>
- assert(bit.bnot(x) == 2^32 - 1 - x)
+ assert(bit32.NOT(x) == (-1 - x) % 2^32)
</pre>
<p>
-<hr><h3><a name="pdf-bit.bor"><code>bit.bor (&middot;&middot;&middot;)</code></a></h3>
+<hr><h3><a name="pdf-bit32.OR"><code>bit32.OR (&middot;&middot;&middot;)</code></a></h3>
<p>
@@ -8237,7 +8369,7 @@ Returns the bitwise or of its operands.
<p>
-<hr><h3><a name="pdf-bit.btest"><code>bit.btest (&middot;&middot;&middot;)</code></a></h3>
+<hr><h3><a name="pdf-bit32.TEST"><code>bit32.TEST (&middot;&middot;&middot;)</code></a></h3>
<p>
@@ -8248,7 +8380,7 @@ whether the bitwise and of its operands is different from zero.
<p>
-<hr><h3><a name="pdf-bit.bxor"><code>bit.bxor (&middot;&middot;&middot;)</code></a></h3>
+<hr><h3><a name="pdf-bit32.XOR"><code>bit32.XOR (&middot;&middot;&middot;)</code></a></h3>
<p>
@@ -8258,36 +8390,33 @@ Returns the bitwise exclusive or of its operands.
<p>
-<hr><h3><a name="pdf-bit.lshift"><code>bit.lshift (x, disp)</code></a></h3>
+<hr><h3><a name="pdf-bit32.ROL"><code>bit32.ROL (x, disp)</code></a></h3>
<p>
-Returns the number <code>x</code> shifted <code>disp</code> bits to the left.
+Returns the number <code>x</code> rotated <code>disp</code> bits to the left.
The number <code>disp</code> may be any representable integer.
-Negative displacements shift to the right.
-In any direction, vacant bits are filled with zeros.
-In particular,
-displacements with absolute values higher than
-the total number of bits in the representation of <code>x</code>
-result in zero (all bits are shifted out).
<p>
-For positive displacements,
-the following equality holds:
+For any valid displacement,
+the following identity holds:
<pre>
- assert(bit.lshift(b, disp) == (b * 2^disp) % 2^32)
-</pre>
+ assert(bit32.ROL(x, disp) == bit32.ROL(x, disp % 32))
+</pre><p>
+In particular,
+negative displacements rotate to the right.
+
<p>
-<hr><h3><a name="pdf-bit.rol"><code>bit.rol (x, disp)</code></a></h3>
+<hr><h3><a name="pdf-bit32.ROR"><code>bit32.ROR (x, disp)</code></a></h3>
<p>
-Returns the number <code>x</code> rotated <code>disp</code> bits to the left.
+Returns the number <code>x</code> rotated <code>disp</code> bits to the right.
The number <code>disp</code> may be any representable integer.
@@ -8296,38 +8425,62 @@ For any valid displacement,
the following identity holds:
<pre>
- assert(bit.rol(x, disp) == bit.rol(x, disp % 32))
+ assert(bit32.ROR(x, disp) == bit32.ROR(x, disp % 32))
</pre><p>
In particular,
-negative displacements rotate to the right.
+negative displacements rotate to the left.
<p>
-<hr><h3><a name="pdf-bit.ror"><code>bit.ror (x, disp)</code></a></h3>
+<hr><h3><a name="pdf-bit32.SAR"><code>bit32.SAR (x, disp)</code></a></h3>
<p>
-Returns the number <code>x</code> rotated <code>disp</code> bits to the right.
+Returns the number <code>x</code> shifted <code>disp</code> bits to the right.
The number <code>disp</code> may be any representable integer.
+Negative displacements shift to the left.
<p>
-For any valid displacement,
-the following identity holds:
+This shift operation is what is called arithmetic shift.
+Vacant bits on the left are filled
+with copies of the higher bit of <code>x</code>;
+vacant bits on the right are filled with zeros.
+In particular,
+displacements with absolute values higher than 31
+result in zero or <code>0xFFFFFFFF</code> (all bits are shifted out).
-<pre>
- assert(bit.ror(x, disp) == bit.ror(x, disp % 32))
-</pre><p>
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.SHL"><code>bit32.SHL (x, disp)</code></a></h3>
+
+
+<p>
+Returns the number <code>x</code> shifted <code>disp</code> bits to the left.
+The number <code>disp</code> may be any representable integer.
+Negative displacements shift to the right.
+In any direction, vacant bits are filled with zeros.
In particular,
-negative displacements rotate to the left.
+displacements with absolute values higher than 31
+result in zero (all bits are shifted out).
+<p>
+For positive displacements,
+the following equality holds:
+
+<pre>
+ assert(bit32.SHL(b, disp) == (b * 2^disp) % 2^32)
+</pre>
+
<p>
-<hr><h3><a name="pdf-bit.rshift"><code>bit.rshift (x, disp)</code></a></h3>
+<hr><h3><a name="pdf-bit32.SHR"><code>bit32.SHR (x, disp)</code></a></h3>
<p>
@@ -8336,8 +8489,7 @@ The number <code>disp</code> may be any representable integer.
Negative displacements shift to the left.
In any direction, vacant bits are filled with zeros.
In particular,
-displacements with absolute values higher than
-the total number of bits in the representation of <code>x</code>
+displacements with absolute values higher than 31
result in zero (all bits are shifted out).
@@ -8346,13 +8498,11 @@ For positive displacements,
the following equality holds:
<pre>
- assert(bit.rshift(b, disp) == math.floor(b * 2^-disp))
+ assert(bit32.SHR(b, disp) == math.floor(b % 2^32 / 2^disp))
</pre>
<p>
This shift operation is what is called logical shift.
-For an arithmetic shift,
-you should use the arithmetic operators.
@@ -8360,7 +8510,7 @@ you should use the arithmetic operators.
-<h2>6.8 - <a name="6.8">Input and Output Facilities</a></h2>
+<h2>6.8 &ndash; <a name="6.8">Input and Output Facilities</a></h2>
<p>
The I/O library provides two different styles for file manipulation.
@@ -8584,7 +8734,7 @@ but that takes an unpredictable amount of time to happen.
<p>
If <code>file</code> was created with <a href="#pdf-io.popen"><code>io.popen</code></a>,
-a sucessful close returns the exit status of the process.
+a successful close returns the exit status of the process.
@@ -8768,7 +8918,7 @@ Otherwise it returns <b>nil</b> plus a string describing the error.
-<h2>6.9 - <a name="6.9">Operating System Facilities</a></h2>
+<h2>6.9 &ndash; <a name="6.9">Operating System Facilities</a></h2>
<p>
This library is implemented through table <a name="pdf-os"><code>os</code></a>.
@@ -8860,9 +9010,13 @@ and zero otherwise.
<p>
-Calls the C&nbsp;function <code>exit</code>,
-with an optional <code>code</code>,
-to terminate the host program.
+Calls the C&nbsp;function <code>exit</code> to terminate the host program.
+If <code>code</code> is <b>true</b>,
+the returned status is <code>EXIT_SUCCESS</code>;
+if <code>code</code> is <b>false</b>,
+the returned status is <code>EXIT_FAILURE</code>.
+if <code>code</code> is a number,
+the returned status is this number.
The default value for <code>code</code> is the success code.
@@ -8994,7 +9148,7 @@ which automatically removes the file when the program ends.
-<h2>6.10 - <a name="6.10">The Debug Library</a></h2>
+<h2>6.10 &ndash; <a name="6.10">The Debug Library</a></h2>
<p>
This library provides
@@ -9305,11 +9459,12 @@ will return identical ids for those upvalue indices.
<p>
-<hr><h3><a name="pdf-debug.upvaluejoin"><code>debug.upvaluejoin ()</code></a></h3>
+<hr><h3><a name="pdf-debug.upvaluejoin"><code>debug.upvaluejoin (func1, n1, func2, n2)</code></a></h3>
<p>
-TO BE DONE!!
+Make the <code>n1</code>-th upvalue of the Lua closure <code>func1</code>
+refer to the <code>n2</code>-th upvalue of the Lua closure <code>func2</code>.
@@ -9317,16 +9472,16 @@ TO BE DONE!!
-<h1>7 - <a name="7">Lua Stand-alone</a></h1>
+<h1>7 &ndash; <a name="7">Lua Standalone</a></h1>
<p>
Although Lua has been designed as an extension language,
to be embedded in a host C&nbsp;program,
-it is also frequently used as a stand-alone language.
-An interpreter for Lua as a stand-alone language,
+it is also frequently used as a standalone language.
+An interpreter for Lua as a standalone language,
called simply <code>lua</code>,
is provided with the standard distribution.
-The stand-alone interpreter includes
+The standalone interpreter includes
all standard libraries, including the debug library.
Its usage is:
@@ -9443,7 +9598,7 @@ right after the assignment to <code>_PROMPT</code>.
<p>
To allow the use of Lua as a
script interpreter in Unix systems,
-the stand-alone interpreter skips
+the standalone interpreter skips
the first line of a chunk if it starts with <code>#</code>.
Therefore, Lua scripts can be made into executable programs
by using <code>chmod +x</code> and the&nbsp;<code>#!</code> form,
@@ -9464,7 +9619,7 @@ is a more portable solution.)
-<h1>8 - <a name="8">Incompatibilities with the Previous Version</a></h1>
+<h1>8 &ndash; <a name="8">Incompatibilities with the Previous Version</a></h1>
<p>
Here we list the incompatibilities that you can find when moving a program
@@ -9476,7 +9631,7 @@ all these compatibility options will be removed in the next version of Lua.
-<h2>8.1 - <a name="8.1">Changes in the Language</a></h2>
+<h2>8.1 &ndash; <a name="8.1">Changes in the Language</a></h2>
<ul>
<li>
@@ -9500,7 +9655,7 @@ All threads share a single fixed environment.
<li>
The event <em>tail return</em> in debug hooks was removed.
Instead, tail calls generate a special new event,
-<em>tail call</em>, so that the debuger can know there will
+<em>tail call</em>, so that the debugger can know there will
not be a corresponding return event.
</li>
@@ -9509,7 +9664,7 @@ not be a corresponding return event.
-<h2>8.2 - <a name="8.2">Changes in the Libraries</a></h2>
+<h2>8.2 &ndash; <a name="8.2">Changes in the Libraries</a></h2>
<ul>
<li>
@@ -9566,7 +9721,7 @@ to restrict it to loading textual chunks.
-<h2>8.3 - <a name="8.3">Changes in the API</a></h2>
+<h2>8.3 &ndash; <a name="8.3">Changes in the API</a></h2>
<ul>
<li>
@@ -9594,6 +9749,24 @@ use the new functions
</li>
<li>
+Function <code>luaL_register</code> is deprecated.
+Use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> so that your module does not
+create globals anymore.
+(Modules are not expected to set global variables anymore.)
+</li>
+
+<li>
+Finalizers ("<code>__gc</code>" metamethods) for userdata are called in the
+reverse order that they were marked,
+not that they were created (see <a href="#2.5.1">&sect;2.5.1</a>).
+(Most userdata are marked immediately after they are created.)
+Moreover,
+if the metatable does not have a "<code>__gc</code>" field when set,
+the finalizer will not be called,
+even if it is set later.
+</li>
+
+<li>
<code>luaL_typerror</code> was renamed <a href="#luaL_typeerror"><code>luaL_typeerror</code></a>,
to have a correct spelling.
</li>
@@ -9618,7 +9791,7 @@ Function <code>lua_objlen</code> was renamed <a href="#lua_rawlen"><code>lua_raw
-<h1>9 - <a name="9">The Complete Syntax of Lua</a></h1>
+<h1>9 &ndash; <a name="9">The Complete Syntax of Lua</a></h1>
<p>
Here is the complete syntax of Lua in extended BNF.
@@ -9644,8 +9817,7 @@ Here is the complete syntax of Lua in extended BNF.
<b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> |
<b>function</b> funcname funcbody |
<b>local</b> <b>function</b> Name funcbody |
- <b>local</b> namelist [&lsquo<b>=</b>&rsquo; explist] |
- <b>in</b> exp <b>do</b> block <b>end</b>
+ <b>local</b> namelist [&lsquo<b>=</b>&rsquo; explist]
laststat ::= <b>return</b> [explist] | <b>break</b>
@@ -9701,10 +9873,10 @@ Here is the complete syntax of Lua in extended BNF.
<HR>
<SMALL>
Last update:
-Fri Jul 30 16:41:34 BRT 2010
+Sat Oct 30 21:36:20 BRST 2010
</SMALL>
<!--
-Last change: revised for Lua 5.2.0 (work4)
+Last change: revised for Lua 5.2.0 (work5)
-->
</body></html>
diff --git a/doc/readme.html b/doc/readme.html
index 9284427d..55919999 100644
--- a/doc/readme.html
+++ b/doc/readme.html
@@ -27,7 +27,7 @@ tt, kbd, code {
<HR>
<H1>
<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A>
-Welcome to Lua 5.2 (work4)
+Welcome to Lua 5.2 (work5)
</H1>
<P>
@@ -89,12 +89,10 @@ because
Lua is implemented in pure ANSI C, and compiles unmodified in all known
platforms that have an ANSI C compiler.
Lua also compiles unmodified as C++.
-
-<P>
-The instructions below are for Unix-like platforms.
-There are also
-<A HREF="#other">instructions for other systems</A>.
-See below for
+The instructions given below for building Lua are for Unix-like platforms.
+See also
+<A HREF="#other">instructions for other systems</A>
+and
<A HREF="#customization">customization options</A>.
<P>
@@ -250,7 +248,7 @@ interpreter:
<DT>
compiler:
<DD>
- library, luac.c print.c
+ library, luac.c
</DL>
<P>
@@ -258,7 +256,7 @@ compiler:
create and use libraries with your compiler. Moreover, to dynamically load
C libraries for Lua you'll need to know how to create dynamic libraries
and you'll need to make sure that the Lua API functions are accessible to
- those dynamic libraries &mdash; but you do <EM>not</EM> want to link the Lua library
+ those dynamic libraries &mdash; but <EM>don't</EM> link the Lua library
into each dynamic library. For Unix, we recommend that the Lua library
be linked statically into the host program and its symbols exported for
dynamic linking; src/Makefile does this for the Lua interpreter.
@@ -268,18 +266,6 @@ compiler:
As mentioned above, you may edit src/luaconf.h to customize
some features before building Lua.
-<H2><A NAME="changes">Changes since Lua 5.2.0 (work3)</A></H2>
-
-<UL>
-<LI> <CODE>module</CODE> and <CODE>luaL_register</CODE> deprecated, replaced by <CODE>luaL_newlib</CODE> and <CODE>luaL_setfuncs</CODE>.
-<LI> new function <CODE>luaL_requiref</CODE>.
-<LI> caching of Lua closures for resue.
-<LI> version-specific environment variables (<CODE>LUA_PATH_5_2</CODE>, etc.).
-<LI> new class '%g' in patterns.
-<LI> <CODE>debug.getlocal</CODE> gets parameter names of inactive functions.
-<LI> new functions <CODE>lua_tonumberx</CODE> and <CODE>lua_tointegerx</CODE>.
-</UL>
-
<H2><A NAME="changes">Changes since Lua 5.1</A></H2>
<P>
@@ -289,61 +275,73 @@ The
lists the
<A HREF="manual.html#8">incompatibilities</A> that had to be introduced.
-<H3>Language</H3>
+<H3>Main changes</H3>
<UL>
-<LI> new lexical environments.
-<LI> no more fenv for threads.
+<LI> yieldable pcall and metamethods
+<LI> new <CODE>_ENV</CODE> scheme
<LI> ephemeron tables
- (tables with weak keys only visit value when key is accessible).
-<LI> yieldable pcall and metamethods.
-<LI> tables honor the <CODE>__len</CODE> metamethod.
-<LI> max constants per function raised to 2^26.
-<LI> hex escapes in strings.
-<LI> no more verification of opcode consistency.
+<LI> new library for bitwise operations
+<LI> light C functions
+<LI> emergency garbage collector
+</UL>
+
+Here are the other changes introduced in Lua 5.2:
+<H3>Language</H3>
+<UL>
+<LI> no more fenv for threads or functions
+<LI> tables honor the <CODE>__len</CODE> metamethod
+<LI> hex and <CODE>\*</CODE> escapes in strings
+<LI> order metamethods work for different types
+<LI> no more verification of opcode consistency
+<LI> hook event "tail return" replaced by "tail call"
+<LI> empty statement
</UL>
<H3>Libraries</H3>
<UL>
-<LI> new library for bitwise operations.
-<LI> new metamethods <CODE>__pairs</CODE> and <CODE>__ipairs</CODE>.
-<LI> arguments for function called through <CODE>xpcall</CODE>.
-<LI> optional argument to load (to control binary x text).
-<LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL).
-<LI> new function <CODE>package.searchpath</CODE>.
-<LI> optional base in <CODE>math.log</CODE>.
-<LI> <CODE>file:write</CODE> returns <CODE>file</CODE>.
-<LI> closing a pipe returns exit status.
-<LI> <CODE>os.exit</CODE> may close state.
-<LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE>.
-<LI> frontier patterns.
-<LI> <CODE>ipairs</CODE> now goes until #t.
+<LI> new metamethods <CODE>__pairs</CODE> and <CODE>__ipairs</CODE>
+<LI> arguments for function called through <CODE>xpcall</CODE>
+<LI> optional 'mode' argument to load (to control binary x text)
+<LI> new function <CODE>loadin</CODE>
+<LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL)
+<LI> new function <CODE>package.searchpath</CODE>
+<LI> optional base in <CODE>math.log</CODE>
+<LI> <CODE>file:write</CODE> returns <CODE>file</CODE>
+<LI> closing a pipe returns exit status
+<LI> <CODE>os.exit</CODE> may close state
+<LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE>
+<LI> frontier patterns
+<LI> <CODE>\0</CODE> in patterns
+<LI> new option <CODE>*L</CODE> for <CODE>io.read</CODE>
+<LI> options for <CODE>io.lines</CODE>
</UL>
<H3>C API</H3>
<UL>
-<LI> mainthread predefined in the registry.
-<LI> <CODE>lua_cpcall</CODE> changed to a predefined function in the registry.
-<LI> new constants <CODE>LUA_OK</CODE> and <CODE>LUA_ERRGCMM</CODE>.
-<LI> new <CODE>lua_compare</CODE>, <CODE>lua_arith</CODE>, and <CODE>lua_len</CODE>.
-<LI> new <CODE>lua_version</CODE> and <CODE>luaL_version</CODE>.
-<LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string.
-<LI> new <CODE>luaL_testudata</CODE>.
-<LI> new <CODE>luaL_tolstring</CODE>.
-<LI> new <CODE>lua_copy</CODE>.
-<LI> new <CODE>lua_upvalueid</CODE> and <CODE>lua_upvaluejoin</CODE>.
-<LI> <CODE>nparams</CODE> and <CODE>isvarag</CODE> available in debug API.
+<LI> main thread predefined in the registry
+<LI> new constants <CODE>LUA_OK</CODE> and <CODE>LUA_ERRGCMM</CODE>
+<LI> new <CODE>lua_compare</CODE>, <CODE>lua_arith</CODE>, and <CODE>lua_len</CODE>
+<LI> new <CODE>lua_version</CODE> and <CODE>luaL_version</CODE>
+<LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string
+<LI> new <CODE>luaL_testudata</CODE>
+<LI> new <CODE>luaL_tolstring</CODE>
+<LI> new <CODE>lua_copy</CODE>
+<LI> new <CODE>lua_absindex</CODE>
+<LI> new <CODE>lua_upvalueid</CODE> and <CODE>lua_upvaluejoin</CODE>
+<LI> <CODE>nparams</CODE> and <CODE>isvarag</CODE> available in debug API
</UL>
<H3>Implementation</H3>
<UL>
-<LI> emergency garbage collector
- (core forces a full collection when allocation fails).
-<LI> udata with finalizers are kept in a separated list for the GC.
-<LI> CallInfo stack now is a linked list.
-<LI> internal (immutable) version of ctypes.
-<LI> parser uses much less C-stack space (no more auto arrays).
-<LI> new hash for floats.
-<LI> handling of non-string error messages in the standalone interpreter.
+<LI> max constants per function raised to 2<SUP>26</SUP>
+<LI> internal (immutable) version of ctypes
+<LI> simpler implementation for string buffers
+<LI> udata with finalizers are kept in a separated list for the GC
+<LI> <CODE>CallInfo</CODE>stack now is a linked list
+<LI> parser uses much less C-stack space (no more auto arrays)
+<LI> new hash for floats
+<LI> handling of non-string error messages in the standalone interpreter
+<LI> generational mode for garbage collection (experimental)
</UL>
<H2><A NAME="license">License</A></H2>
@@ -352,7 +350,7 @@ lists the
</A>
<P>
-Lua is free software licensed under the terms of the
+Lua is free software distributed under the terms of the
<A HREF="http://www.opensource.org/licenses/mit-license.html">MIT license</A>
reproduced below;
it can be used for any purpose, including commercial purposes,
@@ -392,10 +390,10 @@ THE SOFTWARE.
<HR>
<SMALL>
Last update:
-Fri Jul 30 15:12:25 BRT 2010
+Sat Oct 30 21:36:38 BRST 2010
</SMALL>
<!--
-Last change: revised for Lua 5.2.0 (work4)
+Last change: revised for Lua 5.2.0 (work5)
-->
</BODY>
diff --git a/src/Makefile b/src/Makefile
index 84a21035..61ad180e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -33,7 +33,7 @@ LUA_T= lua
LUA_O= lua.o
LUAC_T= luac
-LUAC_O= luac.o print.o
+LUAC_O= luac.o
ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
@@ -62,7 +62,7 @@ clean:
$(RM) $(ALL_T) $(ALL_O)
depend:
- @$(CC) $(CFLAGS) -MM l*.c print.c
+ @$(CC) $(CFLAGS) -MM l*.c
echo:
@echo "PLAT= $(PLAT)"
@@ -94,8 +94,7 @@ bsd:
freebsd:
$(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline"
-generic:
- $(MAKE) $(ALL) MYCFLAGS=
+generic: $(ALL)
linux:
$(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -ldl -lreadline -lncurses"
@@ -170,16 +169,13 @@ ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h
ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \
lmem.h lstring.h lgc.h ltable.h
lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h
-luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \
- lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \
- lundump.h
+luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \
+ ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h
lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h
lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
lzio.h
-print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \
- ltm.h lzio.h lmem.h lopcodes.h lundump.h
# (end of Makefile)
diff --git a/src/lapi.c b/src/lapi.c
index 2d7c336a..094d623b 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.133 2010/07/25 15:18:19 roberto Exp $
+** $Id: lapi.c,v 2.139 2010/10/25 20:31:11 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -85,7 +85,7 @@ LUA_API int lua_checkstack (lua_State *L, int size) {
if (L->stack_last - L->top > size) /* stack large enough? */
res = 1; /* yes; check is OK */
else { /* no; need to grow stack */
- int inuse = L->top - L->stack + EXTRA_STACK;
+ int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */
res = 0; /* no */
else /* try to grow stack */
@@ -347,6 +347,23 @@ LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
}
+LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
+ TValue n;
+ const TValue *o = index2addr(L, idx);
+ if (tonumber(o, &n)) {
+ lua_Unsigned res;
+ lua_Number num = nvalue(o);
+ lua_number2uint(res, num);
+ if (isnum) *isnum = 1;
+ return res;
+ }
+ else {
+ if (isnum) *isnum = 0;
+ return 0;
+ }
+}
+
+
LUA_API int lua_toboolean (lua_State *L, int idx) {
const TValue *o = index2addr(L, idx);
return !l_isfalse(o);
@@ -452,6 +469,16 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
}
+LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
+ lua_Number n;
+ lua_lock(L);
+ n = lua_uint2number(u);
+ setnvalue(L->top, n);
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
TString *ts;
lua_lock(L);
@@ -799,6 +826,7 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
api_check(L, k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
+ api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
func = L->top - (nargs+1);
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
@@ -839,6 +867,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
api_check(L, k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
+ api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
if (errfunc == 0)
func = 0;
@@ -889,7 +918,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
/* get global table from registry */
Table *reg = hvalue(&G(L)->l_registry);
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
- /* set global table as 1st upvalue of 'f' (may be _ENV) */
+ /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
setobj(L, f->l.upvals[0]->v, gt);
luaC_barrier(L, f->l.upvals[0], gt);
}
@@ -974,6 +1003,11 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
g->gcpause = data;
break;
}
+ case LUA_GCSETMAJORINC: {
+ res = g->gcmajorinc;
+ g->gcmajorinc = data;
+ break;
+ }
case LUA_GCSETSTEPMUL: {
res = g->gcstepmul;
g->gcstepmul = data;
@@ -1100,11 +1134,15 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
return "";
}
else {
+ const char *name;
Proto *p = f->l.p;
if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
*val = f->l.upvals[n-1]->v;
if (owner) *owner = obj2gco(f->l.upvals[n - 1]);
- return getstr(p->upvalues[n-1].name);
+ name = getstr(p->upvalues[n-1].name);
+ if (name == NULL) /* no debug information? */
+ name = "";
+ return name;
}
}
@@ -1144,13 +1182,11 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) {
Closure *f;
- Proto *p;
StkId fi = index2addr(L, fidx);
api_check(L, ttisclosure(fi), "Lua function expected");
f = clvalue(fi);
api_check(L, !f->c.isC, "Lua function expected");
- p = f->l.p;
- api_check(L, (1 <= n && n <= p->sizeupvalues), "invalid upvalue index");
+ api_check(L, (1 <= n && n <= f->l.p->sizeupvalues), "invalid upvalue index");
if (pf) *pf = f;
return &f->l.upvals[n - 1]; /* get its upvalue pointer */
}
diff --git a/src/lauxlib.c b/src/lauxlib.c
index 54f13da2..807c5522 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.219 2010/07/28 15:51:59 roberto Exp $
+** $Id: lauxlib.c,v 1.224 2010/10/29 12:52:21 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -330,11 +330,26 @@ LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
}
+LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {
+ int isnum;
+ lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);
+ if (!isnum)
+ tag_error(L, narg, LUA_TNUMBER);
+ return d;
+}
+
+
LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
lua_Integer def) {
return luaL_opt(L, luaL_checkinteger, narg, def);
}
+
+LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg,
+ lua_Unsigned def) {
+ return luaL_opt(L, luaL_checkunsigned, narg, def);
+}
+
/* }====================================================== */
@@ -434,7 +449,7 @@ LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
*/
/* index of free-list header */
-#define freelist "lua-freelist"
+#define freelist 0
LUALIB_API int luaL_ref (lua_State *L, int t) {
@@ -444,12 +459,12 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* `nil' has a unique fixed reference */
}
- lua_getfield(L, t, freelist); /* get first free element */
- ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
+ lua_rawgeti(L, t, freelist); /* get first free element */
+ ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */
lua_pop(L, 1); /* remove it from stack */
if (ref != 0) { /* any free element? */
lua_rawgeti(L, t, ref); /* remove it from list */
- lua_setfield(L, t, freelist); /* (t[freelist] = t[ref]) */
+ lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */
}
else /* no free elements */
ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */
@@ -461,10 +476,10 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
if (ref >= 0) {
t = lua_absindex(L, t);
- lua_getfield(L, t, freelist);
+ lua_rawgeti(L, t, freelist);
lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
lua_pushinteger(L, ref);
- lua_setfield(L, t, freelist); /* t[freelist] = ref */
+ lua_rawseti(L, t, freelist); /* t[freelist] = ref */
}
}
@@ -511,17 +526,32 @@ static int errfile (lua_State *L, const char *what, int fnameindex) {
}
+static int skipBOM (LoadF *lf) {
+ const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */
+ int c;
+ lf->n = 0;
+ do {
+ c = getc(lf->f);
+ if (c == EOF || c != *(unsigned char *)p++) return c;
+ lf->buff[lf->n++] = c; /* to be read by the parser */
+ } while (*p != '\0');
+ lf->n = 0; /* prefix matched; discard it */
+ return getc(lf->f); /* return next character */
+}
+
+
/*
-** reads the first character of file 'f' and skips its first line
-** if it starts with '#'. Returns true if it skipped the first line.
-** In any case, '*cp' has the first "valid" character of the file
-** (after the optional first-line comment).
+** reads the first character of file 'f' and skips an optional BOM mark
+** in its beginning plus its first line if it starts with '#'. Returns
+** true if it skipped the first line. In any case, '*cp' has the
+** first "valid" character of the file (after the optional BOM and
+** a first-line comment).
*/
-static int skipcomment (FILE *f, int *cp) {
- int c = *cp = getc(f);
+static int skipcomment (LoadF *lf, int *cp) {
+ int c = *cp = skipBOM(lf);
if (c == '#') { /* first line is a comment (Unix exec. file)? */
- while ((c = getc(f)) != EOF && c != '\n') ; /* skip first line */
- *cp = getc(f); /* skip end-of-line */
+ while ((c = getc(lf->f)) != EOF && c != '\n') ; /* skip first line */
+ *cp = getc(lf->f); /* skip end-of-line */
return 1; /* there was a comment */
}
else return 0; /* no comment */
@@ -542,14 +572,12 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
lf.f = fopen(filename, "r");
if (lf.f == NULL) return errfile(L, "open", fnameindex);
}
- lf.n = 0;
- if (skipcomment(lf.f, &c)) /* read initial portion */
+ if (skipcomment(&lf, &c)) /* read initial portion */
lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
- lf.n = 0;
- skipcomment(lf.f, &c); /* re-read initial portion */
+ skipcomment(&lf, &c); /* re-read initial portion */
}
if (c != EOF)
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
@@ -628,7 +656,7 @@ LUALIB_API int luaL_len (lua_State *L, int idx) {
int l;
int isnum;
lua_len(L, idx);
- l = lua_tointegerx(L, -1, &isnum);
+ l = (int)lua_tointegerx(L, -1, &isnum);
if (!isnum)
luaL_error(L, "object length is not a number");
lua_pop(L, 1); /* remove object */
@@ -848,5 +876,12 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
else if (*v != ver)
luaL_error(L, "version mismatch: app. needs %d, Lua core provides %f",
ver, *v);
+ /* check conversions number -> integer types */
+ lua_pushnumber(L, -(lua_Number)0x1234);
+ if (lua_tointeger(L, -1) != -0x1234 ||
+ lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
+ luaL_error(L, "bad conversion number->int;"
+ " must recompile Lua with proper settings");
+ lua_pop(L, 1);
}
diff --git a/src/lauxlib.h b/src/lauxlib.h
index b2034673..504fdf58 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.108 2010/07/02 11:38:13 roberto Exp $
+** $Id: lauxlib.h,v 1.109 2010/10/25 20:31:11 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -44,6 +44,9 @@ LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
lua_Integer def);
+LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg);
+LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg,
+ lua_Unsigned def);
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
diff --git a/src/lbaselib.c b/src/lbaselib.c
index 1e13a183..1553c1d0 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.246 2010/07/02 11:38:13 roberto Exp $
+** $Id: lbaselib.c,v 1.251 2010/10/28 15:36:30 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -56,12 +56,15 @@ static int luaB_tonumber (lua_State *L) {
const char *s1 = luaL_checkstring(L, 1);
char *s2;
unsigned long n;
+ int neg = 0;
luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
+ while (isspace((unsigned char)(*s1))) s1++; /* skip initial spaces */
+ if (*s1 == '-') { s1++; neg = 1; }
n = strtoul(s1, &s2, base);
if (s1 != s2) { /* at least one valid digit? */
while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
if (*s2 == '\0') { /* no invalid trailing characters? */
- lua_pushnumber(L, (lua_Number)n);
+ lua_pushnumber(L, (neg) ? -(lua_Number)n : (lua_Number)n);
return 1;
}
}
@@ -142,11 +145,11 @@ static int luaB_rawset (lua_State *L) {
static int luaB_collectgarbage (lua_State *L) {
static const char *const opts[] = {"stop", "restart", "collect",
- "count", "step", "setpause", "setstepmul", "isrunning",
- "gen", "inc", NULL};
+ "count", "step", "setpause", "setstepmul",
+ "setmajorinc", "isrunning", "gen", "inc", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
- LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
+ LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
int ex = luaL_optint(L, 2, 0);
int res = lua_gc(L, o, ex);
@@ -330,11 +333,12 @@ static int luaB_load (lua_State *L) {
static int luaB_loadin (lua_State *L) {
int n;
- luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_checkany(L, 1);
n = luaB_load_aux(L, 2);
if (n == 1) { /* success? */
lua_pushvalue(L, 1); /* environment for loaded function */
- lua_setupvalue(L, -2, 1);
+ if (lua_setupvalue(L, -2, 1) == NULL)
+ luaL_error(L, "loaded chunk does not have an upvalue");
}
return n;
}
diff --git a/src/lbitlib.c b/src/lbitlib.c
index 1b32653d..e93575e6 100644
--- a/src/lbitlib.c
+++ b/src/lbitlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbitlib.c,v 1.6 2010/07/02 12:01:53 roberto Exp $
+** $Id: lbitlib.c,v 1.10 2010/10/28 15:17:29 roberto Exp $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/
@@ -13,22 +13,19 @@
#include "lualib.h"
-/* number of bits considered when shifting/rotating (must be a power of 2) */
+/* number of bits to consider in a number */
#define NBITS 32
+#define ALLONES (~(((~(lua_Unsigned)0) << (NBITS - 1)) << 1))
-typedef LUA_INT32 b_int;
-typedef unsigned LUA_INT32 b_uint;
+/* mask to trim extra bits */
+#define trim(x) ((x) & ALLONES)
-static b_uint getuintarg (lua_State *L, int arg) {
- b_uint r;
- int isnum;
- lua_Number x = lua_tonumberx(L, arg, &isnum);
- if (!isnum) luaL_typeerror(L, arg, "number");
- lua_number2uint(r, x);
- return r;
-}
+typedef lua_Unsigned b_uint;
+
+
+#define getuintarg(L,arg) luaL_checkunsigned(L,arg)
static b_uint andaux (lua_State *L) {
@@ -36,13 +33,13 @@ static b_uint andaux (lua_State *L) {
b_uint r = ~(b_uint)0;
for (i = 1; i <= n; i++)
r &= getuintarg(L, i);
- return r;
+ return trim(r);
}
static int b_and (lua_State *L) {
b_uint r = andaux(L);
- lua_pushnumber(L, lua_uint2number(r));
+ lua_pushunsigned(L, r);
return 1;
}
@@ -59,7 +56,7 @@ static int b_or (lua_State *L) {
b_uint r = 0;
for (i = 1; i <= n; i++)
r |= getuintarg(L, i);
- lua_pushnumber(L, lua_uint2number(r));
+ lua_pushunsigned(L, trim(r));
return 1;
}
@@ -69,49 +66,66 @@ static int b_xor (lua_State *L) {
b_uint r = 0;
for (i = 1; i <= n; i++)
r ^= getuintarg(L, i);
- lua_pushnumber(L, lua_uint2number(r));
+ lua_pushunsigned(L, trim(r));
return 1;
}
static int b_not (lua_State *L) {
b_uint r = ~getuintarg(L, 1);
- lua_pushnumber(L, lua_uint2number(r));
+ lua_pushunsigned(L, trim(r));
return 1;
}
-static int b_shift (lua_State *L, int i) {
- b_uint r = getuintarg(L, 1);
+static int b_shift (lua_State *L, b_uint r, int i) {
if (i < 0) { /* shift right? */
i = -i;
+ r = trim(r);
if (i >= NBITS) r = 0;
else r >>= i;
}
else { /* shift left */
if (i >= NBITS) r = 0;
else r <<= i;
+ r = trim(r);
}
- lua_pushnumber(L, lua_uint2number(r));
+ lua_pushunsigned(L, r);
return 1;
}
static int b_lshift (lua_State *L) {
- return b_shift(L, luaL_checkint(L, 2));
+ return b_shift(L, getuintarg(L, 1), luaL_checkint(L, 2));
}
static int b_rshift (lua_State *L) {
- return b_shift(L, -luaL_checkint(L, 2));
+ return b_shift(L, getuintarg(L, 1), -luaL_checkint(L, 2));
+}
+
+
+static int b_arshift (lua_State *L) {
+ b_uint r = getuintarg(L, 1);
+ int i = luaL_checkint(L, 2);
+ if (i < 0 || !(r & (1 << (NBITS - 1))))
+ return b_shift(L, r, -i);
+ else { /* arithmetic shift for 'negative' number */
+ if (i >= NBITS) r = ALLONES;
+ else
+ r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */
+ lua_pushunsigned(L, r);
+ return 1;
+ }
}
static int b_rot (lua_State *L, int i) {
b_uint r = getuintarg(L, 1);
i &= (NBITS - 1); /* i = i % NBITS */
+ r = trim(r);
r = (r << i) | (r >> (NBITS - i));
- lua_pushnumber(L, lua_uint2number(r));
+ lua_pushunsigned(L, trim(r));
return 1;
}
@@ -127,21 +141,23 @@ static int b_ror (lua_State *L) {
static const luaL_Reg bitlib[] = {
- {"band", b_and},
- {"btest", b_test},
- {"bor", b_or},
- {"bxor", b_xor},
- {"bnot", b_not},
- {"lshift", b_lshift},
- {"rshift", b_rshift},
- {"rol", b_rol},
- {"ror", b_ror},
+ {"AND", b_and},
+ {"TEST", b_test},
+ {"OR", b_or},
+ {"XOR", b_xor},
+ {"NOT", b_not},
+ {"SHL", b_lshift},
+ {"SAR", b_arshift},
+ {"SHR", b_rshift},
+ {"ROL", b_rol},
+ {"ROR", b_ror},
{NULL, NULL}
};
-LUAMOD_API int luaopen_bit (lua_State *L) {
+LUAMOD_API int luaopen_bit32 (lua_State *L) {
luaL_newlib(L, bitlib);
return 1;
}
+
diff --git a/src/ldebug.c b/src/ldebug.c
index 5a04d5a3..a112f4da 100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.72 2010/06/21 16:30:12 roberto Exp $
+** $Id: ldebug.c,v 2.74 2010/10/11 20:24:42 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -160,9 +160,10 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
ar->what = "C";
}
else {
- ar->source = getstr(cl->l.p->source);
- ar->linedefined = cl->l.p->linedefined;
- ar->lastlinedefined = cl->l.p->lastlinedefined;
+ Proto *p = cl->l.p;
+ ar->source = p->source ? getstr(p->source) : "=?";
+ ar->linedefined = p->linedefined;
+ ar->lastlinedefined = p->lastlinedefined;
ar->what = (ar->linedefined == 0) ? "main" : "Lua";
}
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
@@ -315,7 +316,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
? luaF_getlocalname(p, t + 1, pc)
: getstr(p->upvalues[t].name);
kname(p, k, a, what, name);
- what = (vn && strcmp(vn, "_ENV") == 0) ? "global" : "field";
+ what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
}
break;
}
@@ -496,7 +497,12 @@ static void addinfo (lua_State *L, const char *msg) {
if (isLua(ci)) { /* is Lua code? */
char buff[LUA_IDSIZE]; /* add file:line information */
int line = currentline(ci);
- luaO_chunkid(buff, getstr(ci_func(ci)->l.p->source), LUA_IDSIZE);
+ TString *src = ci_func(ci)->l.p->source;
+ if (src)
+ luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
+ else { /* no source available; use "?" instead */
+ buff[0] = '?'; buff[1] = '\0';
+ }
luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
}
}
diff --git a/src/ldo.c b/src/ldo.c
index 834a0543..f4f91006 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.88 2010/06/04 13:06:15 roberto Exp $
+** $Id: ldo.c,v 2.90 2010/10/25 19:01:37 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -177,7 +177,7 @@ void luaD_growstack (lua_State *L, int n) {
if (size > LUAI_MAXSTACK) /* error after extra size? */
luaD_throw(L, LUA_ERRERR);
else {
- int needed = L->top - L->stack + n + EXTRA_STACK;
+ int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
int newsize = 2 * size;
if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
if (newsize < needed) newsize = needed;
@@ -299,7 +299,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
if (!ttisfunction(func)) /* `func' is not a function? */
func = tryfuncTM(L, func); /* check the `function' tag method */
funcr = savestack(L, func);
- L->ci->nresults = nresults;
if (ttislcf(func)) { /* light C function? */
f = fvalue(func); /* get it */
goto isCfunc; /* go to call it */
@@ -312,6 +311,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
isCfunc: /* call C function 'f' */
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci = next_ci(L); /* now 'enter' new function */
+ ci->nresults = nresults;
ci->func = restorestack(L, funcr);
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
@@ -341,6 +341,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
else /* vararg function */
base = adjust_varargs(L, p, nargs);
ci = next_ci(L); /* now 'enter' new function */
+ ci->nresults = nresults;
ci->func = func;
ci->u.l.base = base;
ci->top = base + p->maxstacksize;
@@ -368,8 +369,8 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
}
res = ci->func; /* res == final position of 1st result */
- L->ci = ci = ci->previous; /* back to caller */
wanted = ci->nresults;
+ L->ci = ci = ci->previous; /* back to caller */
/* move results to correct place */
for (i = wanted; i != 0 && firstResult < L->top; i--)
setobjs2s(L, res++, firstResult++);
diff --git a/src/ldump.c b/src/ldump.c
index b2c1e709..54a7bb48 100644
--- a/src/ldump.c
+++ b/src/ldump.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldump.c,v 2.13 2010/03/12 19:14:06 roberto Exp $
+** $Id: ldump.c,v 1.17 2010/10/13 21:04:52 lhf Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -75,7 +75,7 @@ static void DumpString(const TString* s, DumpState* D)
#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
+static void DumpFunction(const Proto* f, DumpState* D);
static void DumpConstants(const Proto* f, DumpState* D)
{
@@ -98,14 +98,11 @@ static void DumpConstants(const Proto* f, DumpState* D)
case LUA_TSTRING:
DumpString(rawtsvalue(o),D);
break;
- default:
- lua_assert(0); /* cannot happen */
- break;
}
}
n=f->sizep;
DumpInt(n,D);
- for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
+ for (i=0; i<n; i++) DumpFunction(f->p[i],D);
}
static void DumpUpvalues(const Proto* f, DumpState* D)
@@ -122,6 +119,7 @@ static void DumpUpvalues(const Proto* f, DumpState* D)
static void DumpDebug(const Proto* f, DumpState* D)
{
int i,n;
+ DumpString((D->strip) ? NULL : f->source,D);
n= (D->strip) ? 0 : f->sizelineinfo;
DumpVector(f->lineinfo,n,sizeof(int),D);
n= (D->strip) ? 0 : f->sizelocvars;
@@ -137,9 +135,8 @@ static void DumpDebug(const Proto* f, DumpState* D)
for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);
}
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
+static void DumpFunction(const Proto* f, DumpState* D)
{
- DumpString((f->source==p || D->strip) ? NULL : f->source,D);
DumpInt(f->linedefined,D);
DumpInt(f->lastlinedefined,D);
DumpChar(f->numparams,D);
@@ -170,6 +167,6 @@ int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip
D.strip=strip;
D.status=0;
DumpHeader(&D);
- DumpFunction(f,NULL,&D);
+ DumpFunction(f,&D);
return D.status;
}
diff --git a/src/lgc.c b/src/lgc.c
index fcaca1b4..2286f54e 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.101 2010/06/30 14:11:17 roberto Exp $
+** $Id: lgc.c,v 2.103 2010/10/25 19:01:37 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -449,7 +449,7 @@ static int traverseproto (global_State *g, Proto *f) {
}
-static l_mem traverseclosure (global_State *g, Closure *cl) {
+static int traverseclosure (global_State *g, Closure *cl) {
if (cl->c.isC) {
int i;
for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
@@ -960,7 +960,7 @@ static void generationalcollection (lua_State *L) {
else {
luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */
luaC_runtilstate(L, bitmask(GCSpause));
- if (g->totalbytes > g->lastmajormem/100 * g->gcpause)
+ if (g->totalbytes > g->lastmajormem/100 * g->gcmajorinc)
g->lastmajormem = 0; /* signal for a major collection */
}
g->GCdebt = stddebt(g);
diff --git a/src/linit.c b/src/linit.c
index b8af9f39..ecde4915 100644
--- a/src/linit.c
+++ b/src/linit.c
@@ -1,5 +1,5 @@
/*
-** $Id: linit.c,v 1.28 2010/07/02 11:38:13 roberto Exp $
+** $Id: linit.c,v 1.29 2010/10/25 14:32:36 roberto Exp $
** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h
*/
@@ -34,7 +34,7 @@ static const luaL_Reg loadedlibs[] = {
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
- {LUA_BITLIBNAME, luaopen_bit},
+ {LUA_BITLIBNAME, luaopen_bit32},
{LUA_MATHLIBNAME, luaopen_math},
#if defined(LUA_COMPAT_DEBUGLIB)
{LUA_DBLIBNAME, luaopen_debug},
diff --git a/src/liolib.c b/src/liolib.c
index 3ecccb11..6574e8b6 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c,v 2.91 2010/07/28 15:51:59 roberto Exp $
+** $Id: liolib.c,v 2.92 2010/10/25 19:01:37 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -453,7 +453,7 @@ static int f_read (lua_State *L) {
static int io_readline (lua_State *L) {
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int i;
- int n = lua_tointeger(L, lua_upvalueindex(2));
+ int n = (int)lua_tointeger(L, lua_upvalueindex(2));
if (f == NULL) /* file is already closed? */
luaL_error(L, "file is already closed");
lua_settop(L , 1);
diff --git a/src/llex.c b/src/llex.c
index e380910d..f1f87171 100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 2.37 2010/04/16 12:31:07 roberto Exp $
+** $Id: llex.c,v 2.40 2010/10/25 12:24:36 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -161,7 +161,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
ls->linenumber = 1;
ls->lastline = 1;
ls->source = source;
- ls->envn = luaS_new(L, "_ENV"); /* create env name */
+ ls->envn = luaS_new(L, LUA_ENV); /* create env name */
luaS_fix(ls->envn); /* never collect this name */
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
next(ls); /* read first char */
@@ -221,11 +221,9 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) {
lua_assert(lisdigit(ls->current));
do {
save_and_next(ls);
- } while (lisdigit(ls->current) || ls->current == '.');
- if (check_next(ls, "Ee")) /* `E'? */
- check_next(ls, "+-"); /* optional exponent sign */
- while (lislalnum(ls->current))
- save_and_next(ls);
+ if (check_next(ls, "EePp")) /* exponent part? */
+ check_next(ls, "+-"); /* optional exponent sign */
+ } while (lislalnum(ls->current) || ls->current == '.');
save(ls, '\0');
buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
@@ -234,7 +232,7 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) {
/*
-** skip a sequence '[=*=[' or ']=*]' and return its number of '='s or
+** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
** -1 if sequence is malformed
*/
static int skip_sep (LexState *ls) {
diff --git a/src/lmathlib.c b/src/lmathlib.c
index 7ba6550c..13aebe9e 100644
--- a/src/lmathlib.c
+++ b/src/lmathlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmathlib.c,v 1.75 2010/07/02 11:38:13 roberto Exp $
+** $Id: lmathlib.c,v 1.76 2010/10/25 20:31:11 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -220,7 +220,7 @@ static int math_random (lua_State *L) {
static int math_randomseed (lua_State *L) {
- srand(luaL_checkint(L, 1));
+ srand(luaL_checkunsigned(L, 1));
(void)rand(); /* discard first value to avoid undesirable correlations */
return 0;
}
diff --git a/src/loadlib.c b/src/loadlib.c
index 82c00b0d..42cfb869 100644
--- a/src/loadlib.c
+++ b/src/loadlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.89 2010/07/28 15:51:59 roberto Exp $
+** $Id: loadlib.c,v 1.92 2010/10/29 14:35:09 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -177,7 +177,7 @@ static void ll_unloadlib (void *lib) {
static void *ll_load (lua_State *L, const char *path, int seeglb) {
HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
- (void)(seeglb); /* symbols are 'global' by default? */
+ (void)(seeglb); /* symbols are 'global' by default */
if (lib == NULL) pusherror(L);
return lib;
}
@@ -212,7 +212,7 @@ static void ll_unloadlib (void *lib) {
static void *ll_load (lua_State *L, const char *path, int seeglb) {
- (void)(path); /* to avoid warnings */
+ (void)(path); (void)(seeglb); /* to avoid warnings */
lua_pushliteral(L, DLMSG);
return NULL;
}
@@ -428,8 +428,6 @@ static int loader_Croot (lua_State *L) {
static int loader_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
- if (!lua_istable(L, -1))
- luaL_error(L, LUA_QL("package.preload") " must be a table");
lua_getfield(L, -1, name);
if (lua_isnil(L, -1)) /* not found? */
lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
@@ -498,7 +496,7 @@ static int ll_require (lua_State *L) {
#if defined(LUA_COMPAT_MODULE)
/*
-** changes the _ENV variable of calling function
+** changes the environment variable of calling function
*/
static void set_env (lua_State *L) {
lua_Debug ar;
diff --git a/src/lobject.c b/src/lobject.c
index d4fff394..f5fc09d7 100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.40 2010/04/18 13:22:48 roberto Exp $
+** $Id: lobject.c,v 2.43 2010/10/29 15:54:55 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -106,14 +106,19 @@ lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
}
+static int checkend (const char *s, const char *endptr) {
+ if (endptr == s) return 0; /* no characters converted */
+ while (lisspace(cast(unsigned char, *endptr))) endptr++;
+ return (*endptr == '\0'); /* OK if no trailing characters */
+}
+
+
int luaO_str2d (const char *s, lua_Number *result) {
char *endptr;
*result = lua_str2number(s, &endptr);
- if (endptr == s) return 0; /* conversion failed */
- if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
- *result = cast_num(strtoul(s, &endptr, 16));
- while (lisspace(cast(unsigned char, *endptr))) endptr++;
- return (*endptr == '\0'); /* OK if no trailing characters */
+ if (checkend(s, endptr)) return 1; /* conversion OK? */
+ *result = cast_num(strtoul(s, &endptr, 0)); /* try hexadecimal */
+ return checkend(s, endptr);
}
@@ -221,7 +226,7 @@ void luaO_chunkid (char *out, const char *source, size_t bufflen) {
else { /* string; format as [string "source"] */
const char *nl = strchr(source, '\n'); /* find first new line (if any) */
addstr(out, PRE, LL(PRE)); /* add prefix */
- bufflen -= LL(PRE RETS POS); /* save space for prefix+suffix */
+ bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
if (l < bufflen && nl == NULL) { /* small one-line source? */
addstr(out, source, l); /* keep it */
}
diff --git a/src/lopcodes.c b/src/lopcodes.c
index cc1acb13..af267224 100644
--- a/src/lopcodes.c
+++ b/src/lopcodes.c
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.c,v 1.43 2010/03/12 19:14:06 roberto Exp $
+** $Id: lopcodes.c,v 1.44 2010/10/13 16:45:54 roberto Exp $
** See Copyright Notice in lua.h
*/
@@ -48,11 +48,11 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
"FORLOOP",
"FORPREP",
"TFORCALL",
+ "TFORLOOP",
"SETLIST",
"CLOSE",
"CLOSURE",
"VARARG",
- "TFORLOOP",
"EXTRAARG",
NULL
};
@@ -96,11 +96,11 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
- ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
};
diff --git a/src/lopcodes.h b/src/lopcodes.h
index 4140db3a..af1dc9cd 100644
--- a/src/lopcodes.h
+++ b/src/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.135 2010/03/12 19:14:06 roberto Exp $
+** $Id: lopcodes.h,v 1.137 2010/10/25 12:24:55 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -17,6 +17,7 @@
`A' : 8 bits
`B' : 9 bits
`C' : 9 bits
+ 'Ax' : 26 bits ('A', 'B', and 'C' together)
`Bx' : 18 bits (`B' and `C' together)
`sBx' : signed Bx
@@ -122,7 +123,7 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */
| (cast(Instruction, bc)<<POS_Bx))
#define CREATE_Ax(o,a) ((cast(Instruction, o)<<POS_OP) \
- | (cast(Instruction, a)<<POS_A))
+ | (cast(Instruction, a)<<POS_Ax))
/*
@@ -212,6 +213,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2);
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
+OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
+
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
@@ -219,8 +222,6 @@ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
-OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
-
OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
} OpCode;
diff --git a/src/loslib.c b/src/loslib.c
index 9b27ebce..0278eb51 100644
--- a/src/loslib.c
+++ b/src/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.31 2010/07/02 12:01:53 roberto Exp $
+** $Id: loslib.c,v 1.32 2010/10/05 12:18:03 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -276,7 +276,11 @@ static int os_setlocale (lua_State *L) {
static int os_exit (lua_State *L) {
- int status = luaL_optint(L, 1, EXIT_SUCCESS);
+ int status;
+ if (lua_isboolean(L, 1))
+ status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
+ else
+ status = luaL_optint(L, 1, EXIT_SUCCESS);
if (lua_toboolean(L, 2))
lua_close(L);
exit(status);
diff --git a/src/lparser.c b/src/lparser.c
index 16c05d9e..3524b9b2 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.90 2010/07/07 16:27:29 roberto Exp $
+** $Id: lparser.c,v 2.92 2010/09/07 19:21:39 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -289,7 +289,7 @@ static void singlevar (LexState *ls, expdesc *var) {
FuncState *fs = ls->fs;
if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */
expdesc key;
- singlevaraux(fs, ls->envn, var, 1); /* get _ENV variable */
+ singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
lua_assert(var->k == VLOCAL || var->k == VUPVAL);
codestring(ls, &key, varname); /* key is variable name */
luaK_indexed(fs, var, &key); /* env[varname] */
@@ -352,15 +352,20 @@ static void leaveblock (FuncState *fs) {
}
-static void pushclosure (LexState *ls, Proto *clp, expdesc *v) {
+/*
+** adds prototype being created into its parent list of prototypes
+** and codes instruction to create new closure
+*/
+static void codeclosure (LexState *ls, Proto *clp, expdesc *v) {
FuncState *fs = ls->fs->prev;
Proto *f = fs->f; /* prototype of function creating new closure */
- int oldsize = f->sizep;
- luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
- MAXARG_Bx, "functions");
- while (oldsize < f->sizep) f->p[oldsize++] = NULL;
+ if (fs->np >= f->sizep) {
+ int oldsize = f->sizep;
+ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
+ MAXARG_Bx, "functions");
+ while (oldsize < f->sizep) f->p[oldsize++] = NULL;
+ }
f->p[fs->np++] = clp;
- /* initial environment for new function is current lexical environment */
luaC_objbarrier(ls->L, f, clp);
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
}
@@ -428,14 +433,14 @@ static void close_func (LexState *ls) {
/*
** opens the main function, which is a regular vararg function with an
-** upvalue named '_ENV'
+** upvalue named LUA_ENV
*/
static void open_mainfunc (LexState *ls, FuncState *fs) {
expdesc v;
open_func(ls, fs);
fs->f->is_vararg = 1; /* main function is always vararg */
init_exp(&v, VLOCAL, 0);
- newupvalue(fs, ls->envn, &v); /* create '_ENV' upvalue */
+ newupvalue(fs, ls->envn, &v); /* create environment upvalue */
}
@@ -653,7 +658,7 @@ static void body (LexState *ls, expdesc *e, int needself, int line) {
chunk(ls);
new_fs.f->lastlinedefined = ls->linenumber;
check_match(ls, TK_END, TK_FUNCTION, line);
- pushclosure(ls, new_fs.f, e);
+ codeclosure(ls, new_fs.f, e);
close_func(ls);
}
diff --git a/src/lstate.c b/src/lstate.c
index 6ea00b62..39a0ef4d 100644
--- a/src/lstate.c
+++ b/src/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.85 2010/04/30 18:36:22 roberto Exp $
+** $Id: lstate.c,v 2.86 2010/09/03 14:14:01 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -29,6 +29,10 @@
#define LUAI_GCPAUSE 200 /* 200% */
#endif
+#if !defined(LUAI_GCMAJOR)
+#define LUAI_GCMAJOR 200 /* 200% */
+#endif
+
#if !defined(LUAI_GCMUL)
#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
#endif
@@ -254,6 +258,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->weak = g->ephemeron = g->allweak = NULL;
g->totalbytes = sizeof(LG);
g->gcpause = LUAI_GCPAUSE;
+ g->gcmajorinc = LUAI_GCMAJOR;
g->gcstepmul = LUAI_GCMUL;
for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
diff --git a/src/lstate.h b/src/lstate.h
index e829ed4a..bc64a4ae 100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.65 2010/05/03 17:39:48 roberto Exp $
+** $Id: lstate.h,v 2.68 2010/10/29 17:52:46 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -66,13 +66,13 @@ typedef struct stringtable {
/*
-** informations about a call
+** information about a call
*/
typedef struct CallInfo {
StkId func; /* function index in the stack */
StkId top; /* top for this function */
struct CallInfo *previous, *next; /* dynamic call link */
- short nresults; /* expected number of results from a call */
+ short nresults; /* expected number of results from this function */
lu_byte callstatus;
union {
struct { /* only for Lua functions */
@@ -136,6 +136,7 @@ typedef struct global_State {
UpVal uvhead; /* head of double-linked list of all open upvalues */
Mbuffer buff; /* temporary buffer for string concatenation */
int gcpause; /* size of pause between successive GCs */
+ int gcmajorinc; /* how much to wait for a major GC (only in gen. mode) */
int gcstepmul; /* GC `granularity' */
lua_CFunction panic; /* to be called in unprotected errors */
struct lua_State *mainthread;
diff --git a/src/lstrlib.c b/src/lstrlib.c
index 558a748e..f2132005 100644
--- a/src/lstrlib.c
+++ b/src/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.154 2010/07/02 11:38:13 roberto Exp $
+** $Id: lstrlib.c,v 1.156 2010/10/29 17:52:46 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -424,7 +424,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
default: goto dflt;
}
}
- default: dflt: { /* pattern class plus optional sufix */
+ default: dflt: { /* pattern class plus optional suffix */
const char *ep = classend(ms, p); /* points to what is next */
int m = s < ms->src_end && singlematch(uchar(*s), p, ep);
switch (*ep) {
@@ -758,9 +758,9 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
else if (*s == '\0' || iscntrl(uchar(*s))) {
char buff[10];
if (!isdigit(uchar(*(s+1))))
- sprintf(buff, "\\%d", uchar(*s));
+ sprintf(buff, "\\%d", (int)uchar(*s));
else
- sprintf(buff, "\\%03d", uchar(*s));
+ sprintf(buff, "\\%03d", (int)uchar(*s));
luaL_addstring(b, buff);
}
else
diff --git a/src/ltablib.c b/src/ltablib.c
index b094d2f8..17ea33bc 100644
--- a/src/ltablib.c
+++ b/src/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.56 2010/07/02 11:38:13 roberto Exp $
+** $Id: ltablib.c,v 1.57 2010/10/25 19:01:37 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -16,7 +16,8 @@
#include "lualib.h"
-#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), lua_rawlen(L, n))
+#define aux_getn(L,n) \
+ (luaL_checktype(L, n, LUA_TTABLE), (int)lua_rawlen(L, n))
static int foreachi (lua_State *L) {
diff --git a/src/lua.c b/src/lua.c
index 7d23636f..fe2f0698 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -1,5 +1,5 @@
/*
-** $Id: lua.c,v 1.192 2010/07/25 15:03:37 roberto Exp $
+** $Id: lua.c,v 1.194 2010/10/25 19:01:37 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -369,10 +369,11 @@ static int collectargs (char **argv, int *pi, int *pv, int *pe) {
break;
case 'e':
*pe = 1; /* go through */
- case 'l':
- if (argv[i][2] == '\0') {
- i++;
- if (argv[i] == NULL) return -(i - 1);
+ case 'l': /* both options need an argument */
+ if (argv[i][2] == '\0') { /* no concatenated argument? */
+ i++; /* try next 'argv' */
+ if (argv[i] == NULL || argv[i][0] == '-')
+ return -(i - 1); /* no next argument or it is another option */
}
break;
default: /* invalid option; return its index... */
@@ -427,7 +428,7 @@ static int handle_luainit (lua_State *L) {
static int pmain (lua_State *L) {
- int argc = lua_tointeger(L, 1);
+ int argc = (int)lua_tointeger(L, 1);
char **argv = (char **)lua_touserdata(L, 2);
int script;
int has_i = 0, has_v = 0, has_e = 0;
diff --git a/src/lua.h b/src/lua.h
index d1cf33ab..9de92287 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.273 2010/07/25 15:18:19 roberto Exp $
+** $Id: lua.h,v 1.276 2010/10/26 19:32:19 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@@ -18,7 +18,7 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "2"
-#define LUA_VERSION_RELEASE "0" " (work4)"
+#define LUA_VERSION_RELEASE "0" " (work5)"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
@@ -106,6 +106,9 @@ typedef LUA_NUMBER lua_Number;
/* type for integer functions */
typedef LUA_INTEGER lua_Integer;
+/* unsigned integer type */
+typedef LUA_UNSIGNED lua_Unsigned;
+
/*
@@ -159,6 +162,7 @@ LUA_API const char *(lua_typename) (lua_State *L, int tp);
LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
+LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum);
LUA_API int (lua_toboolean) (lua_State *L, int idx);
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
LUA_API size_t (lua_rawlen) (lua_State *L, int idx);
@@ -196,6 +200,7 @@ LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
LUA_API void (lua_pushnil) (lua_State *L);
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
+LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n);
LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l);
LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
@@ -271,9 +276,10 @@ LUA_API int (lua_status) (lua_State *L);
#define LUA_GCSTEP 5
#define LUA_GCSETPAUSE 6
#define LUA_GCSETSTEPMUL 7
-#define LUA_GCISRUNNING 8
-#define LUA_GCGEN 9
-#define LUA_GCINC 10
+#define LUA_GCSETMAJORINC 8
+#define LUA_GCISRUNNING 9
+#define LUA_GCGEN 10
+#define LUA_GCINC 11
LUA_API int (lua_gc) (lua_State *L, int what, int data);
@@ -302,6 +308,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL)
#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL)
+#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL)
#define lua_pop(L,n) lua_settop(L, -(n)-1)
diff --git a/src/luac.c b/src/luac.c
index ee2026ba..19ef916d 100644
--- a/src/luac.c
+++ b/src/luac.c
@@ -1,5 +1,5 @@
/*
-** $Id: luac.c,v 1.61 2010/05/14 11:40:22 lhf Exp $
+** $Id: luac.c,v 1.65 2010/10/26 09:07:52 lhf Exp $
** Lua compiler (saves bytecodes to files; also list bytecodes)
** See Copyright Notice in lua.h
*/
@@ -15,14 +15,13 @@
#include "lua.h"
#include "lauxlib.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lmem.h"
#include "lobject.h"
-#include "lopcodes.h"
-#include "lstring.h"
+#include "lstate.h"
#include "lundump.h"
+static void PrintFunction(const Proto* f, int full);
+#define luaU_print PrintFunction
+
#define PROGNAME "luac" /* default program name */
#define OUTPUT PROGNAME ".out" /* default output file */
@@ -52,16 +51,16 @@ static void usage(const char* message)
else
fprintf(stderr,"%s: %s\n",progname,message);
fprintf(stderr,
- "usage: %s [options] [filenames]\n"
- "Available options are:\n"
- " -l list\n"
- " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
- " -p parse only\n"
- " -s strip debug information\n"
- " -v show version information\n"
- " -- stop handling options\n"
- " - stop handling options and process stdin\n"
- ,progname,Output);
+ "usage: %s [options] [filenames]\n"
+ "Available options are:\n"
+ " -l list\n"
+ " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
+ " -p parse only\n"
+ " -s strip debug information\n"
+ " -v show version information\n"
+ " -- stop handling options\n"
+ " - stop handling options and process stdin\n"
+ ,progname,Output);
exit(EXIT_FAILURE);
}
@@ -89,7 +88,8 @@ static int doargs(int argc, char* argv[])
else if (IS("-o")) /* output file */
{
output=argv[++i];
- if (output==NULL || *output==0 || *output=='-') usage(LUA_QL("-o") " needs argument");
+ if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
+ usage(LUA_QL("-o") " needs argument");
if (IS("-")) output=NULL;
}
else if (IS("-p")) /* parse only */
@@ -114,7 +114,24 @@ static int doargs(int argc, char* argv[])
return i;
}
-#define toproto(L,i) (clvalue(L->top+(i))->l.p)
+#define FUNCTION "(function()end)();"
+
+static const char* reader(lua_State *L, void *ud, size_t *size)
+{
+ UNUSED(L);
+ if ((*(int*)ud)--)
+ {
+ *size=sizeof(FUNCTION)-1;
+ return FUNCTION;
+ }
+ else
+ {
+ *size=0;
+ return NULL;
+ }
+}
+
+#define toproto(L,i) getproto(L->top+(i))
static const Proto* combine(lua_State* L, int n)
{
@@ -122,24 +139,13 @@ static const Proto* combine(lua_State* L, int n)
return toproto(L,-1);
else
{
- int i,pc;
- Proto* f=luaF_newproto(L);
- setptvalue2s(L,L->top,f); incr_top(L);
- f->source=luaS_newliteral(L,"=(" PROGNAME ")");
- f->maxstacksize=1;
- pc=2*n+1;
- f->code=luaM_newvector(L,pc,Instruction);
- f->sizecode=pc;
- f->p=luaM_newvector(L,n,Proto*);
- f->sizep=n;
- pc=0;
- for (i=0; i<n; i++)
- {
- f->p[i]=toproto(L,i-n-1);
- f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i);
- f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1);
- }
- f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0);
+ Proto* f;
+ int i=n;
+ if (lua_load(L,reader,&i,"=(" PROGNAME ")")!=LUA_OK) fatal(lua_tostring(L,-1));
+ f=toproto(L,-1);
+ for (i=0; i<n; i++) f->p[i]=toproto(L,i-n-1);
+ f->sizelineinfo=0;
+ f->sizeupvalues=0;
return f;
}
}
@@ -152,7 +158,7 @@ static int writer(lua_State* L, const void* p, size_t size, void* u)
static int pmain(lua_State* L)
{
- int argc=lua_tointeger(L,1);
+ int argc=(int)lua_tointeger(L,1);
char** argv=lua_touserdata(L,2);
const Proto* f;
int i;
@@ -160,7 +166,7 @@ static int pmain(lua_State* L)
for (i=0; i<argc; i++)
{
const char* filename=IS("-") ? NULL : argv[i];
- if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
+ if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1));
}
f=combine(L,argc);
if (listing) luaU_print(f,listing>1);
@@ -188,7 +194,235 @@ int main(int argc, char* argv[])
lua_pushcfunction(L,&pmain);
lua_pushinteger(L,argc);
lua_pushlightuserdata(L,argv);
- if (lua_pcall(L,2,0,0)!=0) fatal(lua_tostring(L,-1));
+ if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
lua_close(L);
return EXIT_SUCCESS;
}
+
+/*
+** $Id: print.c,v 1.66 2010/10/26 09:07:52 lhf Exp $
+** print bytecodes
+** See Copyright Notice in lua.h
+*/
+
+#include <ctype.h>
+#include <stdio.h>
+
+#define luac_c
+#define LUA_CORE
+
+#include "ldebug.h"
+#include "lobject.h"
+#include "lopcodes.h"
+
+#define Sizeof(x) ((int)sizeof(x))
+#define VOID(p) ((const void*)(p))
+
+static void PrintString(const TString* ts)
+{
+ const char* s=getstr(ts);
+ size_t i,n=ts->tsv.len;
+ printf("%c",'"');
+ for (i=0; i<n; i++)
+ {
+ int c=(int)(unsigned char)s[i];
+ switch (c)
+ {
+ case '"': printf("\\\""); break;
+ case '\\': printf("\\\\"); break;
+ case '\a': printf("\\a"); break;
+ case '\b': printf("\\b"); break;
+ case '\f': printf("\\f"); break;
+ case '\n': printf("\\n"); break;
+ case '\r': printf("\\r"); break;
+ case '\t': printf("\\t"); break;
+ case '\v': printf("\\v"); break;
+ default: if (isprint(c))
+ printf("%c",c);
+ else
+ printf("\\%03d",c);
+ }
+ }
+ printf("%c",'"');
+}
+
+static void PrintConstant(const Proto* f, int i)
+{
+ const TValue* o=&f->k[i];
+ switch (ttype(o))
+ {
+ case LUA_TNIL:
+ printf("nil");
+ break;
+ case LUA_TBOOLEAN:
+ printf(bvalue(o) ? "true" : "false");
+ break;
+ case LUA_TNUMBER:
+ printf(LUA_NUMBER_FMT,nvalue(o));
+ break;
+ case LUA_TSTRING:
+ PrintString(rawtsvalue(o));
+ break;
+ default: /* cannot happen */
+ printf("? type=%d",ttype(o));
+ break;
+ }
+}
+
+#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
+
+static void PrintCode(const Proto* f)
+{
+ const Instruction* code=f->code;
+ int pc,n=f->sizecode;
+ for (pc=0; pc<n; pc++)
+ {
+ Instruction i=code[pc];
+ OpCode o=GET_OPCODE(i);
+ int a=GETARG_A(i);
+ int b=GETARG_B(i);
+ int c=GETARG_C(i);
+ int ax=GETARG_Ax(i);
+ int bx=GETARG_Bx(i);
+ int sbx=GETARG_sBx(i);
+ int line=getfuncline(f,pc);
+ printf("\t%d\t",pc+1);
+ if (line>0) printf("[%d]\t",line); else printf("[-]\t");
+ printf("%-9s\t",luaP_opnames[o]);
+ switch (getOpMode(o))
+ {
+ case iABC:
+ printf("%d",a);
+ if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
+ if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
+ break;
+ case iABx:
+ if (getBMode(o)==OpArgK) printf("%d %d",a,-bx); else printf("%d %d",a,bx);
+ break;
+ case iAsBx:
+ if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
+ break;
+ case iAx:
+ printf("%d",-1-ax);
+ break;
+ }
+ switch (o)
+ {
+ case OP_LOADK:
+ if (bx>0) { printf("\t; "); PrintConstant(f,bx-1); }
+ break;
+ case OP_GETUPVAL:
+ case OP_SETUPVAL:
+ printf("\t; %s",UPVALNAME(b));
+ break;
+ case OP_GETTABUP:
+ printf("\t; %s",UPVALNAME(b));
+ if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
+ break;
+ case OP_SETTABUP:
+ printf("\t; %s",UPVALNAME(a));
+ if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
+ if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
+ break;
+ case OP_GETTABLE:
+ case OP_SELF:
+ if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
+ break;
+ case OP_SETTABLE:
+ case OP_ADD:
+ case OP_SUB:
+ case OP_MUL:
+ case OP_DIV:
+ case OP_POW:
+ case OP_EQ:
+ case OP_LT:
+ case OP_LE:
+ if (ISK(b) || ISK(c))
+ {
+ printf("\t; ");
+ if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
+ printf(" ");
+ if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
+ }
+ break;
+ case OP_JMP:
+ case OP_FORLOOP:
+ case OP_FORPREP:
+ case OP_TFORLOOP:
+ printf("\t; to %d",sbx+pc+2);
+ break;
+ case OP_CLOSURE:
+ printf("\t; %p",VOID(f->p[bx]));
+ break;
+ case OP_SETLIST:
+ if (c==0) printf("\t; %d",(int)code[++pc]);
+ else printf("\t; %d",c);
+ break;
+ case OP_EXTRAARG:
+ printf("\t; "); PrintConstant(f,ax);
+ break;
+ default:
+ break;
+ }
+ printf("\n");
+ }
+}
+
+#define SS(x) ((x==1)?"":"s")
+#define S(x) (int)(x),SS(x)
+
+static void PrintHeader(const Proto* f)
+{
+ const char* s=f->source ? getstr(f->source) : "=?";
+ if (*s=='@' || *s=='=')
+ s++;
+ else if (*s==LUA_SIGNATURE[0])
+ s="(bstring)";
+ else
+ s="(string)";
+ printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
+ (f->linedefined==0)?"main":"function",s,
+ f->linedefined,f->lastlinedefined,
+ S(f->sizecode),VOID(f));
+ printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
+ (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
+ S(f->maxstacksize),S(f->sizeupvalues));
+ printf("%d local%s, %d constant%s, %d function%s\n",
+ S(f->sizelocvars),S(f->sizek),S(f->sizep));
+}
+
+static void PrintDebug(const Proto* f)
+{
+ int i,n;
+ n=f->sizek;
+ printf("constants (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+ printf("\t%d\t",i+1);
+ PrintConstant(f,i);
+ printf("\n");
+ }
+ n=f->sizelocvars;
+ printf("locals (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+ printf("\t%d\t%s\t%d\t%d\n",
+ i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
+ }
+ n=f->sizeupvalues;
+ printf("upvalues (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+ printf("\t%d\t%s\t%d\t%d\n",
+ i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
+ }
+}
+
+static void PrintFunction(const Proto* f, int full)
+{
+ int i,n=f->sizep;
+ PrintHeader(f);
+ PrintCode(f);
+ if (full) PrintDebug(f);
+ for (i=0; i<n; i++) PrintFunction(f->p[i],full);
+}
diff --git a/src/luaconf.h b/src/luaconf.h
index 12ec5fc1..2345e00c 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.142 2010/07/28 15:51:59 roberto Exp $
+** $Id: luaconf.h,v 1.148 2010/10/29 17:52:46 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -47,8 +47,8 @@
#if defined(LUA_USE_MACOSX)
#define LUA_USE_POSIX
-#define LUA_USE_DLOPEN
-#define LUA_USE_READLINE /* needs some extra libraries */
+#define LUA_USE_DLOPEN /* does not need -ldl */
+#define LUA_USE_READLINE /* needs an extra library: -lreadline */
#endif
@@ -116,6 +116,14 @@
/*
+@@ LUA_ENV is the name of the variable that holds the current
+@@ environment, used to access global names.
+** CHANGE it if you do not like this name.
+*/
+#define LUA_ENV "_ENV"
+
+
+/*
@@ LUA_API is a mark for all core API functions.
@@ LUALIB_API is a mark for all auxiliary library functions.
@@ LUAMOD_API is a mark for all standard library opening functions.
@@ -430,26 +438,28 @@
*/
#define LUA_INTEGER ptrdiff_t
+/*
+@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned.
+** It must have at least 32 bits.
+*/
+#define LUA_UNSIGNED unsigned LUA_INT32
+
/*
@@ lua_number2int is a macro to convert lua_Number to int.
@@ lua_number2integer is a macro to convert lua_Number to LUA_INTEGER.
-@@ lua_number2uint is a macro to convert a lua_Number to an unsigned
-@* LUA_INT32.
-@@ lua_uint2number is a macro to convert an unsigned LUA_INT32
-@* to a lua_Number.
-** CHANGE them if you know a faster way to convert a lua_Number to
-** int (with any rounding method and without throwing errors) in your
-** system. In Pentium machines, a naive typecast from double to int
-** in C is extremely slow, so any alternative is worth trying.
+@@ lua_number2uint is a macro to convert a lua_Number to a LUA_UNSIGNED.
+@@ lua_uint2number is a macro to convert a LUA_UNSIGNED to a lua_Number.
*/
-/* On a Pentium, resort to a trick */
-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
- (defined(__i386) || defined (_M_IX86) || defined(__i386__)) /* { */
+#if defined(LUA_CORE) /* { */
+
+#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && \
+ !defined(LUA_NOIEEE754TRICK) /* { */
-/* On a Microsoft compiler, use assembler */
-#if defined(_MSC_VER) /* { */
+/* On a Microsoft compiler on a Pentium, use assembler to avoid clashes
+ with a DirectX idiosyncrasy */
+#if defined(_MSC_VER) && defined(M_IX86) /* { */
#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i}
#define lua_number2integer(i,n) lua_number2int(i, n)
@@ -457,31 +467,76 @@
{__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;}
#else /* }{ */
-/* the next trick should work on any Pentium, but sometimes clashes
- with a DirectX idiosyncrasy */
+/* the next trick should work on any machine using IEEE754 with
+ a 32-bit integer type */
-union luai_Cast { double l_d; long l_l; };
-#define lua_number2int(i,n) \
- { volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; (i) = u.l_l; }
-#define lua_number2integer(i,n) lua_number2int(i, n)
-#define lua_number2uint(i,n) lua_number2int(i, n)
+union luai_Cast { double l_d; LUA_INT32 l_p[2]; };
+
+/*
+@@ LUA_IEEEENDIAN is the endianness of doubles in your machine
+@@ (0 for little endian, 1 for big endian); if not defined, Lua will
+@@ check it dynamically.
+*/
+/* check for known architectures */
+#if defined(__i386__) || defined(__i386) || defined(i386) || \
+ defined (__x86_64)
+#define LUA_IEEEENDIAN 0
+#elif defined(__POWERPC__) || defined(__ppc__)
+#define LUA_IEEEENDIAN 1
+#endif
+
+#if !defined(LUA_IEEEENDIAN) /* { */
+#define LUAI_EXTRAIEEE \
+ static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)};
+#define LUA_IEEEENDIAN (ieeeendian.l_p[1] == 33)
+#else
+#define LUAI_EXTRAIEEE /* empty */
+#endif /* } */
+
+#define lua_number2int32(i,n,t) \
+ { LUAI_EXTRAIEEE \
+ volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \
+ (i) = (t)u.l_p[LUA_IEEEENDIAN]; }
+
+#define lua_number2int(i,n) lua_number2int32(i, n, int)
+#define lua_number2integer(i,n) lua_number2int32(i, n, LUA_INTEGER)
+#define lua_number2uint(i,n) lua_number2int32(i, n, LUA_UNSIGNED)
#endif /* } */
-#else /* }{ */
-/* this option always works, but may be slow */
+#endif /* } */
+
+
+/* the following definitions always work, but may be slow */
+
+#if !defined(lua_number2int)
#define lua_number2int(i,n) ((i)=(int)(n))
-#define lua_number2integer(i,n) ((i)=(LUA_INTEGER)(n))
-#define lua_number2uint(i,n) ((i)=(unsigned LUA_INT32)(n))
+#endif
-#endif /* } */
+#if !defined(lua_number2integer)
+#define lua_number2integer(i,n) ((i)=(LUA_INTEGER)(n))
+#endif
+#if !defined(lua_number2uint) && (defined(lapi_c) || defined(luaall_c)) /* { */
+/* the following definition assures proper modulo behavior */
+#if defined(LUA_NUMBER_DOUBLE)
+#include <math.h>
+#define lua_number2uint(i,n) \
+ ((i)=(LUA_UNSIGNED)((n) - floor((n)/4294967296.0)*4294967296.0))
+#else
+#define lua_number2uint(i,n) ((i)=(LUA_UNSIGNED)(n))
+#endif
+#endif /* } */
-/* on several machines, coercion from unsigned to double is too slow,
- so avoid that if possible */
+#if !defined(lua_uint2number)
+/* on several machines, coercion from unsigned to double is slow,
+ so it may be worth to avoid */
#define lua_uint2number(u) \
((LUA_INT32)(u) < 0 ? (lua_Number)(u) : (lua_Number)(LUA_INT32)(u))
+#endif
+
+#endif /* } */
/*
diff --git a/src/lualib.h b/src/lualib.h
index db2e200e..233a331e 100644
--- a/src/lualib.h
+++ b/src/lualib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lualib.h,v 1.40 2010/06/10 21:29:47 roberto Exp $
+** $Id: lualib.h,v 1.41 2010/10/25 14:32:36 roberto Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -32,8 +32,8 @@ LUAMOD_API int (luaopen_os) (lua_State *L);
#define LUA_STRLIBNAME "string"
LUAMOD_API int (luaopen_string) (lua_State *L);
-#define LUA_BITLIBNAME "bit"
-LUAMOD_API int (luaopen_bit) (lua_State *L);
+#define LUA_BITLIBNAME "bit32"
+LUAMOD_API int (luaopen_bit32) (lua_State *L);
#define LUA_MATHLIBNAME "math"
LUAMOD_API int (luaopen_math) (lua_State *L);
diff --git a/src/lundump.c b/src/lundump.c
index e82e1951..c875d767 100644
--- a/src/lundump.c
+++ b/src/lundump.c
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.c,v 2.13 2010/03/12 19:14:06 roberto Exp $
+** $Id: lundump.c,v 1.68 2010/10/26 00:23:46 lhf Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -27,27 +27,20 @@ typedef struct {
const char* name;
} LoadState;
-#ifdef LUAC_TRUST_BINARIES
-#define IF(c,s)
-#else
-#define IF(c,s) if (c) error(S,s)
-
static void error(LoadState* S, const char* why)
{
- luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
+ luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why);
luaD_throw(S->L,LUA_ERRSYNTAX);
}
-#endif
#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
-#define LoadByte(S) (lu_byte)LoadChar(S)
+#define LoadByte(S) (lu_byte)LoadChar(S)
#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
static void LoadBlock(LoadState* S, void* b, size_t size)
{
- size_t r=luaZ_read(S->Z,b,size);
- IF (r!=0, "unexpected end");
+ if (luaZ_read(S->Z,b,size)!=0) error(S,"corrupted");
}
static int LoadChar(LoadState* S)
@@ -61,7 +54,6 @@ static int LoadInt(LoadState* S)
{
int x;
LoadVar(S,x);
- IF (x<0, "bad integer");
return x;
}
@@ -94,7 +86,7 @@ static void LoadCode(LoadState* S, Proto* f)
LoadVector(S,f->code,n,sizeof(Instruction));
}
-static Proto* LoadFunction(LoadState* S, TString* p);
+static Proto* LoadFunction(LoadState* S);
static void LoadConstants(LoadState* S, Proto* f)
{
@@ -113,7 +105,7 @@ static void LoadConstants(LoadState* S, Proto* f)
setnilvalue(o);
break;
case LUA_TBOOLEAN:
- setbvalue(o,LoadChar(S)!=0);
+ setbvalue(o,LoadChar(S));
break;
case LUA_TNUMBER:
setnvalue(o,LoadNumber(S));
@@ -121,16 +113,13 @@ static void LoadConstants(LoadState* S, Proto* f)
case LUA_TSTRING:
setsvalue2n(S->L,o,LoadString(S));
break;
- default:
- IF (1, "bad constant");
- break;
}
}
n=LoadInt(S);
f->p=luaM_newvector(S->L,n,Proto*);
f->sizep=n;
for (i=0; i<n; i++) f->p[i]=NULL;
- for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
+ for (i=0; i<n; i++) f->p[i]=LoadFunction(S);
}
static void LoadUpvalues(LoadState* S, Proto* f)
@@ -150,6 +139,7 @@ static void LoadUpvalues(LoadState* S, Proto* f)
static void LoadDebug(LoadState* S, Proto* f)
{
int i,n;
+ f->source=LoadString(S);
n=LoadInt(S);
f->lineinfo=luaM_newvector(S->L,n,int);
f->sizelineinfo=n;
@@ -168,13 +158,10 @@ static void LoadDebug(LoadState* S, Proto* f)
for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
}
-static Proto* LoadFunction(LoadState* S, TString* p)
+static Proto* LoadFunction(LoadState* S)
{
- Proto* f;
- if (++G(S->L)->nCcalls > LUAI_MAXCCALLS) error(S, "function nest too deep");
- f=luaF_newproto(S->L);
+ Proto* f=luaF_newproto(S->L);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
- f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->linedefined=LoadInt(S);
f->lastlinedefined=LoadInt(S);
f->numparams=LoadByte(S);
@@ -185,17 +172,25 @@ static Proto* LoadFunction(LoadState* S, TString* p)
LoadUpvalues(S,f);
LoadDebug(S,f);
S->L->top--;
- G(S->L)->nCcalls--;
return f;
}
+/* the code below must be consistent with the code in luaU_header */
+#define N0 LUAC_HEADERSIZE
+#define N1 (sizeof(LUA_SIGNATURE)-1)
+#define N2 N1+2
+#define N3 N2+6
+
static void LoadHeader(LoadState* S)
{
char h[LUAC_HEADERSIZE];
char s[LUAC_HEADERSIZE];
luaU_header(h);
LoadBlock(S,s,LUAC_HEADERSIZE);
- IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
+ if (memcmp(h,s,N0)==0) return;
+ if (memcmp(h,s,N1)!=0) error(S,"not a");
+ if (memcmp(h,s,N2)!=0) error(S,"version mismatch in");
+ if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted");
}
/*
@@ -214,23 +209,29 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
S.Z=Z;
S.b=buff;
LoadHeader(&S);
- return LoadFunction(&S,luaS_newliteral(L,"=?"));
+ return LoadFunction(&S);
}
+/* data to catch conversion errors */
+#define TAIL "\x19\x93\r\n\x1a\n"
+
/*
-* make header
+* make header for precompiled chunks
+* if you make any changes in the code below or in LUA_SIGNATURE in lua.h,
+* be sure to update LoadHeader above and LUAC_HEADERSIZE in lundump.h
*/
void luaU_header (char* h)
{
int x=1;
memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
h+=sizeof(LUA_SIGNATURE)-1;
- *h++=(char)LUAC_VERSION;
- *h++=(char)LUAC_FORMAT;
+ *h++=(char)0x52; /* Lua 5.2 */
+ *h++=(char)0; /* the official format */
*h++=(char)*(char*)&x; /* endianness */
*h++=(char)sizeof(int);
*h++=(char)sizeof(size_t);
*h++=(char)sizeof(Instruction);
*h++=(char)sizeof(lua_Number);
*h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
+ memcpy(h,TAIL,sizeof(TAIL)-1);
}
diff --git a/src/lundump.h b/src/lundump.h
index 5b19104f..e55918cf 100644
--- a/src/lundump.h
+++ b/src/lundump.h
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.h,v 1.37 2005/11/16 11:55:07 roberto Exp $
+** $Id: lundump.h,v 1.43 2010/10/26 00:23:46 lhf Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -19,18 +19,7 @@ LUAI_FUNC void luaU_header (char* h);
/* dump one chunk; from ldump.c */
LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
-#ifdef luac_c
-/* print one chunk; from print.c */
-LUAI_FUNC void luaU_print (const Proto* f, int full);
-#endif
-
-/* for header of binary files -- this is Lua 5.1 */
-#define LUAC_VERSION 0x51
-
-/* for header of binary files -- this is the official format */
-#define LUAC_FORMAT 0
-
/* size of header of binary files */
-#define LUAC_HEADERSIZE 12
+#define LUAC_HEADERSIZE 18
#endif
diff --git a/src/lvm.c b/src/lvm.c
index a222049b..42c6c81f 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.123 2010/06/30 14:11:17 roberto Exp $
+** $Id: lvm.c,v 2.125 2010/10/29 17:52:46 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -301,7 +301,7 @@ void luaV_concat (lua_State *L, int total) {
setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
}
total -= n-1; /* got 'n' strings to create 1 new */
- L->top -= n-1; /* poped 'n' strings and pushed one */
+ L->top -= n-1; /* popped 'n' strings and pushed one */
} while (total > 1); /* repeat until only 1 result left */
}
@@ -421,7 +421,7 @@ void luaV_finishOp (lua_State *L) {
case OP_CONCAT: {
StkId top = L->top - 1; /* top when 'call_binTM' was called */
int b = GETARG_B(inst); /* first element to concatenate */
- int total = top - 1 - (base + b); /* elements yet to concatenate */
+ int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */
setobj2s(L, top - 2, top); /* put TM result in proper position */
if (total > 1) { /* are there elements to concat? */
L->top = top - 1; /* top is one after last element (at top-2) */
diff --git a/src/print.c b/src/print.c
deleted file mode 100644
index 83a1cd68..00000000
--- a/src/print.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
-** $Id: print.c,v 1.61 2010/07/31 11:34:07 lhf Exp $
-** print bytecodes
-** See Copyright Notice in lua.h
-*/
-
-#include <ctype.h>
-#include <stdio.h>
-
-#define luac_c
-#define LUA_CORE
-
-#include "ldebug.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lundump.h"
-
-#define PrintFunction luaU_print
-
-#define Sizeof(x) ((int)sizeof(x))
-#define VOID(p) ((const void*)(p))
-
-static void PrintString(const TString* ts)
-{
- const char* s=getstr(ts);
- size_t i,n=ts->tsv.len;
- putchar('"');
- for (i=0; i<n; i++)
- {
- int c=s[i];
- switch (c)
- {
- case '"': printf("\\\""); break;
- case '\\': printf("\\\\"); break;
- case '\a': printf("\\a"); break;
- case '\b': printf("\\b"); break;
- case '\f': printf("\\f"); break;
- case '\n': printf("\\n"); break;
- case '\r': printf("\\r"); break;
- case '\t': printf("\\t"); break;
- case '\v': printf("\\v"); break;
- default: if (isprint((unsigned char)c))
- putchar(c);
- else
- printf("\\%03u",(unsigned char)c);
- }
- }
- putchar('"');
-}
-
-static void PrintConstant(const Proto* f, int i)
-{
- const TValue* o=&f->k[i];
- switch (ttype(o))
- {
- case LUA_TNIL:
- printf("nil");
- break;
- case LUA_TBOOLEAN:
- printf(bvalue(o) ? "true" : "false");
- break;
- case LUA_TNUMBER:
- printf(LUA_NUMBER_FMT,nvalue(o));
- break;
- case LUA_TSTRING:
- PrintString(rawtsvalue(o));
- break;
- default: /* cannot happen */
- printf("? type=%d",ttype(o));
- break;
- }
-}
-
-#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
-
-static void PrintCode(const Proto* f)
-{
- const Instruction* code=f->code;
- int pc,n=f->sizecode;
- for (pc=0; pc<n; pc++)
- {
- Instruction i=code[pc];
- OpCode o=GET_OPCODE(i);
- int a=GETARG_A(i);
- int b=GETARG_B(i);
- int c=GETARG_C(i);
- int ax=GETARG_Ax(i);
- int bx=GETARG_Bx(i);
- int sbx=GETARG_sBx(i);
- int line=getfuncline(f,pc);
-#ifdef LUAC_DUMP_INSTRUCTIONS
- printf("%0*X",2*sizeof(i),i);
-#endif
- printf("\t%d\t",pc+1);
- if (line>0) printf("[%d]\t",line); else printf("[-]\t");
- printf("%-9s\t",luaP_opnames[o]);
- switch (getOpMode(o))
- {
- case iABC:
- printf("%d",a);
- if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
- if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
- break;
- case iABx:
- if (getBMode(o)==OpArgK) printf("%d %d",a,-bx); else printf("%d %d",a,bx);
- break;
- case iAsBx:
- if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
- break;
- case iAx:
- printf("%d",ax);
- break;
- }
- switch (o)
- {
- case OP_LOADK:
- printf("\t; "); PrintConstant(f,bx-1);
- break;
- case OP_GETUPVAL:
- case OP_SETUPVAL:
- printf("\t; %s", UPVALNAME(b));
- break;
- case OP_GETTABUP:
- printf("\t; %s", UPVALNAME(b));
- if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
- break;
- case OP_SETTABUP:
- printf("\t; %s", UPVALNAME(a));
- if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
- if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
- break;
- case OP_GETTABLE:
- case OP_SELF:
- if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
- break;
- case OP_SETTABLE:
- case OP_ADD:
- case OP_SUB:
- case OP_MUL:
- case OP_DIV:
- case OP_POW:
- case OP_EQ:
- case OP_LT:
- case OP_LE:
- if (ISK(b) || ISK(c))
- {
- printf("\t; ");
- if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
- printf(" ");
- if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
- }
- break;
- case OP_JMP:
- case OP_FORLOOP:
- case OP_FORPREP:
- printf("\t; to %d",sbx+pc+2);
- break;
- case OP_CLOSURE:
- printf("\t; %p",VOID(f->p[bx]));
- break;
- case OP_SETLIST:
- if (c==0) printf("\t; %d",(int)code[++pc]);
- else printf("\t; %d",c);
- break;
- default:
- break;
- }
- printf("\n");
- }
-}
-
-#define SS(x) ((x==1)?"":"s")
-#define S(x) x,SS(x)
-
-static void PrintHeader(const Proto* f)
-{
- const char* s=getstr(f->source);
- if (*s=='@' || *s=='=')
- s++;
- else if (*s==LUA_SIGNATURE[0])
- s="(bstring)";
- else
- s="(string)";
- printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
- (f->linedefined==0)?"main":"function",s,
- f->linedefined,f->lastlinedefined,
- S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
- printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
- f->numparams,f->is_vararg?"+":"",SS(f->numparams),
- S(f->maxstacksize),S(f->sizeupvalues));
- printf("%d local%s, %d constant%s, %d function%s\n",
- S(f->sizelocvars),S(f->sizek),S(f->sizep));
-}
-
-static void PrintDebug(const Proto* f)
-{
- int i,n;
- n=f->sizek;
- printf("constants (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t",i+1);
- PrintConstant(f,i);
- printf("\n");
- }
- n=f->sizelocvars;
- printf("locals (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\t%d\t%d\n",
- i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
- }
- n=f->sizeupvalues;
- printf("upvalues (%d) for %p:\n",n,VOID(f));
- if (f->upvalues==NULL) return;
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\n",i,getstr(f->upvalues[i].name));
- }
-}
-
-void PrintFunction(const Proto* f, int full)
-{
- int i,n=f->sizep;
- PrintHeader(f);
- PrintCode(f);
- if (full) PrintDebug(f);
- for (i=0; i<n; i++) PrintFunction(f->p[i],full);
-}
diff --git a/test/hello.lua b/test/hello.lua
deleted file mode 100644
index 0925498f..00000000
--- a/test/hello.lua
+++ /dev/null
@@ -1,3 +0,0 @@
--- the first program in every language
-
-io.write("Hello world, from ",_VERSION,"!\n")