diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | README | 6 | ||||
-rw-r--r-- | doc/Makefile | 9 | ||||
-rw-r--r-- | doc/contents.html | 30 | ||||
-rw-r--r-- | doc/manual.html | 490 | ||||
-rw-r--r-- | doc/readme.html | 128 | ||||
-rw-r--r-- | src/Makefile | 14 | ||||
-rw-r--r-- | src/lapi.c | 50 | ||||
-rw-r--r-- | src/lauxlib.c | 75 | ||||
-rw-r--r-- | src/lauxlib.h | 5 | ||||
-rw-r--r-- | src/lbaselib.c | 18 | ||||
-rw-r--r-- | src/lbitlib.c | 82 | ||||
-rw-r--r-- | src/ldebug.c | 18 | ||||
-rw-r--r-- | src/ldo.c | 9 | ||||
-rw-r--r-- | src/ldump.c | 15 | ||||
-rw-r--r-- | src/lgc.c | 6 | ||||
-rw-r--r-- | src/linit.c | 4 | ||||
-rw-r--r-- | src/liolib.c | 4 | ||||
-rw-r--r-- | src/llex.c | 14 | ||||
-rw-r--r-- | src/lmathlib.c | 4 | ||||
-rw-r--r-- | src/loadlib.c | 10 | ||||
-rw-r--r-- | src/lobject.c | 19 | ||||
-rw-r--r-- | src/lopcodes.c | 6 | ||||
-rw-r--r-- | src/lopcodes.h | 9 | ||||
-rw-r--r-- | src/loslib.c | 8 | ||||
-rw-r--r-- | src/lparser.c | 27 | ||||
-rw-r--r-- | src/lstate.c | 7 | ||||
-rw-r--r-- | src/lstate.h | 7 | ||||
-rw-r--r-- | src/lstrlib.c | 8 | ||||
-rw-r--r-- | src/ltablib.c | 5 | ||||
-rw-r--r-- | src/lua.c | 13 | ||||
-rw-r--r-- | src/lua.h | 17 | ||||
-rw-r--r-- | src/luac.c | 312 | ||||
-rw-r--r-- | src/luaconf.h | 115 | ||||
-rw-r--r-- | src/lualib.h | 6 | ||||
-rw-r--r-- | src/lundump.c | 59 | ||||
-rw-r--r-- | src/lundump.h | 15 | ||||
-rw-r--r-- | src/lvm.c | 6 | ||||
-rw-r--r-- | src/print.c | 229 | ||||
-rw-r--r-- | test/hello.lua | 3 |
40 files changed, 1099 insertions, 765 deletions
@@ -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) @@ -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 – The Debug Library</A> </UL> <P> -<LI><A HREF="manual.html#7">7 – Lua Stand-alone</A> +<LI><A HREF="manual.html#7">7 – Lua Standalone</A> <P> <LI><A HREF="manual.html#8">8 – 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 – <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 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 – <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 – <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 – <a name="2.2">Environments and the Global Environment</a></h2> <p> As discussed in <a href="#3.2">§3.2</a> and <a href="#3.3.3">§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">§3.3.2</a>). +variable called <code>_ENV</code> (see <a href="#3.3.2">§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 – <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 – <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 – <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 – <a name="2.5.1">Garbage-Collection Metamethods</a></h3> <p> Using the C 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 – <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 – <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 – <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 – <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 – <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 – <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 – <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">§3.3.4</a>). -<h3>3.3.2 - <a name="3.3.2">Chunks</a></h3> +<h3>3.3.2 – <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">§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 – <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 – <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 – <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 – <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">§3.4.9</a>. -<h3>3.3.7 - <a name="3.3.7">Local Declarations</a></h3><p> +<h3>3.3.7 – <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">§3 -<h2>3.4 - <a name="3.4">Expressions</a></h2> +<h2>3.4 – <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 – <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 – <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 – <a name="3.4.3">Relational Operators</a></h3><p> The relational operators in Lua are <pre> @@ -1812,7 +1842,7 @@ and <code>a >= b</code> is translated to <code>b <= a</code>. -<h3>3.4.4 - <a name="3.4.4">Logical Operators</a></h3><p> +<h3>3.4.4 – <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">§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 – <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">§2.4</a>). -<h3>3.4.6 - <a name="3.4.6">The Length Operator</a></h3> +<h3>3.4.6 – <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">§2.4</a>). -<h3>3.4.7 - <a name="3.4.7">Precedence</a></h3><p> +<h3>3.4.7 – <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 – <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 – <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 – <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 – <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 – <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 – <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 1 and the stack top -<h2>4.2 - <a name="4.2">Stack Size</a></h2> +<h2>4.2 – <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 – <a name="4.3">Pseudo-Indices</a></h2> <p> Unless otherwise noted, @@ -2399,7 +2429,7 @@ and the upvalues of a C function (see <a href="#4.4">§4.4</a>). -<h2>4.4 - <a name="4.4">C Closures</a></h2> +<h2>4.4 – <a name="4.4">C Closures</a></h2> <p> When a C 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 – <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 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 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 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 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 – <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 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 – <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 – <a name="4.8">Functions and Types</a></h2> <p> Here we list all functions and types from the C 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">§4.5</a>). (When loading main chunks, this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">§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">§3.4.2</a>); +otherwise, <a href="#lua_tounsignedx"><code>lua_tounsignedx</code></a> returns 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 – <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 – <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 – <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 – <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 – <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">§2.2</a>).) +(When loading main chunks, +this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">§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 – <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 – <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 – <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 – <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 and 5. -<h2>6.5 - <a name="6.5">Table Manipulation</a></h2><p> +<h2>6.5 – <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">§3.4.6</a>). -<h2>6.6 - <a name="6.6">Mathematical Functions</a></h2> +<h2>6.6 – <a name="6.6">Mathematical Functions</a></h2> <p> This library is an interface to the standard C 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 – <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 (···)</code></a></h3> +<hr><h3><a name="pdf-bit32.AND"><code>bit32.AND (···)</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 (···)</code></a></h3> +<hr><h3><a name="pdf-bit32.OR"><code>bit32.OR (···)</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 (···)</code></a></h3> +<hr><h3><a name="pdf-bit32.TEST"><code>bit32.TEST (···)</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 (···)</code></a></h3> +<hr><h3><a name="pdf-bit32.XOR"><code>bit32.XOR (···)</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 – <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 – <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 function <code>exit</code>, -with an optional <code>code</code>, -to terminate the host program. +Calls the C 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 – <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 – <a name="7">Lua Standalone</a></h1> <p> Although Lua has been designed as an extension language, to be embedded in a host C 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 <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 – <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 – <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 – <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 – <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">§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 – <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>’ explist] | - <b>in</b> exp <b>do</b> block <b>end</b> + <b>local</b> namelist [&lsquo<b>=</b>’ 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 — but you do <EM>not</EM> want to link the Lua library + those dynamic libraries — 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) @@ -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); } } @@ -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; } @@ -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); @@ -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) { @@ -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; @@ -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) @@ -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 @@ -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") |