summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLua Team <team@lua.org>2011-11-24 12:00:00 +0000
committerrepogen <>2011-11-24 12:00:00 +0000
commit2e5ae8240bb2daf5d66d69e199de10dde62f5d13 (patch)
treeb9f21bdd5006c59adc99000afa3cf22da8ea1c57
parentc17c598e967843fa77a465caf0e0df15d9019409 (diff)
downloadlua-github-2e5ae8240bb2daf5d66d69e199de10dde62f5d13.tar.gz
Lua 5.2.0-rc15.2.0-rc1
-rw-r--r--Makefile4
-rw-r--r--README2
-rw-r--r--doc/alert.pngbin1411 -> 0 bytes
-rw-r--r--doc/contents.html20
-rw-r--r--doc/lua.1116
-rw-r--r--doc/lua.css5
-rw-r--r--doc/luac.1118
-rw-r--r--doc/manual.css7
-rw-r--r--doc/manual.html1026
-rw-r--r--doc/readme.html110
-rw-r--r--src/Makefile1
-rw-r--r--src/lapi.c125
-rw-r--r--src/lauxlib.c41
-rw-r--r--src/lauxlib.h33
-rw-r--r--src/lbaselib.c80
-rw-r--r--src/lcode.c22
-rw-r--r--src/lcode.h3
-rw-r--r--src/lcorolib.c4
-rw-r--r--src/lctype.c5
-rw-r--r--src/lctype.h4
-rw-r--r--src/ldblib.c11
-rw-r--r--src/ldebug.c200
-rw-r--r--src/ldebug.h20
-rw-r--r--src/ldo.c34
-rw-r--r--src/ldo.h4
-rw-r--r--src/ldump.c6
-rw-r--r--src/lgc.c142
-rw-r--r--src/lgc.h6
-rw-r--r--src/liolib.c104
-rw-r--r--src/llex.c87
-rw-r--r--src/llimits.h20
-rw-r--r--src/lmem.c4
-rw-r--r--src/loadlib.c104
-rw-r--r--src/lobject.c10
-rw-r--r--src/lobject.h68
-rw-r--r--src/lopcodes.h4
-rw-r--r--src/lparser.c160
-rw-r--r--src/lparser.h13
-rw-r--r--src/lstate.c13
-rw-r--r--src/lstate.h6
-rw-r--r--src/lstrlib.c21
-rw-r--r--src/ltable.c61
-rw-r--r--src/ltable.h8
-rw-r--r--src/ltablib.c4
-rw-r--r--src/lua.c51
-rw-r--r--src/lua.h17
-rw-r--r--src/luac.c7
-rw-r--r--src/luaconf.h27
-rw-r--r--src/lvm.c49
-rw-r--r--src/lzio.c4
-rw-r--r--src/lzio.h8
51 files changed, 1862 insertions, 1137 deletions
diff --git a/Makefile b/Makefile
index da62ab94..ec53e1a2 100644
--- a/Makefile
+++ b/Makefile
@@ -62,13 +62,13 @@ install: dummy
cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
- #cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
+ cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
uninstall:
cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN)
cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC)
cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB)
- #cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN)
+ cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN)
local:
$(MAKE) install INSTALL_TOP=../install
diff --git a/README b/README
index f00e8e77..ee447665 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
-This is Lua 5.2 (beta), released on 05 Jul 2011.
+This is Lua 5.2, released on 24 Nov 2011.
For installation instructions, license details, and
further information about Lua, see doc/readme.html.
diff --git a/doc/alert.png b/doc/alert.png
deleted file mode 100644
index 49380746..00000000
--- a/doc/alert.png
+++ /dev/null
Binary files differ
diff --git a/doc/contents.html b/doc/contents.html
index 788bf6c8..9f7043d4 100644
--- a/doc/contents.html
+++ b/doc/contents.html
@@ -21,11 +21,6 @@ Lua 5.2 Reference Manual
</H1>
<P>
-<IMG SRC="alert.png" ALIGN="absbottom" ALT="[!]">
-<EM>This is a beta version of Lua 5.2.
-Some details may change in the final version.</EM>
-
-<P>
The reference manual is the official definition of the Lua language.
For a complete introduction to Lua programming, see the book
<A HREF="http://www.lua.org/docs.html#books">Programming in Lua</A>.
@@ -95,7 +90,7 @@ Freely available under the terms of the
<UL>
<LI><A HREF="manual.html#4.1">4.1 &ndash; The Stack</A>
<LI><A HREF="manual.html#4.2">4.2 &ndash; Stack Size</A>
-<LI><A HREF="manual.html#4.3">4.3 &ndash; Pseudo-Indices</A>
+<LI><A HREF="manual.html#4.3">4.3 &ndash; Valid and Acceptable Indices</A>
<LI><A HREF="manual.html#4.4">4.4 &ndash; C Closures</A>
<LI><A HREF="manual.html#4.5">4.5 &ndash; Registry</A>
<LI><A HREF="manual.html#4.6">4.6 &ndash; Error Handling in C</A>
@@ -154,8 +149,8 @@ Freely available under the terms of the
<A HREF="manual.html#pdf-error">error</A><BR>
<A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR>
<A HREF="manual.html#pdf-ipairs">ipairs</A><BR>
-<A HREF="manual.html#pdf-load">load</A><BR>
<A HREF="manual.html#pdf-loadfile">loadfile</A><BR>
+<A HREF="manual.html#pdf-load">load</A><BR>
<A HREF="manual.html#pdf-next">next</A><BR>
<A HREF="manual.html#pdf-pairs">pairs</A><BR>
<A HREF="manual.html#pdf-pcall">pcall</A><BR>
@@ -406,6 +401,8 @@ Freely available under the terms of the
<A HREF="manual.html#lua_rawlen">lua_rawlen</A><BR>
<A HREF="manual.html#lua_rawset">lua_rawset</A><BR>
<A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR>
+<A HREF="manual.html#lua_rawgetp">lua_rawgetp</A><BR>
+<A HREF="manual.html#lua_rawsetp">lua_rawsetp</A><BR>
<A HREF="manual.html#lua_register">lua_register</A><BR>
<A HREF="manual.html#lua_remove">lua_remove</A><BR>
<A HREF="manual.html#lua_replace">lua_replace</A><BR>
@@ -463,8 +460,8 @@ Freely available under the terms of the
<A HREF="manual.html#luaL_buffinitsize">luaL_buffinitsize</A><BR>
<A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR>
<A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR>
-<A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR>
<A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR>
+<A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR>
<A HREF="manual.html#luaL_checklong">luaL_checklong</A><BR>
<A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR>
<A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR>
@@ -487,14 +484,15 @@ Freely available under the terms of the
<A HREF="manual.html#luaL_len">luaL_len</A><BR>
<A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR>
<A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR>
+<A HREF="manual.html#luaL_loadfilex">luaL_loadfilex</A><BR>
<A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR>
<A HREF="manual.html#luaL_newlib">luaL_newlib</A><BR>
<A HREF="manual.html#luaL_newlibtable">luaL_newlibtable</A><BR>
<A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR>
<A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR>
<A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR>
-<A HREF="manual.html#luaL_optint">luaL_optint</A><BR>
<A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR>
+<A HREF="manual.html#luaL_optint">luaL_optint</A><BR>
<A HREF="manual.html#luaL_optlong">luaL_optlong</A><BR>
<A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR>
<A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR>
@@ -522,10 +520,10 @@ Freely available under the terms of the
<HR>
<SMALL CLASS="footer">
Last update:
-Tue Jun 28 14:53:13 BRT 2011
+Wed Nov 23 16:14:28 BRST 2011
</SMALL>
<!--
-Last change: revised for Lua 5.2.0 (beta)
+Last change: revised for Lua 5.2.0
-->
</BODY>
diff --git a/doc/lua.1 b/doc/lua.1
new file mode 100644
index 00000000..1dbf0436
--- /dev/null
+++ b/doc/lua.1
@@ -0,0 +1,116 @@
+.\" $Id: lua.man,v 1.13 2011/11/16 17:16:53 lhf Exp $
+.TH LUA 1 "$Date: 2011/11/16 17:16:53 $"
+.SH NAME
+lua \- Lua interpreter
+.SH SYNOPSIS
+.B lua
+[
+.I options
+]
+[
+.I script
+[
+.I args
+]
+]
+.SH DESCRIPTION
+.B lua
+is the standalone Lua interpreter.
+It loads and executes Lua programs,
+either in textual source form or
+in precompiled binary form.
+(Precompiled binaries are output by
+.BR luac ,
+the Lua compiler.)
+.B lua
+can be used as a batch interpreter and also interactively.
+.LP
+The given
+.I options
+are handled in order and then
+the Lua program in file
+.I script
+is loaded and executed.
+The given
+.I args
+are available to
+.I script
+as strings in a global table named
+.BR arg .
+If no options or arguments are given,
+then
+.B "\-v \-i"
+is assumed when the standard input is a terminal;
+otherwise,
+.B "\-"
+is assumed.
+.LP
+In interactive mode,
+.B lua
+prompts the user,
+reads lines from the standard input,
+and executes them as they are read.
+If a line does not contain a complete statement,
+then a secondary prompt is displayed and
+lines are read until a complete statement is formed or
+a syntax error is found.
+If a line starts with
+.BR '=' ,
+then
+.B lua
+evaluates and displays
+the values of the expressions in the remainder of the line.
+.LP
+At the very start,
+before even handling the command line,
+.B lua
+checks the contents of the environment variables
+.B LUA_INIT_5_2
+or
+.BR LUA_INIT ,
+in that order.
+If the contents is of the form
+.RI '@ filename ',
+then
+.I filename
+is executed.
+Otherwise, the string is assumed to be a Lua statement and is executed.
+.SH OPTIONS
+.TP
+.BI \-e " stat"
+execute statement
+.IR stat .
+.TP
+.B \-i
+enter interactive mode after executing
+.IR script .
+.TP
+.BI \-l " name"
+execute the equivalent of
+.IB name =require(' name ')
+before executing
+.IR script .
+.TP
+.B \-v
+show version information.
+.TP
+.B \-E
+ignore environment variables.
+.TP
+.B \-\-
+stop handling options.
+.TP
+.B \-
+stop handling options and execute the standard input as a file.
+.SH "SEE ALSO"
+.BR luac (1)
+.br
+The documentation at lua.org,
+especially section 7 of the reference manual.
+.SH DIAGNOSTICS
+Error messages should be self explanatory.
+.SH AUTHORS
+R. Ierusalimschy,
+L. H. de Figueiredo,
+W. Celes
+.\" EOF
diff --git a/doc/lua.css b/doc/lua.css
index fb462d9b..54708f82 100644
--- a/doc/lua.css
+++ b/doc/lua.css
@@ -1,7 +1,6 @@
body {
color: #000000 ;
background-color: #FFFFFF ;
- font-family: sans-serif ;
font-family: Helvetica, Arial, sans-serif ;
text-align: justify ;
margin-right: 20px ;
@@ -18,12 +17,13 @@ h2 {
padding-top: 0.4em ;
padding-bottom: 0.4em ;
padding-left: 20px ;
+ padding-right: 20px ;
margin-left: -20px ;
background-color: #E0E0FF ;
}
h3 {
- padding-left: 8px ;
+ padding-left: 0.5em ;
border-left: solid #E0E0FF 1em ;
}
@@ -76,7 +76,6 @@ input[type=text] {
-moz-border-radius: 2em ;
background-image: url('images/search.png') ;
background-repeat: no-repeat;
- background-position: left center ;
background-position: 4px center ;
padding-left: 20px ;
height: 2em ;
diff --git a/doc/luac.1 b/doc/luac.1
new file mode 100644
index 00000000..33a4ed00
--- /dev/null
+++ b/doc/luac.1
@@ -0,0 +1,118 @@
+.\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $
+.TH LUAC 1 "$Date: 2011/11/16 13:53:40 $"
+.SH NAME
+luac \- Lua compiler
+.SH SYNOPSIS
+.B luac
+[
+.I options
+] [
+.I filenames
+]
+.SH DESCRIPTION
+.B luac
+is the Lua compiler.
+It translates programs written in the Lua programming language
+into binary files containing precompiled chunks
+that can be later loaded and executed.
+.LP
+The main advantages of precompiling chunks are:
+faster loading,
+protecting source code from accidental user changes,
+and
+off-line syntax checking.
+Precompiling does not imply faster execution
+because in Lua chunks are always compiled into bytecodes before being executed.
+.B luac
+simply allows those bytecodes to be saved in a file for later execution.
+Precompiled chunks are not necessarily smaller than the corresponding source.
+The main goal in precompiling is faster loading.
+.LP
+In the command line,
+you can mix
+text files containing Lua source and
+binary files containing precompiled chunks.
+.B luac
+produces a single output file containing the combined bytecodes
+for all files given.
+Executing the combined file is equivalent to executing the given files.
+By default,
+the output file is named
+.BR luac.out ,
+but you can change this with the
+.B \-o
+option.
+.LP
+Precompiled chunks are
+.I not
+portable across different architectures.
+Moreover,
+the internal format of precompiled chunks
+is likely to change when a new version of Lua is released.
+Make sure you save the source files of all Lua programs that you precompile.
+.LP
+.SH OPTIONS
+.TP
+.B \-l
+produce a listing of the compiled bytecode for Lua's virtual machine.
+Listing bytecodes is useful to learn about Lua's virtual machine.
+If no files are given, then
+.B luac
+loads
+.B luac.out
+and lists its contents.
+Use
+.B \-l \-l
+for a full listing.
+.TP
+.BI \-o " file"
+output to
+.IR file ,
+instead of the default
+.BR luac.out .
+(You can use
+.B "'\-'"
+for standard output,
+but not on platforms that open standard output in text mode.)
+The output file may be one of the given files because
+all files are loaded before the output file is written.
+Be careful not to overwrite precious files.
+.TP
+.B \-p
+load files but do not generate any output file.
+Used mainly for syntax checking and for testing precompiled chunks:
+corrupted files will probably generate errors when loaded.
+If no files are given, then
+.B luac
+loads
+.B luac.out
+and tests its contents.
+No messages are displayed if the file loads without errors.
+.TP
+.B \-s
+strip debug information before writing the output file.
+This saves some space in very large chunks,
+but if errors occur when running a stripped chunk,
+then the error messages may not contain the full information they usually do.
+In particular,
+line numbers and names of local variables are lost.
+.TP
+.B \-v
+show version information.
+.TP
+.B \-\-
+stop handling options.
+.TP
+.B \-
+stop handling options and process standard input.
+.SH "SEE ALSO"
+.BR lua (1)
+.br
+The documentation at lua.org.
+.SH DIAGNOSTICS
+Error messages should be self explanatory.
+.SH AUTHORS
+R. Ierusalimschy,
+L. H. de Figueiredo,
+W. Celes
+.\" EOF
diff --git a/doc/manual.css b/doc/manual.css
index 6d5a3f09..b158aea3 100644
--- a/doc/manual.css
+++ b/doc/manual.css
@@ -2,13 +2,16 @@ h3 code {
font-family: inherit ;
}
-pre {
- font-size: 105% ;
+pre, code {
+ font-size: 12pt ;
}
span.apii {
float: right ;
font-family: inherit ;
+ font-style: normal ;
+ font-size: small ;
+ color: gray ;
}
p+h1, ul+h1 {
diff --git a/doc/manual.html b/doc/manual.html
index 72155652..9e16e6b0 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -16,11 +16,6 @@
Lua 5.2 Reference Manual
</h1>
-<IMG SRC="alert.png" ALIGN="absbottom" ALT="[!]">
-<EM>This is a beta version of Lua 5.2.
-Some details may change in the final version.</EM>
-<P>
-
by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
<p>
<small>
@@ -38,7 +33,7 @@ Freely available under the terms of the
<!-- ====================================================================== -->
<p>
-<!-- $Id: manual.of,v 1.86 2011/07/08 20:00:45 roberto Exp $ -->
+<!-- $Id: manual.of,v 1.88 2011/11/24 13:23:53 roberto Exp $ -->
@@ -51,8 +46,8 @@ general procedural programming with data description
facilities.
It also offers good support for object-oriented programming,
functional programming, and data-driven programming.
-Lua is intended to be used as a powerful, light-weight
-scripting language for any program that needs one.
+Lua is intended to be used as a powerful, lightweight,
+embeddable scripting language for any program that needs one.
Lua is implemented as a library, written in <em>clean C</em>,
the common subset of Standard&nbsp;C and C++.
@@ -86,14 +81,14 @@ this document is dry in places.
For a discussion of the decisions behind the design of Lua,
see the technical papers available at Lua's web site.
For a detailed introduction to programming in Lua,
-see Roberto's book, <em>Programming in Lua</em> (second edition).
+see Roberto's book, <em>Programming in Lua</em>.
<h1>2 &ndash; <a name="2">Basic Concepts</a></h1>
<p>
-This section describes some basic concepts of the language.
+This section describes the basic concepts of the language.
@@ -148,11 +143,14 @@ functions written in C
<p>
The type <em>userdata</em> is provided to allow arbitrary C&nbsp;data to
be stored in Lua variables.
-This type corresponds to a block of raw memory
-and has no pre-defined operations in Lua,
+A userdata value is a pointer to a block of raw memory.
+There are two kinds of userdata:
+full userdata, where the block of memory is managed by Lua,
+and light userdata, where the block of memory is managed by the host.
+Userdata has no predefined operations in Lua,
except assignment and identity test.
-However, by using <em>metatables</em>,
-the programmer can define operations for userdata values
+By using <em>metatables</em>,
+the programmer can define operations for full userdata values
(see <a href="#2.4">&sect;2.4</a>).
Userdata values cannot be created or modified in Lua,
only through the C&nbsp;API.
@@ -200,7 +198,7 @@ which is called the length of the sequence (see <a href="#3.4.6">&sect;3.4.6</a>
<p>
Like indices,
-the value of a table field can be of any type.
+the values of table fields can be of any type.
In particular,
because functions are first-class values,
table fields can contain functions.
@@ -227,7 +225,7 @@ these operations do not imply any kind of copy.
<p>
The library function <a href="#pdf-type"><code>type</code></a> returns a string describing the type
-of a given value.
+of a given value (see <a href="#6.1">&sect;6.1</a>).
@@ -239,8 +237,8 @@ of a given value.
As will be discussed in <a href="#3.2">&sect;3.2</a> and <a href="#3.3.3">&sect;3.3.3</a>,
any reference to a global name <code>var</code> is syntactically translated
to <code>_ENV.var</code>.
-Moreover, every chunk is compiled in the scope of an external
-variable called <code>_ENV</code> (see <a href="#3.3.2">&sect;3.3.2</a>),
+Moreover, every chunk is compiled in the scope of
+an external local variable called <code>_ENV</code> (see <a href="#3.3.2">&sect;3.3.2</a>),
so <code>_ENV</code> itself is never a global name in a chunk.
@@ -252,12 +250,11 @@ 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.
+following the usual visibility rules of Lua (see <a href="#3.5">&sect;3.5</a>).
<p>
-Any table used as the value of <code>_ENV</code> is usually called
-an <em>environment</em>.
+Any table used as the value of <code>_ENV</code> is called an <em>environment</em>.
<p>
@@ -268,13 +265,14 @@ In Lua, the variable <a href="#pdf-_G"><code>_G</code></a> is initialized with t
<p>
When Lua compiles a chunk,
-it initializes the value of its <code>_ENV</code> variable
+it initializes the value of its <code>_ENV</code> upvalue
with the global environment (see <a href="#pdf-load"><code>load</code></a>).
Therefore, by default,
global variables in Lua code refer to entries in the global environment.
-Moreover, all standard libraries are loaded in the global environment,
+Moreover, all standard libraries are loaded in the global environment
and several functions there operate on that environment.
-You can use <a href="#pdf-load"><code>load</code></a> to load a chunk with a different environment.
+You can use <a href="#pdf-load"><code>load</code></a> (or <a href="#pdf-loadfile"><code>loadfile</code></a>)
+to load a chunk with a different environment.
(In C, you have to load the chunk and then change the value
of its first upvalue.)
@@ -325,7 +323,7 @@ any value for the error object.
<p>
When you use <a href="#pdf-xpcall"><code>xpcall</code></a> or <a href="#lua_pcall"><code>lua_pcall</code></a>,
-you may give an <em>message handler</em>
+you may give a <em>message handler</em>
to be called in case of errors.
This function is called with the original error message
and returns a new error message.
@@ -389,8 +387,8 @@ but the string library sets a metatable for the string type (see <a href="#6.4">
<p>
A metatable controls how an object behaves in arithmetic operations,
order comparisons, concatenation, length operation, and indexing.
-A metatable also can define a function to be called when a userdata
-is garbage collected.
+A metatable also can define a function to be called
+when a userdata or a table is garbage collected.
When Lua performs one of these operations over a value,
it checks whether this value has a metatable with the corresponding event.
If so, the value associated with that key (the metamethod)
@@ -427,8 +425,8 @@ This should be read as
rawget(getmetatable(obj) or {}, event)
</pre><p>
-That is, the access to a metamethod does not invoke other metamethods,
-and the access to objects with no metatables does not fail
+This means that the access to a metamethod does not invoke other metamethods,
+and access to objects with no metatables does not fail
(it simply results in <b>nil</b>).
@@ -590,13 +588,17 @@ The function <code>getequalhandler</code> defines how Lua chooses a metamethod
for equality.
A metamethod is selected only when both values
being compared have the same type
-and the same metamethod for the selected operation.
+and the same metamethod for the selected operation,
+and the values are either tables or full userdata.
<pre>
- function getequalhandler (op1, op2, event)
- if type(op1) ~= type(op2) then return nil end
- local mm1 = metatable(op1)[event]
- local mm2 = metatable(op2)[event]
+ function getequalhandler (op1, op2)
+ if type(op1) ~= type(op2) or
+ (type(op1) ~= "table" and type(op1) ~= "userdata") then
+ return nil -- different values
+ end
+ local mm1 = metatable(op1).__eq
+ local mm2 = metatable(op2).__eq
if mm1 == mm2 then return mm1 else return nil end
end
</pre><p>
@@ -604,21 +606,19 @@ The "eq" event is defined as follows:
<pre>
function eq_event (op1, op2)
- if type(op1) ~= type(op2) then -- different types?
- return false -- different values
- end
if op1 == op2 then -- primitive equal?
return true -- values are equal
end
-- try metamethod
- local h = getequalhandler(op1, op2, "__eq")
+ local h = getequalhandler(op1, op2)
if h then
- return (h(op1, op2))
+ return not not h(op1, op2)
else
return false
end
end
</pre><p>
+Note that the result is always a boolean.
</li>
<li><b>"lt": </b>
@@ -634,13 +634,14 @@ the <code>&lt;</code> operation.
else
local h = getbinhandler(op1, op2, "__lt")
if h then
- return (h(op1, op2))
+ return not not h(op1, op2)
else
error(&middot;&middot;&middot;)
end
end
end
</pre><p>
+Note that the result is always a boolean.
</li>
<li><b>"le": </b>
@@ -656,7 +657,7 @@ the <code>&lt;=</code> operation.
else
local h = getbinhandler(op1, op2, "__le")
if h then
- return (h(op1, op2))
+ return not not h(op1, op2)
else
h = getbinhandler(op1, op2, "__lt")
if h then
@@ -671,6 +672,11 @@ the <code>&lt;=</code> operation.
Note that, in the absence of a "le" metamethod,
Lua tries the "lt", assuming that <code>a &lt;= b</code> is
equivalent to <code>not (b &lt; a)</code>.
+
+
+<p>
+As with the other comparison operators,
+the result is always a boolean.
</li>
<li><b>"index": </b>
@@ -770,7 +776,7 @@ Lua manages memory automatically by running
a <em>garbage collector</em> to collect all <em>dead objects</em>
(that is, objects that are no longer accessible from Lua).
All memory used by Lua is subject to automatic management:
-tables, userdata, functions, threads, strings, etc.
+strings, tables, userdata, functions, threads, internal structures, etc.
<p>
@@ -819,10 +825,25 @@ memory usage.
<p>
You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C
or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua.
-With these functions you can also control
+You can also use these functions to control
the collector directly (e.g., stop and restart it).
+<p>
+As an experimental feature in Lua 5.2,
+you can change the collector's operation mode
+from incremental to <em>generational</em>.
+A <em>generational collector</em> assumes that most objects die young,
+and therefore it traverses only young (recently created) objects.
+This behavior can reduce the time used by the collector,
+but also increases memory usage (as old dead objects may accumulate).
+To mitigate this second problem,
+from time to time the generational collector performs a full collection.
+Remember that this is an experimental feature;
+you are welcome to try it,
+but check your gains.
+
+
<h3>2.5.1 &ndash; <a name="2.5.1">Garbage-Collection Metamethods</a></h3>
@@ -879,11 +900,17 @@ the execution of the regular code.
<p>
-Because the object being collected must still be used by the finalizer
-and even <em>resurrected</em>
-(e.g., stored by the finalizer in a global variable),
-the object memory is freed only when it becomes completely inaccessible
-(that is, in the next garbage-collection cycle unless it was resurrected).
+Because the object being collected must still be used by the finalizer,
+it (and other objects accessible only through it)
+must be <em>resurrected</em> by Lua.
+Usually, this resurrection is transient,
+and the object memory is freed in the next garbage-collection cycle.
+However, if the finalizer stores the object in some global place
+(e.g., a global variable),
+then there is a permanent resurrection.
+In any case,
+the object memory is freed only when it becomes completely inaccessible;
+its finalizer will never be called twice.
@@ -927,32 +954,42 @@ the pair is removed.
<p>
-After you use a table as a metatable,
-you should not change the value of its <code>__mode</code> field.
-Otherwise, the weak behavior of the tables controlled by this
-metatable is undefined.
+Any change in the weakness of a table may take effect only
+at the next collect cycle.
+In particular, if you change the weakness to a stronger mode,
+Lua may still collect some items from that table
+before the change takes effect.
<p>
Only objects that have an explicit construction
-can be removed from weak tables.
-Values, such as numbers and booleans,
+are removed from weak tables.
+Values, such as numbers and light C functions,
are not subject to garbage collection,
and therefore are not removed from weak tables
(unless its associated value is collected).
-Lua treats strings and light C functions as non-object values.
+Although strings are subject to garbage collection,
+they do not have an explicit construction,
+and therefore are not removed from weak tables.
<p>
-Objects marked for finalization have a special behavior in weak tables.
-When a marked object is a value in a weak table,
-it is removed from the table before running its finalizer.
-However, when it is a key,
-it is removed from the table only after running its finalizer.
+Resurrected objects
+(that is, objects being finalized
+and objects accessible only through objects being finalized)
+have a special behavior in weak tables.
+They are removed from weak values before running their finalizers,
+but are removed from weak keys only in the next collection
+after running their finalizers, when such objects are actually freed.
This behavior allows the finalizer to access properties
associated with the object through weak tables.
+<p>
+If a weak table is among the resurrected objects in a collection cycle,
+it may not be properly cleared until the next cycle.
+
+
@@ -1060,7 +1097,6 @@ When you run it, it produces the following output:
<pre>
co-body 1 10
foo 2
-
main true 4
co-body r
main true 11 -9
@@ -1090,7 +1126,7 @@ and what their combinations mean.
<p>
-The language constructs will be explained using the usual extended BNF notation,
+Language constructs will be explained using the usual extended BNF notation,
in which
{<em>a</em>}&nbsp;means&nbsp;0 or more <em>a</em>'s, and
[<em>a</em>]&nbsp;means an optional <em>a</em>.
@@ -1176,7 +1212,7 @@ into the string contents.
<p>
-A character in a literal string can also be specified by its numerical value.
+A byte in a literal string can also be specified by its numerical value.
This can be done with the escape sequence <code>\x<em>XX</em></code>,
where <em>XX</em> is a sequence of exactly two hexadecimal digits,
or with the escape sequence <code>\<em>ddd</em></code>,
@@ -1407,13 +1443,13 @@ even if it does not use that variable.
<p>
A chunk can be stored in a file or in a string inside the host program.
To execute a chunk,
-Lua first pre-compiles the chunk into instructions for a virtual machine,
+Lua first precompiles the chunk into instructions for a virtual machine,
and then it executes the compiled code
with an interpreter for the virtual machine.
<p>
-Chunks can also be pre-compiled into binary form;
+Chunks can also be precompiled into binary form;
see program <code>luac</code> for details.
Programs in source and compiled forms are interchangeable;
Lua automatically detects the file type and acts accordingly.
@@ -1555,7 +1591,7 @@ enter into the scope of a local variable.
<p>
-Both labels and empty statements are called <em>void statements</em>,
+Labels and empty statements are called <em>void statements</em>,
as they perform no actions.
@@ -1806,14 +1842,13 @@ and the unary <em>length operator</em> (see <a href="#3.4.6">&sect;3.4.6</a>).
<p>
Both function calls and vararg expressions can result in multiple values.
-If an expression is used as a statement
-(only possible for function calls (see <a href="#3.3.6">&sect;3.3.6</a>)),
+If a function call is used as a statement (see <a href="#3.3.6">&sect;3.3.6</a>),
then its return list is adjusted to zero elements,
thus discarding all returned values.
If an expression is used as the last (or the only) element
of a list of expressions,
then no adjustment is made
-(unless the call is enclosed in parentheses).
+(unless the expression is enclosed in parentheses).
In all other contexts,
Lua adjusts the result list to one element,
discarding all values except the first one.
@@ -1881,8 +1916,7 @@ Lua provides automatic conversion between
string and number values at run time.
Any arithmetic operation applied to a string tries to convert
this string to a number, following the rules of the Lua lexer.
-(The string may have leading and trailing spaces,
-plus an optional sign.)
+(The string may have leading and trailing spaces and a sign.)
Conversely, whenever a number is used where a string is expected,
the number is converted to a string, in a reasonable format.
For complete control over how numbers are converted to strings,
@@ -2254,8 +2288,8 @@ contains references to <code>f</code>.)
<p>
A function definition is an executable expression,
whose value has type <em>function</em>.
-When Lua pre-compiles a chunk,
-all its function bodies are pre-compiled too.
+When Lua precompiles a chunk,
+all its function bodies are precompiled too.
Then, whenever Lua executes the function definition,
the function is <em>instantiated</em> (or <em>closed</em>).
This function instance (or <em>closure</em>)
@@ -2272,9 +2306,9 @@ initialized with the argument values:
When a function is called,
the list of arguments is adjusted to
the length of the list of parameters,
-unless the function is a variadic or <em>vararg function</em>,
-which is
-indicated by three dots ('<code>...</code>') at the end of its parameter list.
+unless the function is a <em>vararg function</em>,
+which is indicated by three dots ('<code>...</code>')
+at the end of its parameter list.
A vararg function does not adjust its argument list;
instead, it collects all extra arguments and supplies them
to the function through a <em>vararg expression</em>,
@@ -2425,7 +2459,8 @@ are declared in the header file <a name="pdf-lua.h"><code>lua.h</code></a>.
<p>
Even when we use the term "function",
any facility in the API may be provided as a macro instead.
-All such macros use each of their arguments exactly once
+Except where stated otherwise,
+all such macros use each of their arguments exactly once
(except for the first argument, which is always a Lua state),
and so do not generate any hidden side-effects.
@@ -2434,8 +2469,7 @@ and so do not generate any hidden side-effects.
As in most C&nbsp;libraries,
the Lua API functions do not check their arguments for validity or consistency.
However, you can change this behavior by compiling Lua
-with a proper definition for the macro <a name="pdf-luai_apicheck"><code>luai_apicheck</code></a>,
-in file <code>luaconf.h</code>.
+with the macro <a name="pdf-LUA_USE_APICHECK"><code>LUA_USE_APICHECK</code></a> defined.
@@ -2472,10 +2506,6 @@ index&nbsp;<em>n</em> represents the last element;
index&nbsp;-1 also represents the last element
(that is, the element at the&nbsp;top)
and index <em>-n</em> represents the first element.
-We say that an index is <em>valid</em>
-if it lies between&nbsp;1 and the stack top
-(that is, if <code>1 &le; abs(index) &le; top</code>).
-
@@ -2494,7 +2524,7 @@ to ensure that the stack has extra slots when pushing new elements.
<p>
Whenever Lua calls C,
-it ensures that at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> stack positions are available.
+it ensures that the stack has at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra slots.
<code>LUA_MINSTACK</code> is defined as 20,
so that usually you do not have to worry about stack space
unless your code has loops pushing elements onto the stack.
@@ -2509,33 +2539,66 @@ So, before pushing anything in the stack after such a call
you should use <a href="#lua_checkstack"><code>lua_checkstack</code></a>.
+
+
+
+<h2>4.3 &ndash; <a name="4.3">Valid and Acceptable Indices</a></h2>
+
<p>
-Most query functions accept as indices any value inside the
-available stack space, that is, indices up to the maximum stack size
-that you have set through <a href="#lua_checkstack"><code>lua_checkstack</code></a>.
-Such indices are called <em>acceptable indices</em>.
-More formally, we define an <em>acceptable index</em>
+Any function in the API that receives stack indices
+works only with <em>valid indices</em> or <em>acceptable indices</em>.
+
+
+<p>
+A <em>valid index</em> is an index that refers to a
+valid position within the stack, that is,
+it lies between&nbsp;1 and the stack top
+(<code>1 &le; abs(index) &le; top</code>).
+
+Usually, functions that need a specific stack position
+(e.g., <a href="#lua_remove"><code>lua_remove</code></a>) require valid indices.
+
+
+<p>
+Functions that do not need a specific stack position,
+but only a value in the stack (e.g., query functions),
+can be called with acceptable indices.
+An <em>acceptable index</em> refers to a position within
+the space allocated for the stack,
+that is, indices up to the stack size.
+More formally, we define an acceptable index
as follows:
<pre>
(index &lt; 0 &amp;&amp; abs(index) &lt;= top) ||
- (index &gt; 0 &amp;&amp; index &lt;= stackspace)
+ (index &gt; 0 &amp;&amp; index &lt;= stack size)
</pre><p>
-Note that 0 is never an acceptable index.
+(Note that 0 is never an acceptable index.)
+When a function is called,
+its stack size is <code>top + LUA_MINSTACK</code>.
+You can change its stack size through function <a href="#lua_checkstack"><code>lua_checkstack</code></a>.
+<p>
+Acceptable indices serve to avoid extra tests
+against the stack top when querying the stack.
+For instance, a C&nbsp;function can query its third argument
+without the need to first check whether there is a third argument,
+that is, without the need to check whether 3 is a valid index.
+<p>
+For functions that can be called with acceptable indices,
+any non-valid index is treated as if it
+contains a value of a virtual type <a name="pdf-LUA_TNONE"><code>LUA_TNONE</code></a>.
-<h2>4.3 &ndash; <a name="4.3">Pseudo-Indices</a></h2>
<p>
Unless otherwise noted,
any function that accepts valid indices also accepts <em>pseudo-indices</em>,
which represent some Lua values that are accessible to C&nbsp;code
but which are not in the stack.
-Pseudo-indices are used to access
-the registry
+Pseudo-indices are used to access the registry
and the upvalues of a C&nbsp;function (see <a href="#4.4">&sect;4.4</a>).
@@ -2547,10 +2610,10 @@ and the upvalues of a C&nbsp;function (see <a href="#4.4">&sect;4.4</a>).
<p>
When a C&nbsp;function is created,
it is possible to associate some values with it,
-thus creating a <em>C&nbsp;closure</em>;
+thus creating a <em>C&nbsp;closure</em>
+(see <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>);
these values are called <em>upvalues</em> and are
-accessible to the function whenever it is called
-(see <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>).
+accessible to the function whenever it is called.
<p>
@@ -2573,12 +2636,13 @@ produces an acceptable (but invalid) index.
<p>
Lua provides a <em>registry</em>,
-a pre-defined table that can be used by any C&nbsp;code to
-store whatever Lua value it needs to store.
-This table is always located at pseudo-index
+a predefined table that can be used by any C&nbsp;code to
+store whatever Lua values it needs to store.
+The registry table is always located at pseudo-index
<a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>.
Any C&nbsp;library can store data into this table,
-but it should take care to choose keys different from those used
+but it should take care to choose keys
+that are different from those used
by other libraries, to avoid collisions.
Typically, you should use as key a string containing your library name,
or a light userdata with the address of a C&nbsp;object in your code,
@@ -2610,7 +2674,6 @@ the main thread of the state.
<li><b><a name="pdf-LUA_RIDX_GLOBALS"><code>LUA_RIDX_GLOBALS</code></a>: </b> At this index the registry has
the global environment.
-This is the C&nbsp;equivalent to the <a href="#pdf-_G"><code>_G</code></a> global variable.
</li>
</ul>
@@ -2629,8 +2692,8 @@ and runtime errors)
it <em>raises</em> an error;
that is, it does a long jump.
A <em>protected environment</em> uses <code>setjmp</code>
-to set a recover point;
-any error jumps to the most recent active recover point.
+to set a recovery point;
+any error jumps to the most recent active recovery point.
<p>
@@ -2639,7 +2702,8 @@ Lua calls a <em>panic function</em> (see <a href="#lua_atpanic"><code>lua_atpani
and then calls <code>abort</code>,
thus exiting the host application.
Your panic function can avoid this exit by
-never returning (e.g., doing a long jump).
+never returning
+(e.g., doing a long jump to your own recovery point outside Lua).
<p>
@@ -2677,8 +2741,7 @@ All those functions receive a <em>continuation function</em>
<p>
-To explain continuations,
-let us set some terminology.
+We need to set some terminology to explain continuations.
We have a C function called from Lua which we will call
the <em>original function</em>.
This original function then calls one of those three functions in the C API,
@@ -2704,7 +2767,7 @@ of the original function.
<p>
-Lua treats the continuation function as if it was the original function.
+Lua treats the continuation function as if it were the original function.
The continuation function receives the same Lua stack
from the original function,
in the same state it would be if the callee function had returned.
@@ -2712,7 +2775,7 @@ in the same state it would be if the callee function had returned.
after a <a href="#lua_callk"><code>lua_callk</code></a> the function and its arguments are
removed from the stack and replaced by the results from the call.)
It also has the same upvalues.
-Whatever it returns is handled by Lua as if it was the return
+Whatever it returns is handled by Lua as if it were the return
of the original function.
@@ -2749,15 +2812,14 @@ by looking only at its arguments
The third field, <code>x</code>,
tells whether the function may throw errors:
'<code>-</code>' means the function never throws any error;
-'<code>m</code>' means the function may throw an error
-only due to not enough memory;
+'<code>m</code>' means the function may throw only memory allocation errors;
'<code>e</code>' means the function may throw other kinds of errors;
'<code>v</code>' means the function may throw an error on purpose.
<hr><h3><a name="lua_absindex"><code>lua_absindex</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_absindex (lua_State *L, int idx);</pre>
<p>
@@ -2795,7 +2857,7 @@ that is, the size given when it was allocated or reallocated.
<p>
When <code>ptr</code> is <code>NULL</code>,
-<code>osize</code> codes the kind of object that Lua is allocating.
+<code>osize</code> encodes the kind of object that Lua is allocating.
<code>osize</code> is any of
<a href="#pdf-LUA_TSTRING"><code>LUA_TSTRING</code></a>, <a href="#pdf-LUA_TTABLE"><code>LUA_TTABLE</code></a>, <a href="#pdf-LUA_TFUNCTION"><code>LUA_TFUNCTION</code></a>,
<a href="#pdf-LUA_TUSERDATA"><code>LUA_TUSERDATA</code></a>, or <a href="#pdf-LUA_TTHREAD"><code>LUA_TTHREAD</code></a> when (and only when)
@@ -2818,7 +2880,7 @@ and return <code>NULL</code>.
When <code>nsize</code> is not zero,
the allocator should behave like <code>realloc</code>.
The allocator returns <code>NULL</code>
-if and only if it cannot fill the request.
+if and only if it cannot fulfill the request.
Lua assumes that the allocator never fails when
<code>osize &gt;= nsize</code>.
@@ -2843,8 +2905,8 @@ Note that Standard&nbsp;C ensures
that <code>free(NULL)</code> has no effect and that
<code>realloc(NULL, size)</code> is equivalent to <code>malloc(size)</code>.
This code assumes that <code>realloc</code> does not fail when shrinking a block.
-Standard&nbsp;C does not ensure this behavior,
-but it seems a safe assumption.
+(Although Standard&nbsp;C does not ensure this behavior,
+it seems to be a safe assumption.)
@@ -2883,7 +2945,7 @@ The value of <code>op</code> must be one of the following constants:
<hr><h3><a name="lua_atpanic"><code>lua_atpanic</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre>
<p>
@@ -2901,7 +2963,7 @@ In particular, the error message is at the top of the stack.
<hr><h3><a name="lua_call"><code>lua_call</code></a></h3><p>
-<span class="apii">[-(nargs + 1), +nresults, <em>e</em>]</span>
+<span class="apii">[-(nargs+1), +nresults, <em>e</em>]</span>
<pre>void lua_call (lua_State *L, int nargs, int nresults);</pre>
<p>
@@ -3025,12 +3087,12 @@ of numerical arguments and returns their average and sum:
<hr><h3><a name="lua_checkstack"><code>lua_checkstack</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_checkstack (lua_State *L, int extra);</pre>
<p>
Ensures that there are at least <code>extra</code> free stack slots in the stack.
-It returns false if it cannot grant the request,
+It returns false if it cannot fulfill the request,
because it would cause the stack to be larger than a fixed maximum size
(typically at least a few thousand elements) or
because it cannot allocate memory for the new stack size.
@@ -3043,7 +3105,7 @@ it is left unchanged.
<hr><h3><a name="lua_close"><code>lua_close</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>void lua_close (lua_State *L);</pre>
<p>
@@ -3052,10 +3114,9 @@ Destroys all objects in the given Lua state
and frees all dynamic memory used by this state.
On several platforms, you may not need to call this function,
because all resources are naturally released when the host program ends.
-On the other hand, long-running programs,
-such as a daemon or a web server,
-might need to release states as soon as they are not needed,
-to avoid growing too large.
+On the other hand, long-running programs that create multiple states,
+such as daemons or web servers,
+might need to close states as soon as they are not needed.
@@ -3066,6 +3127,7 @@ to avoid growing too large.
<pre>int lua_compare (lua_State *L, int index1, int index2, int op);</pre>
<p>
+Compares two Lua values.
Returns 1 if the value at acceptable index <code>index1</code> satisfies <code>op</code>
when compared with the value at acceptable index <code>index2</code>,
following the semantics of the corresponding Lua operator
@@ -3106,7 +3168,7 @@ Concatenation is performed following the usual semantics of Lua
<hr><h3><a name="lua_copy"><code>lua_copy</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>void lua_copy (lua_State *L, int fromidx, int toidx);</pre>
<p>
@@ -3176,7 +3238,7 @@ Generates a Lua error.
The error message (which can actually be a Lua value of any type)
must be on the stack top.
This function does a long jump,
-and therefore never returns.
+and therefore never returns
(see <a href="#luaL_error"><code>luaL_error</code></a>).
@@ -3245,10 +3307,20 @@ returns a boolean that tells whether the collector is running
(i.e., not stopped).
</li>
+<li><b><code>LUA_GCGEN</code>: </b>
+changes the collector to generational mode
+(see <a href="#2.5">&sect;2.5</a>).
+</li>
+
+<li><b><code>LUA_GCINC</code>: </b>
+changes the collector to incremental mode.
+This is the default mode.
+</li>
+
</ul>
<p>
-For more details about some options,
+For more details about these options,
see <a href="#pdf-collectgarbage"><code>collectgarbage</code></a>.
@@ -3256,7 +3328,7 @@ see <a href="#pdf-collectgarbage"><code>collectgarbage</code></a>.
<hr><h3><a name="lua_getallocf"><code>lua_getallocf</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_Alloc lua_getallocf (lua_State *L, void **ud);</pre>
<p>
@@ -3269,7 +3341,7 @@ opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>.
<hr><h3><a name="lua_getctx"><code>lua_getctx</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_getctx (lua_State *L, int *ctx);</pre>
<p>
@@ -3293,7 +3365,7 @@ When the callee is <a href="#lua_pcallk"><code>lua_pcallk</code></a>,
Lua may also call its continuation function
to handle errors during the call.
That is, upon an error in the function called by <a href="#lua_pcallk"><code>lua_pcallk</code></a>,
-Lua may not return <a href="#lua_pcallk"><code>lua_pcallk</code></a>
+Lua may not return to the original function
but instead may call the continuation function.
In that case, a call to <a href="#lua_getctx"><code>lua_getctx</code></a> will return the error code
(the value that would be returned by <a href="#lua_pcallk"><code>lua_pcallk</code></a>);
@@ -3324,21 +3396,19 @@ for the "index" event (see <a href="#2.4">&sect;2.4</a>).
<p>
Pushes onto the stack the value of the global <code>name</code>.
-It is defined as a macro.
<hr><h3><a name="lua_getmetatable"><code>lua_getmetatable</code></a></h3><p>
-<span class="apii">[-0, +(0|1), <em>-</em>]</span>
+<span class="apii">[-0, +(0|1), &ndash;]</span>
<pre>int lua_getmetatable (lua_State *L, int index);</pre>
<p>
Pushes onto the stack the metatable of the value at the given
acceptable index.
-If the index is not valid,
-or if the value does not have a metatable,
+If the value does not have a metatable,
the function returns&nbsp;0 and pushes nothing on the stack.
@@ -3366,7 +3436,7 @@ for the "index" event (see <a href="#2.4">&sect;2.4</a>).
<hr><h3><a name="lua_gettop"><code>lua_gettop</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_gettop (lua_State *L);</pre>
<p>
@@ -3380,7 +3450,7 @@ this result is equal to the number of elements in the stack
<hr><h3><a name="lua_getuservalue"><code>lua_getuservalue</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_getuservalue (lua_State *L, int index);</pre>
<p>
@@ -3393,7 +3463,7 @@ This Lua value must be a table or <b>nil</b>.
<hr><h3><a name="lua_insert"><code>lua_insert</code></a></h3><p>
-<span class="apii">[-1, +1, <em>-</em>]</span>
+<span class="apii">[-1, +1, &ndash;]</span>
<pre>void lua_insert (lua_State *L, int index);</pre>
<p>
@@ -3423,11 +3493,11 @@ which is usually the largest signed integral type the machine handles
<hr><h3><a name="lua_isboolean"><code>lua_isboolean</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_isboolean (lua_State *L, int index);</pre>
<p>
-Returns 1 if the value at the given acceptable index has type boolean,
+Returns 1 if the value at the given acceptable index is a boolean,
and 0&nbsp;otherwise.
@@ -3435,7 +3505,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_iscfunction"><code>lua_iscfunction</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_iscfunction (lua_State *L, int index);</pre>
<p>
@@ -3447,7 +3517,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_isfunction"><code>lua_isfunction</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_isfunction (lua_State *L, int index);</pre>
<p>
@@ -3459,7 +3529,7 @@ Returns 1 if the value at the given acceptable index is a function
<hr><h3><a name="lua_islightuserdata"><code>lua_islightuserdata</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_islightuserdata (lua_State *L, int index);</pre>
<p>
@@ -3471,7 +3541,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_isnil"><code>lua_isnil</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_isnil (lua_State *L, int index);</pre>
<p>
@@ -3483,7 +3553,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_isnone"><code>lua_isnone</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_isnone (lua_State *L, int index);</pre>
<p>
@@ -3496,7 +3566,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_isnoneornil"><code>lua_isnoneornil</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_isnoneornil (lua_State *L, int index);</pre>
<p>
@@ -3510,7 +3580,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_isnumber"><code>lua_isnumber</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_isnumber (lua_State *L, int index);</pre>
<p>
@@ -3523,7 +3593,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_isstring"><code>lua_isstring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_isstring (lua_State *L, int index);</pre>
<p>
@@ -3536,7 +3606,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_istable"><code>lua_istable</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_istable (lua_State *L, int index);</pre>
<p>
@@ -3548,7 +3618,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_isthread"><code>lua_isthread</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_isthread (lua_State *L, int index);</pre>
<p>
@@ -3560,7 +3630,7 @@ and 0&nbsp;otherwise.
<hr><h3><a name="lua_isuserdata"><code>lua_isuserdata</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_isuserdata (lua_State *L, int index);</pre>
<p>
@@ -3585,7 +3655,7 @@ The result is pushed on the stack.
<hr><h3><a name="lua_load"><code>lua_load</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>int lua_load (lua_State *L,
lua_Reader reader,
void *data,
@@ -3601,13 +3671,13 @@ The return values of <a href="#lua_load"><code>lua_load</code></a> are:
<ul>
-<li><b><a href="#pdf-LUA_OK"><code>LUA_OK</code></a> (0): </b> no errors;</li>
+<li><b><a href="#pdf-LUA_OK"><code>LUA_OK</code></a>: </b> no errors;</li>
<li><b><a name="pdf-LUA_ERRSYNTAX"><code>LUA_ERRSYNTAX</code></a>: </b>
-syntax error during pre-compilation;</li>
+syntax error during precompilation;</li>
<li><b><a href="#pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>: </b>
-memory allocation error.</li>
+memory allocation error;</li>
<li><b><a href="#pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>: </b>
error while running a <code>__gc</code> metamethod.
@@ -3623,7 +3693,7 @@ it does not run it.
<p>
-<a href="#lua_load"><code>lua_load</code></a> automatically detects whether the chunk is text or binary,
+<a href="#lua_load"><code>lua_load</code></a> automatically detects whether the chunk is text or binary
and loads it accordingly (see program <code>luac</code>).
@@ -3642,25 +3712,25 @@ which is used for error messages and in debug information (see <a href="#4.9">&s
If the resulting function has one upvalue,
this upvalue is set to the value of the global environment
stored at index <code>LUA_RIDX_GLOBALS</code> in the registry (see <a href="#4.5">&sect;4.5</a>).
-(When loading main chunks,
-this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).)
+When loading main chunks,
+this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).
<hr><h3><a name="lua_newstate"><code>lua_newstate</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_State *lua_newstate (lua_Alloc f, void *ud);</pre>
<p>
Creates a new thread running in a new, independent state.
-Returns <code>NULL</code> if cannot create the thread/state
+Returns <code>NULL</code> if cannot create the thread or the state
(due to lack of memory).
The argument <code>f</code> is the allocator function;
Lua does all memory allocation for this state through this function.
The second argument, <code>ud</code>, is an opaque pointer that Lua
-simply passes to the allocator in every call.
+passes to the allocator in every call.
@@ -3686,7 +3756,7 @@ It is equivalent to <code>lua_createtable(L, 0, 0)</code>.
Creates a new thread, pushes it on the stack,
and returns a pointer to a <a href="#lua_State"><code>lua_State</code></a> that represents this new thread.
The new thread returned by this function shares with the original thread
-all global objects (such as tables),
+its global environment,
but has an independent execution stack.
@@ -3707,15 +3777,7 @@ like any Lua object.
This function allocates a new block of memory with the given size,
pushes onto the stack a new full userdata with the block address,
and returns this address.
-
-
-<p>
-Userdata represent C&nbsp;values in Lua.
-A <em>full userdata</em> represents a block of memory.
-It is an object (like a table):
-you must create it, it can have its own metatable,
-and you can detect when it is being collected.
-A full userdata is only equal to itself (under raw equality).
+The host program can freely use this memory.
@@ -3780,7 +3842,7 @@ Lua to operate with another type for numbers (e.g., float or long).
<hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p>
-<span class="apii">[-(nargs + 1), +(nresults|1), <em>-</em>]</span>
+<span class="apii">[-(nargs + 1), +(nresults|1), &ndash;]</span>
<pre>int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);</pre>
<p>
@@ -3855,9 +3917,13 @@ It is generated by the garbage collector.)
<hr><h3><a name="lua_pcallk"><code>lua_pcallk</code></a></h3><p>
-<span class="apii">[-(nargs + 1), +(nresults|1), <em>-</em>]</span>
-<pre>int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
- int ctx, lua_CFunction k);</pre>
+<span class="apii">[-(nargs + 1), +(nresults|1), &ndash;]</span>
+<pre>int lua_pcallk (lua_State *L,
+ int nargs,
+ int nresults,
+ int errfunc,
+ int ctx,
+ lua_CFunction k);</pre>
<p>
This function behaves exactly like <a href="#lua_pcall"><code>lua_pcall</code></a>,
@@ -3868,7 +3934,7 @@ but allows the called function to yield (see <a href="#4.7">&sect;4.7</a>).
<hr><h3><a name="lua_pop"><code>lua_pop</code></a></h3><p>
-<span class="apii">[-n, +0, <em>-</em>]</span>
+<span class="apii">[-n, +0, &ndash;]</span>
<pre>void lua_pop (lua_State *L, int n);</pre>
<p>
@@ -3879,7 +3945,7 @@ Pops <code>n</code> elements from the stack.
<hr><h3><a name="lua_pushboolean"><code>lua_pushboolean</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_pushboolean (lua_State *L, int b);</pre>
<p>
@@ -3920,14 +3986,14 @@ The maximum value for <code>n</code> is 255.
When <code>n</code> is zero,
this function creates a <em>light C function</em>,
which is just a pointer to the C&nbsp;function.
-In that case, it cannot throw a memory error.
+In that case, it never throws a memory error.
<hr><h3><a name="lua_pushcfunction"><code>lua_pushcfunction</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre>
<p>
@@ -3948,7 +4014,9 @@ and return its results (see <a href="#lua_CFunction"><code>lua_CFunction</code><
<pre>
#define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)
-</pre>
+</pre><p>
+Note that <code>f</code> is used twice.
+
@@ -3980,7 +4048,7 @@ The conversion specifiers can only be
'<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>),
'<code>%p</code>' (inserts a pointer as a hexadecimal numeral),
'<code>%d</code>' (inserts an <code>int</code>), and
-'<code>%c</code>' (inserts an <code>int</code> as a character).
+'<code>%c</code>' (inserts an <code>int</code> as a byte).
</li>
</ul>
@@ -3989,7 +4057,7 @@ The conversion specifiers can only be
<hr><h3><a name="lua_pushinteger"><code>lua_pushinteger</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_pushinteger (lua_State *L, lua_Integer n);</pre>
<p>
@@ -4000,7 +4068,7 @@ Pushes a number with value <code>n</code> onto the stack.
<hr><h3><a name="lua_pushlightuserdata"><code>lua_pushlightuserdata</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_pushlightuserdata (lua_State *L, void *p);</pre>
<p>
@@ -4027,7 +4095,7 @@ light userdata with the same C&nbsp;address.
<p>
This macro is equivalent to <a href="#lua_pushlstring"><code>lua_pushlstring</code></a>,
but can be used only when <code>s</code> is a literal string.
-In these cases, it automatically provides the string length.
+It automatically provides the string length.
@@ -4055,7 +4123,7 @@ Returns a pointer to the internal copy of the string.
<hr><h3><a name="lua_pushnil"><code>lua_pushnil</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_pushnil (lua_State *L);</pre>
<p>
@@ -4066,7 +4134,7 @@ Pushes a nil value onto the stack.
<hr><h3><a name="lua_pushnumber"><code>lua_pushnumber</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre>
<p>
@@ -4100,7 +4168,7 @@ If <code>s</code> is <code>NULL</code>, pushes <b>nil</b> and returns <code>NULL
<hr><h3><a name="lua_pushthread"><code>lua_pushthread</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>int lua_pushthread (lua_State *L);</pre>
<p>
@@ -4112,7 +4180,7 @@ Returns 1 if this thread is the main thread of its state.
<hr><h3><a name="lua_pushvalue"><code>lua_pushvalue</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_pushvalue (lua_State *L, int index);</pre>
<p>
@@ -4138,7 +4206,7 @@ instead of a variable number of arguments.
<hr><h3><a name="lua_rawequal"><code>lua_rawequal</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_rawequal (lua_State *L, int index1, int index2);</pre>
<p>
@@ -4153,7 +4221,7 @@ Also returns&nbsp;0 if any of the indices are non valid.
<hr><h3><a name="lua_rawget"><code>lua_rawget</code></a></h3><p>
-<span class="apii">[-1, +1, <em>-</em>]</span>
+<span class="apii">[-1, +1, &ndash;]</span>
<pre>void lua_rawget (lua_State *L, int index);</pre>
<p>
@@ -4165,7 +4233,7 @@ Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw
<hr><h3><a name="lua_rawgeti"><code>lua_rawgeti</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void lua_rawgeti (lua_State *L, int index, int n);</pre>
<p>
@@ -4178,8 +4246,23 @@ that is, it does not invoke metamethods.
+<hr><h3><a name="lua_rawgetp"><code>lua_rawgetp</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_rawgetp (lua_State *L, int index, const void *p);</pre>
+
+<p>
+Pushes onto the stack the value <code>t[k]</code>,
+where <code>t</code> is the table at the given valid index and
+<code>k</code> is the pointer <code>p</code> represented as a light userdata.
+The access is raw;
+that is, it does not invoke metamethods.
+
+
+
+
+
<hr><h3><a name="lua_rawlen"><code>lua_rawlen</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>size_t lua_rawlen (lua_State *L, int index);</pre>
<p>
@@ -4226,6 +4309,26 @@ that is, it does not invoke metamethods.
+<hr><h3><a name="lua_rawsetp"><code>lua_rawsetp</code></a></h3><p>
+<span class="apii">[-1, +0, <em>m</em>]</span>
+<pre>void lua_rawsetp (lua_State *L, int index, const void *p);</pre>
+
+<p>
+Does the equivalent of <code>t[k] = v</code>,
+where <code>t</code> is the table at the given valid index,
+<code>k</code> is the pointer <code>p</code> represented as a light userdata,
+and <code>v</code> is the value at the top of the stack.
+
+
+<p>
+This function pops the value from the stack.
+The assignment is raw;
+that is, it does not invoke metamethods.
+
+
+
+
+
<hr><h3><a name="lua_Reader"><code>lua_Reader</code></a></h3>
<pre>typedef const char * (*lua_Reader) (lua_State *L,
void *data,
@@ -4250,9 +4353,7 @@ The reader function may return pieces of any size greater than zero.
<hr><h3><a name="lua_register"><code>lua_register</code></a></h3><p>
<span class="apii">[-0, +0, <em>e</em>]</span>
-<pre>void lua_register (lua_State *L,
- const char *name,
- lua_CFunction f);</pre>
+<pre>void lua_register (lua_State *L, const char *name, lua_CFunction f);</pre>
<p>
Sets the C function <code>f</code> as the new value of global <code>name</code>.
@@ -4267,7 +4368,7 @@ It is defined as a macro:
<hr><h3><a name="lua_remove"><code>lua_remove</code></a></h3><p>
-<span class="apii">[-1, +0, <em>-</em>]</span>
+<span class="apii">[-1, +0, &ndash;]</span>
<pre>void lua_remove (lua_State *L, int index);</pre>
<p>
@@ -4281,7 +4382,7 @@ because a pseudo-index is not an actual stack position.
<hr><h3><a name="lua_replace"><code>lua_replace</code></a></h3><p>
-<span class="apii">[-1, +0, <em>-</em>]</span>
+<span class="apii">[-1, +0, &ndash;]</span>
<pre>void lua_replace (lua_State *L, int index);</pre>
<p>
@@ -4295,8 +4396,8 @@ and then pops the top element.
<hr><h3><a name="lua_resume"><code>lua_resume</code></a></h3><p>
-<span class="apii">[-?, +?, <em>-</em>]</span>
-<pre>int lua_resume (lua_State *L, int narg);</pre>
+<span class="apii">[-?, +?, &ndash;]</span>
+<pre>int lua_resume (lua_State *L, lua_State *from, int narg);</pre>
<p>
Starts and resumes a coroutine in a given thread.
@@ -4330,11 +4431,17 @@ be passed as results from <code>yield</code>,
and then call <a href="#lua_resume"><code>lua_resume</code></a>.
+<p>
+The parameter <code>from</code> represents the coroutine that is resuming <code>L</code>.
+If there is no such coroutine,
+this parameter can be <code>NULL</code>.
+
+
<hr><h3><a name="lua_setallocf"><code>lua_setallocf</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);</pre>
<p>
@@ -4371,14 +4478,13 @@ for the "newindex" event (see <a href="#2.4">&sect;2.4</a>).
<p>
Pops a value from the stack and
sets it as the new value of global <code>name</code>.
-It is defined as a macro.
<hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p>
-<span class="apii">[-1, +0, <em>-</em>]</span>
+<span class="apii">[-1, +0, &ndash;]</span>
<pre>void lua_setmetatable (lua_State *L, int index);</pre>
<p>
@@ -4411,7 +4517,7 @@ for the "newindex" event (see <a href="#2.4">&sect;2.4</a>).
<hr><h3><a name="lua_settop"><code>lua_settop</code></a></h3><p>
-<span class="apii">[-?, +?, <em>-</em>]</span>
+<span class="apii">[-?, +?, &ndash;]</span>
<pre>void lua_settop (lua_State *L, int index);</pre>
<p>
@@ -4426,7 +4532,7 @@ If <code>index</code> is&nbsp;0, then all stack elements are removed.
<hr><h3><a name="lua_setuservalue"><code>lua_setuservalue</code></a></h3><p>
-<span class="apii">[-1, +0, <em>-</em>]</span>
+<span class="apii">[-1, +0, &ndash;]</span>
<pre>void lua_setuservalue (lua_State *L, int index);</pre>
<p>
@@ -4457,7 +4563,7 @@ which creates a Lua state from scratch.
<hr><h3><a name="lua_status"><code>lua_status</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_status (lua_State *L);</pre>
<p>
@@ -4482,7 +4588,7 @@ You can resume threads with status <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>
<hr><h3><a name="lua_toboolean"><code>lua_toboolean</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_toboolean (lua_State *L, int index);</pre>
<p>
@@ -4501,7 +4607,7 @@ use <a href="#lua_isboolean"><code>lua_isboolean</code></a> to test the value's
<hr><h3><a name="lua_tocfunction"><code>lua_tocfunction</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_CFunction lua_tocfunction (lua_State *L, int index);</pre>
<p>
@@ -4514,18 +4620,18 @@ otherwise, returns <code>NULL</code>.
<hr><h3><a name="lua_tointeger"><code>lua_tointeger</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_Integer lua_tointeger (lua_State *L, int index);</pre>
<p>
-A macro equivalent to <code>lua_tointegerx(L, index, NULL)</code>.
+Equivalent to <a href="#lua_tointegerx"><code>lua_tointegerx</code></a> with <code>isnum</code> equal to <code>NULL</code>.
<hr><h3><a name="lua_tointegerx"><code>lua_tointegerx</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);</pre>
<p>
@@ -4533,7 +4639,7 @@ Converts the Lua value at the given acceptable index
to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>.
The Lua value must be a number or a string convertible to a number
(see <a href="#3.4.2">&sect;3.4.2</a>);
-otherwise, <a href="#lua_tointegerx"><code>lua_tointegerx</code></a> returns&nbsp;0.
+otherwise, <code>lua_tointegerx</code> returns&nbsp;0.
<p>
@@ -4542,7 +4648,7 @@ it is truncated in some non-specified way.
<p>
-If <code>isnum</code> is different from <code>NULL</code>,
+If <code>isnum</code> is not <code>NULL</code>,
its referent is assigned a boolean value that
indicates whether the operation succeeded.
@@ -4561,20 +4667,20 @@ it also sets <code>*len</code> with the string length.
The Lua value must be a string or a number;
otherwise, the function returns <code>NULL</code>.
If the value is a number,
-then <a href="#lua_tolstring"><code>lua_tolstring</code></a> also
+then <code>lua_tolstring</code> also
<em>changes the actual value in the stack to a string</em>.
(This change confuses <a href="#lua_next"><code>lua_next</code></a>
-when <a href="#lua_tolstring"><code>lua_tolstring</code></a> is applied to keys during a table traversal.)
+when <code>lua_tolstring</code> is applied to keys during a table traversal.)
<p>
-<a href="#lua_tolstring"><code>lua_tolstring</code></a> returns a fully aligned pointer
+<code>lua_tolstring</code> returns a fully aligned pointer
to a string inside the Lua state.
This string always has a zero ('<code>\0</code>')
after its last character (as in&nbsp;C),
but can contain other zeros in its body.
Because Lua has garbage collection,
-there is no guarantee that the pointer returned by <a href="#lua_tolstring"><code>lua_tolstring</code></a>
+there is no guarantee that the pointer returned by <code>lua_tolstring</code>
will be valid after the corresponding value is removed from the stack.
@@ -4582,18 +4688,18 @@ will be valid after the corresponding value is removed from the stack.
<hr><h3><a name="lua_tonumber"><code>lua_tonumber</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_Number lua_tonumber (lua_State *L, int index);</pre>
<p>
-A macro equivalent to <code>lua_tonumberx(L, index, NULL)</code>.
+Equivalent to <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> with <code>isnum</code> equal to <code>NULL</code>.
<hr><h3><a name="lua_tonumberx"><code>lua_tonumberx</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);</pre>
<p>
@@ -4605,7 +4711,7 @@ otherwise, <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> returns&nbsp;
<p>
-If <code>isnum</code> is different from <code>NULL</code>,
+If <code>isnum</code> is not <code>NULL</code>,
its referent is assigned a boolean value that
indicates whether the operation succeeded.
@@ -4614,14 +4720,14 @@ indicates whether the operation succeeded.
<hr><h3><a name="lua_topointer"><code>lua_topointer</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>const void *lua_topointer (lua_State *L, int index);</pre>
<p>
Converts the value at the given acceptable index to a generic
C&nbsp;pointer (<code>void*</code>).
The value can be a userdata, a table, a thread, or a function;
-otherwise, <a href="#lua_topointer"><code>lua_topointer</code></a> returns <code>NULL</code>.
+otherwise, <code>lua_topointer</code> returns <code>NULL</code>.
Different objects will give different pointers.
There is no way to convert the pointer back to its original value.
@@ -4645,7 +4751,7 @@ Equivalent to <a href="#lua_tolstring"><code>lua_tolstring</code></a> with <code
<hr><h3><a name="lua_tothread"><code>lua_tothread</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_State *lua_tothread (lua_State *L, int index);</pre>
<p>
@@ -4659,18 +4765,18 @@ 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>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_Unsigned lua_tounsigned (lua_State *L, int index);</pre>
<p>
-A macro equivalent to <code>lua_tounsignedx(L, index, NULL)</code>.
+Equivalent to <a href="#lua_tounsignedx"><code>lua_tounsignedx</code></a> with <code>isnum</code> equal to <code>NULL</code>.
<hr><h3><a name="lua_tounsignedx"><code>lua_tounsignedx</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);</pre>
<p>
@@ -4678,7 +4784,7 @@ Converts the Lua value at the given acceptable index
to the unsigned integral type <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
The Lua value must be a number or a string convertible to a number
(see <a href="#3.4.2">&sect;3.4.2</a>);
-otherwise, <a href="#lua_tounsignedx"><code>lua_tounsignedx</code></a> returns&nbsp;0.
+otherwise, <code>lua_tounsignedx</code> returns&nbsp;0.
<p>
@@ -4690,7 +4796,7 @@ one more than the maximum representable value.
<p>
-If <code>isnum</code> is different from <code>NULL</code>,
+If <code>isnum</code> is not <code>NULL</code>,
its referent is assigned a boolean value that
indicates whether the operation succeeded.
@@ -4699,7 +4805,7 @@ 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>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>void *lua_touserdata (lua_State *L, int index);</pre>
<p>
@@ -4714,13 +4820,12 @@ Otherwise, returns <code>NULL</code>.
<hr><h3><a name="lua_type"><code>lua_type</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_type (lua_State *L, int index);</pre>
<p>
Returns the type of the value in the given acceptable index,
-or <code>LUA_TNONE</code> for a non-valid index
-(that is, an index to an "empty" stack position).
+or <code>LUA_TNONE</code> for a non-valid index.
The types returned by <a href="#lua_type"><code>lua_type</code></a> are coded by the following constants
defined in <code>lua.h</code>:
<a name="pdf-LUA_TNIL"><code>LUA_TNIL</code></a>,
@@ -4739,7 +4844,7 @@ and
<hr><h3><a name="lua_typename"><code>lua_typename</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>const char *lua_typename (lua_State *L, int tp);</pre>
<p>
@@ -4807,11 +4912,11 @@ calling the writer again.
<hr><h3><a name="lua_xmove"><code>lua_xmove</code></a></h3><p>
-<span class="apii">[-?, +?, <em>-</em>]</span>
+<span class="apii">[-?, +?, &ndash;]</span>
<pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre>
<p>
-Exchange values between different threads of the same global state.
+Exchange values between different threads of the same state.
<p>
@@ -4823,7 +4928,7 @@ and pushes them onto the stack <code>to</code>.
<hr><h3><a name="lua_yield"><code>lua_yield</code></a></h3><p>
-<span class="apii">[-?, +?, <em>-</em>]</span>
+<span class="apii">[-?, +?, &ndash;]</span>
<pre>int lua_yield (lua_State *L, int nresults);</pre>
<p>
@@ -4838,7 +4943,7 @@ the function calling <code>lua_yield</code>.
<hr><h3><a name="lua_yieldk"><code>lua_yieldk</code></a></h3><p>
-<span class="apii">[-?, +?, <em>-</em>]</span>
+<span class="apii">[-?, +?, &ndash;]</span>
<pre>int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k);</pre>
<p>
@@ -4850,7 +4955,7 @@ This function should only be called as the
return expression of a C&nbsp;function, as follows:
<pre>
- return lua_yield (L, nresults, i, k);
+ return lua_yieldk (L, n, i, k);
</pre><p>
When a C&nbsp;function calls <a href="#lua_yieldk"><code>lua_yieldk</code></a> in that way,
the running coroutine suspends its execution,
@@ -4928,7 +5033,7 @@ If <code>source</code> starts with a '<code>@</code>',
it means that the function was defined in a file where
the file name follows the '<code>@</code>'.
If <code>source</code> starts with a '<code>=</code>',
-the rest of it should describe the source in a user-dependent manner.
+the remainder of its contents describe the source in a user-dependent manner.
Otherwise,
the function was defined in a string where
<code>source</code> is that string.
@@ -4994,7 +5099,7 @@ the number of fixed parameters of the function
</li>
<li><b><code>isvararg</code>: </b>
-whether the function is a vararg function
+true if the function is a vararg function
(always true for C&nbsp;functions).
</li>
@@ -5004,7 +5109,7 @@ whether the function is a vararg function
<hr><h3><a name="lua_gethook"><code>lua_gethook</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_Hook lua_gethook (lua_State *L);</pre>
<p>
@@ -5015,7 +5120,7 @@ Returns the current hook function.
<hr><h3><a name="lua_gethookcount"><code>lua_gethookcount</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_gethookcount (lua_State *L);</pre>
<p>
@@ -5026,7 +5131,7 @@ Returns the current hook count.
<hr><h3><a name="lua_gethookmask"><code>lua_gethookmask</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_gethookmask (lua_State *L);</pre>
<p>
@@ -5115,7 +5220,7 @@ This function returns 0 on error
<hr><h3><a name="lua_getlocal"><code>lua_getlocal</code></a></h3><p>
-<span class="apii">[-0, +(0|1), <em>-</em>]</span>
+<span class="apii">[-0, +(0|1), &ndash;]</span>
<pre>const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);</pre>
<p>
@@ -5156,7 +5261,7 @@ the number of active local variables.
<hr><h3><a name="lua_getstack"><code>lua_getstack</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_getstack (lua_State *L, int level, lua_Debug *ar);</pre>
<p>
@@ -5179,7 +5284,7 @@ it returns 0.
<hr><h3><a name="lua_getupvalue"><code>lua_getupvalue</code></a></h3><p>
-<span class="apii">[-0, +(0|1), <em>-</em>]</span>
+<span class="apii">[-0, +(0|1), &ndash;]</span>
<pre>const char *lua_getupvalue (lua_State *L, int funcindex, int n);</pre>
<p>
@@ -5241,7 +5346,7 @@ this execution occurs without any calls to hooks.
<hr><h3><a name="lua_sethook"><code>lua_sethook</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);</pre>
<p>
@@ -5294,7 +5399,7 @@ A hook is disabled by setting <code>mask</code> to zero.
<hr><h3><a name="lua_setlocal"><code>lua_setlocal</code></a></h3><p>
-<span class="apii">[-(0|1), +0, <em>-</em>]</span>
+<span class="apii">[-(0|1), +0, &ndash;]</span>
<pre>const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);</pre>
<p>
@@ -5316,7 +5421,7 @@ the number of active local variables.
<hr><h3><a name="lua_setupvalue"><code>lua_setupvalue</code></a></h3><p>
-<span class="apii">[-(0|1), +0, <em>-</em>]</span>
+<span class="apii">[-(0|1), +0, &ndash;]</span>
<pre>const char *lua_setupvalue (lua_State *L, int funcindex, int n);</pre>
<p>
@@ -5337,7 +5442,7 @@ when the index is greater than the number of upvalues.
<hr><h3><a name="lua_upvalueid"><code>lua_upvalueid</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>void *lua_upvalueid (lua_State *L, int funcindex, int n);</pre>
<p>
@@ -5386,7 +5491,7 @@ common tasks.
<p>
-All functions from the auxiliary library
+All functions and types from the auxiliary library
are defined in header file <code>lauxlib.h</code> and
have a prefix <code>luaL_</code>.
@@ -5395,6 +5500,8 @@ have a prefix <code>luaL_</code>.
All functions in the auxiliary library are built on
top of the basic API,
and so they provide nothing that cannot be done with that API.
+Nevertheless, the use of the auxiliary library ensures
+more consistency to your code.
<p>
@@ -5432,7 +5539,7 @@ in alphabetical order.
<pre>void luaL_addchar (luaL_Buffer *B, char c);</pre>
<p>
-Adds the character <code>c</code> to the buffer <code>B</code>
+Adds the byte <code>c</code> to the buffer <code>B</code>
(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
@@ -5474,7 +5581,7 @@ buffer area (see <a href="#luaL_prepbuffer"><code>luaL_prepbuffer</code></a>).
Adds the zero-terminated string pointed to by <code>s</code>
to the buffer <code>B</code>
(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
-The string should not contain embedded zeros.
+The string cannot contain embedded zeros.
@@ -5509,12 +5616,8 @@ which is the value to be added to the buffer.
<p>
Checks whether <code>cond</code> is true.
-If not, raises an error with the following message,
-where <code>func</code> is retrieved from the call stack:
+If not, raises an error with a standard message.
-<pre>
- bad argument #&lt;narg&gt; to &lt;func&gt; (&lt;extramsg&gt;)
-</pre>
@@ -5524,12 +5627,9 @@ where <code>func</code> is retrieved from the call stack:
<pre>int luaL_argerror (lua_State *L, int narg, const char *extramsg);</pre>
<p>
-Raises an error with the following message,
-where <code>func</code> is retrieved from the call stack:
+Raises an error with a standard message
+that includes <code>extramsg</code> as a comment.
-<pre>
- bad argument #&lt;narg&gt; to &lt;func&gt; (&lt;extramsg&gt;)
-</pre>
<p>
This function never returns,
@@ -5553,17 +5653,17 @@ Its pattern of use is as follows:
<ul>
-<li>First you declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
+<li>First declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
-<li>Then you initialize it with a call <code>luaL_buffinit(L, &amp;b)</code>.</li>
+<li>Then initialize it with a call <code>luaL_buffinit(L, &amp;b)</code>.</li>
<li>
-Then you add string pieces to the buffer calling any of
+Then add string pieces to the buffer calling any of
the <code>luaL_add*</code> functions.
</li>
<li>
-You finish by calling <code>luaL_pushresult(&amp;b)</code>.
+Finish by calling <code>luaL_pushresult(&amp;b)</code>.
This call leaves the final string on the top of the stack.
</li>
@@ -5575,15 +5675,15 @@ you can use the buffer like this:
<ul>
-<li>First you declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
+<li>First declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
-<li>Then you initialize it and preallocate a space of
+<li>Then initialize it and preallocate a space of
size <code>sz</code> with a call <code>luaL_buffinitsize(L, &amp;b, sz)</code>.</li>
-<li>Then you copy the string into that space.</li>
+<li>Then copy the string into that space.</li>
<li>
-You finish by calling <code>luaL_pushresult(&amp;b, sz)</code>,
+Finish by calling <code>luaL_pushresult(&amp;b, sz)</code>,
where <code>sz</code> is the total size of the resulting string
copied into that space.
</li>
@@ -5611,7 +5711,7 @@ plus the final string on its top.
<hr><h3><a name="luaL_buffinit"><code>luaL_buffinit</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>void luaL_buffinit (lua_State *L, luaL_Buffer *B);</pre>
<p>
@@ -5647,7 +5747,7 @@ Calls a metamethod.
<p>
If the object at index <code>obj</code> has a metatable and this
metatable has a field <code>e</code>,
-this function calls this field and passes the object as its only argument.
+this function calls this field passing the object as its only argument.
In this case this function returns true and pushes onto the
stack the value returned by the call.
If there is no metatable or no metamethod,
@@ -5755,7 +5855,7 @@ if the string cannot be found.
<p>
If <code>def</code> is not <code>NULL</code>,
the function uses <code>def</code> as a default value when
-there is no argument <code>narg</code> or if this argument is <b>nil</b>.
+there is no argument <code>narg</code> or when this argument is <b>nil</b>.
<p>
@@ -5836,7 +5936,7 @@ and returns this number cast to a <a href="#lua_Unsigned"><code>lua_Unsigned</co
<hr><h3><a name="luaL_checkversion"><code>luaL_checkversion</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>void luaL_checkversion (lua_State *L);</pre>
<p>
@@ -5870,7 +5970,7 @@ or true in case of errors.
<hr><h3><a name="luaL_dostring"><code>luaL_dostring</code></a></h3><p>
-<span class="apii">[-0, +?, <em>-</em>]</span>
+<span class="apii">[-0, +?, &ndash;]</span>
<pre>int luaL_dostring (lua_State *L, const char *str);</pre>
<p>
@@ -5952,7 +6052,7 @@ returns false and pushes nothing.
<hr><h3><a name="luaL_getmetatable"><code>luaL_getmetatable</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>void luaL_getmetatable (lua_State *L, const char *tname);</pre>
<p>
@@ -6012,7 +6112,7 @@ Raises an error if the result of the operation is not a number.
<hr><h3><a name="luaL_loadbuffer"><code>luaL_loadbuffer</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>int luaL_loadbuffer (lua_State *L,
const char *buff,
size_t sz,
@@ -6035,7 +6135,16 @@ used for debug information and error messages.
<hr><h3><a name="luaL_loadfile"><code>luaL_loadfile</code></a></h3><p>
<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>int luaL_loadfile (lua_State *L, const char *filename);</pre>
+<pre>int luaL_loadfile (lua_State *L, const char *filename);</pre><p>
+Equivalent to <a href="#luaL_loadfilex"><code>luaL_loadfilex</code></a> with <code>mode</code> equal to <code>NULL</code>.
+
+
+
+
+<hr><h3><a name="luaL_loadfilex"><code>luaL_loadfilex</code></a></h3><p>
+<span class="apii">[-0, +1, <em>m</em>]</span>
+<pre>int luaL_loadfilex (lua_State *L, const char *filename,
+ const char *mode);</pre>
<p>
Loads a file as a Lua chunk.
@@ -6047,9 +6156,15 @@ The first line in the file is ignored if it starts with a <code>#</code>.
<p>
+The string <code>mode</code> works as in function <a href="#pdf-load"><code>load</code></a>,
+with the addition that
+a <code>NULL</code> value is equivalent to the string "<code>bt</code>".
+
+
+<p>
This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>,
but it has an extra error code <a name="pdf-LUA_ERRFILE"><code>LUA_ERRFILE</code></a>
-if it cannot open/read the file.
+if it cannot open/read the file or the file has a wrong mode.
<p>
@@ -6061,7 +6176,7 @@ it does not run it.
<hr><h3><a name="luaL_loadstring"><code>luaL_loadstring</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
+<span class="apii">[-0, +1, &ndash;]</span>
<pre>int luaL_loadstring (lua_State *L, const char *s);</pre>
<p>
@@ -6141,7 +6256,7 @@ with <code>tname</code> in the registry.
<hr><h3><a name="luaL_newstate"><code>luaL_newstate</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>lua_State *luaL_newstate (void);</pre>
<p>
@@ -6434,7 +6549,7 @@ These values are popped from the stack after the registration.
<hr><h3><a name="luaL_setmetatable"><code>luaL_setmetatable</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>void luaL_setmetatable (lua_State *L, const char *tname);</pre>
<p>
@@ -6499,7 +6614,7 @@ to start the traceback.
<hr><h3><a name="luaL_typename"><code>luaL_typename</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>const char *luaL_typename (lua_State *L, int index);</pre>
<p>
@@ -6510,7 +6625,7 @@ Returns the name of the type of the value at the given index.
<hr><h3><a name="luaL_unref"><code>luaL_unref</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
+<span class="apii">[-0, +0, &ndash;]</span>
<pre>void luaL_unref (lua_State *L, int t, int ref);</pre>
<p>
@@ -6575,28 +6690,28 @@ Currently, Lua has the following standard libraries:
<ul>
-<li>basic library;</li>
+<li>basic library (<a href="#6.1">&sect;6.1</a>);</li>
-<li>package library;</li>
+<li>coroutine library (<a href="#6.2">&sect;6.2</a>);</li>
-<li>coroutine library;</li>
+<li>package library (<a href="#6.3">&sect;6.3</a>);</li>
-<li>string manipulation;</li>
+<li>string manipulation (<a href="#6.4">&sect;6.4</a>);</li>
-<li>table manipulation;</li>
+<li>table manipulation (<a href="#6.5">&sect;6.5</a>);</li>
-<li>mathematical functions (sin, log, etc.);</li>
+<li>mathematical functions (<a href="#6.6">&sect;6.6</a>) (sin, log, etc.);</li>
-<li>bitwise operations;</li>
+<li>bitwise operations (<a href="#6.7">&sect;6.7</a>);</li>
-<li>input and output;</li>
+<li>input and output (<a href="#6.8">&sect;6.8</a>);</li>
-<li>operating system facilities;</li>
+<li>operating system facilities (<a href="#6.9">&sect;6.9</a>);</li>
-<li>debug facilities.</li>
+<li>debug facilities (<a href="#6.10">&sect;6.10</a>).</li>
</ul><p>
-Except for the basic and package libraries,
+Except for the basic and the package libraries,
each library provides all its functions as fields of a global table
or as methods of its objects.
@@ -6627,7 +6742,7 @@ e.g., by using <a href="#lua_call"><code>lua_call</code></a>.
<h2>6.1 &ndash; <a name="6.1">Basic Functions</a></h2>
<p>
-The basic library provides some core functions to Lua.
+The basic library provides core functions to Lua.
If you do not include this library in your application,
you should check carefully whether you need to provide
implementations for some of its facilities.
@@ -6660,13 +6775,13 @@ This is the default option.
</li>
<li><b>"<code>stop</code>": </b>
-stops automatic invocation of the garbage collector.
-The collector will run only when explcitly invoked,
+stops automatic execution of the garbage collector.
+The collector will run only when explicitly invoked,
until a call to restart it.
</li>
<li><b>"<code>restart</code>": </b>
-restarts automatic invocation the garbage collector.
+restarts automatic execution of the garbage collector.
</li>
<li><b>"<code>count</code>": </b>
@@ -6709,6 +6824,16 @@ returns a boolean that tells whether the collector is running
(i.e., not stopped).
</li>
+<li><b>"<code>generational</code>": </b>
+changes the collector to generational mode.
+This is an experimental feature (see <a href="#2.5">&sect;2.5</a>).
+</li>
+
+<li><b>"<code>incremental</code>": </b>
+changes the collector to incremental mode.
+This is the default mode.
+</li>
+
</ul>
@@ -6789,7 +6914,7 @@ so that the construction
<pre>
for i,v in ipairs(t) do <em>body</em> end
</pre><p>
-will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), &middot;&middot;&middot;,
+will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), ...,
up to the first integer key absent from the table.
@@ -6823,8 +6948,8 @@ If the resulting function has upvalues,
the first upvalue is set to the value of the
global environment or to <code>env</code>,
if that parameter is given.
-(When loading main chunks,
-the first upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).)
+When loading main chunks,
+the first upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).
<p>
@@ -6832,21 +6957,22 @@ the first upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">&se
and debug information (see <a href="#4.9">&sect;4.9</a>).
When absent,
it defaults to <code>ld</code>, if <code>ld</code> is a string,
-or to "<code>=(load)</code>".
+or to "<code>=(load)</code>" otherwise.
<p>
The string <code>mode</code> controls whether the chunk can be text or binary
(that is, a precompiled chunk).
-A letter '<code>t</code>' in <code>mode</code> allows a text chunk;
-a letter '<code>b</code>' allows a binary chunk.
+It may be the string "<code>b</code>" (only binary chunks),
+"<code>t</code>" (only text chunks),
+or "<code>bt</code>" (both binary and text).
The default is "<code>bt</code>".
<p>
-<hr><h3><a name="pdf-loadfile"><code>loadfile ([filename])</code></a></h3>
+<hr><h3><a name="pdf-loadfile"><code>loadfile ([filename [, mode [, env]]])</code></a></h3>
<p>
@@ -6945,13 +7071,14 @@ In case of any error, <code>pcall</code> returns <b>false</b> plus the error mes
<p>
<hr><h3><a name="pdf-print"><code>print (&middot;&middot;&middot;)</code></a></h3>
-Receives any number of arguments,
+Receives any number of arguments
and prints their values to <code>stdout</code>,
-using the <a href="#pdf-tostring"><code>tostring</code></a> function to convert them to strings.
+using the <a href="#pdf-tostring"><code>tostring</code></a> function to convert each argument to a string.
<code>print</code> is not intended for formatted output,
but only as a quick way to show a value,
-typically for debugging.
-For formatted output, use <a href="#pdf-string.format"><code>string.format</code></a>.
+for instance for debugging.
+For complete control over the output,
+use <a href="#pdf-string.format"><code>string.format</code></a> and <a href="#pdf-io.write"><code>io.write</code></a>.
@@ -6990,7 +7117,7 @@ Returns an integer number.
Sets the real value of <code>table[index]</code> to <code>value</code>,
without invoking any metamethod.
<code>table</code> must be a table,
-<code>index</code> any value different from <b>nil</b>,
+<code>index</code> any value different from <b>nil</b> and NaN,
and <code>value</code> any Lua value.
@@ -7035,37 +7162,43 @@ This function returns <code>table</code>.
<p>
<hr><h3><a name="pdf-tonumber"><code>tonumber (e [, base])</code></a></h3>
-Tries to convert its argument to a number.
-If the argument is already a number or a string convertible
-to a number, then <code>tonumber</code> returns this number;
+
+
+<p>
+When called with no <code>base</code>,
+<code>tonumber</code> tries to convert its argument to a number.
+If the argument is already a number or
+a string convertible to a number (see <a href="#3.4.2">&sect;3.4.2</a>),
+then <code>tonumber</code> returns this number;
otherwise, it returns <b>nil</b>.
<p>
-An optional argument specifies the base to interpret the numeral.
+When called with <code>base</code>,
+then <code>e</code> should be a string to be interpreted as
+an integer numeral in that base.
The base may be any integer between 2 and 36, inclusive.
In bases above&nbsp;10, the letter '<code>A</code>' (in either upper or lower case)
represents&nbsp;10, '<code>B</code>' represents&nbsp;11, and so forth,
with '<code>Z</code>' representing 35.
-In base 10 (the default),
-the numeral is converted following the coercion rules (see <a href="#3.4.2">&sect;3.4.2</a>).
-In other bases, only integers are accepted.
+If the string <code>e</code> is not a valid numeral in the given base,
+the function returns <b>nil</b>.
<p>
-<hr><h3><a name="pdf-tostring"><code>tostring (e)</code></a></h3>
-Receives an argument of any type and
+<hr><h3><a name="pdf-tostring"><code>tostring (v)</code></a></h3>
+Receives a value of any type and
converts it to a string in a reasonable format.
-For complete control of how numbers are converted,
-use <a href="#pdf-string.format"><code>string.format</code></a>.
+(For complete control of how numbers are converted,
+use <a href="#pdf-string.format"><code>string.format</code></a>.)
<p>
-If the metatable of <code>e</code> has a <code>"__tostring"</code> field,
+If the metatable of <code>v</code> has a <code>"__tostring"</code> field,
then <code>tostring</code> calls the corresponding value
-with <code>e</code> as argument,
+with <code>v</code> as argument,
and uses the result of the call as its result.
@@ -7139,11 +7272,11 @@ an object with type <code>"thread"</code>.
Starts or continues the execution of coroutine <code>co</code>.
The first time you resume a coroutine,
it starts running its body.
-The values <code>val1</code>, &middot;&middot;&middot; are passed
+The values <code>val1</code>, ... are passed
as the arguments to the body function.
If the coroutine has yielded,
<code>resume</code> restarts it;
-the values <code>val1</code>, &middot;&middot;&middot; are passed
+the values <code>val1</code>, ... are passed
as the results from the yield.
@@ -7280,7 +7413,7 @@ final value of <code>package.loaded[modname]</code>.
<p>
If there is any error loading or running the module,
or if it cannot find any loader for the module,
-then <code>require</code> signals an error.
+then <code>require</code> raises an error.
@@ -7309,8 +7442,8 @@ 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 building the
-<code>luaopen_</code> function name.
+<li>The fifth line is a mark to ignore all text before it
+when building the <code>luaopen_</code> function name.
Default is '<code>-</code>'.</li>
</ul>
@@ -7372,7 +7505,7 @@ available to other dynamically linked libraries.
Otherwise,
it looks for a function <code>funcname</code> inside the library
and returns this function as a C&nbsp;function.
-(So, <code>funcname</code> must follow the protocol (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>)).
+(So, <code>funcname</code> must follow the prototype <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
<p>
@@ -7409,7 +7542,7 @@ At start-up, Lua initializes this variable with
the value of the environment variable <a name="pdf-LUA_PATH_5_2"><code>LUA_PATH_5_2</code></a> or
the environment variable <a name="pdf-LUA_PATH"><code>LUA_PATH</code></a> or
with a default path defined in <code>luaconf.h</code>,
-if the environment variable is not defined.
+if those environment variables are not defined.
Any "<code>;;</code>" in the value of the environment variable
is replaced by the default path.
@@ -7511,7 +7644,7 @@ with each submodule keeping its original open function.
<p>
-All searchers except the first (preload) return as the extra value
+All searchers except the first one (preload) return as the extra value
the file name where the module was found,
as returned by <a href="#pdf-package.searchpath"><code>package.searchpath</code></a>.
The first searcher returns no extra value.
@@ -7520,7 +7653,7 @@ The first searcher returns no extra value.
<p>
-<hr><h3><a name="pdf-package.searchpath"><code>package.searchpath (name, path [, sep])</code></a></h3>
+<hr><h3><a name="pdf-package.searchpath"><code>package.searchpath (name, path [, sep [, rep]])</code></a></h3>
<p>
@@ -7528,17 +7661,16 @@ Searches for the given <code>name</code> in the given <code>path</code>.
<p>
-A path is string containing a sequence of
+A path is a string containing a sequence of
<em>templates</em> separated by semicolons.
For each template,
-the function changes each interrogation
-mark in the template by a copy of <code>name</code>
+the function replaces each interrogation mark (if any)
+in the template with a copy of <code>name</code>
wherein all occurrences of <code>sep</code>
(a dot, by default)
-were replaced by the system's directory separator,
+were replaced by <code>rep</code>
+(the system's directory separator, by default),
and then tries to open the resulting file name.
-If <code>sep</code> is the empty string,
-the replacement is not done.
<p>
@@ -7583,7 +7715,7 @@ The string library provides all its functions inside the table
It also sets a metatable for strings
where the <code>__index</code> field points to the <code>string</code> table.
Therefore, you can use the string functions in object-oriented style.
-For instance, <code>string.byte(s, i)</code>
+For instance, <code>string.byte(s,i)</code>
can be written as <code>s:byte(i)</code>.
@@ -7594,13 +7726,15 @@ The string library assumes one-byte character encodings.
<p>
<hr><h3><a name="pdf-string.byte"><code>string.byte (s [, i [, j]])</code></a></h3>
Returns the internal numerical codes of the characters <code>s[i]</code>,
-<code>s[i+1]</code>, &middot;&middot;&middot;, <code>s[j]</code>.
+<code>s[i+1]</code>, ..., <code>s[j]</code>.
The default value for <code>i</code> is&nbsp;1;
the default value for <code>j</code> is&nbsp;<code>i</code>.
+These indices are corrected
+following the same rules of function <a href="#pdf-string.sub"><code>string.sub</code></a>.
<p>
-Note that numerical codes are not necessarily portable across platforms.
+Numerical codes are not necessarily portable across platforms.
@@ -7614,7 +7748,7 @@ to its corresponding argument.
<p>
-Note that numerical codes are not necessarily portable across platforms.
+Numerical codes are not necessarily portable across platforms.
@@ -7709,7 +7843,7 @@ it is converted to one following the same rules of <a href="#pdf-tostring"><code
<hr><h3><a name="pdf-string.gmatch"><code>string.gmatch (s, pattern)</code></a></h3>
Returns an iterator function that,
each time it is called,
-returns the next captures from <code>pattern</code> over string <code>s</code>.
+returns the next captures from <code>pattern</code> over the string <code>s</code>.
If <code>pattern</code> specifies no captures,
then the whole match is produced in each call.
@@ -7737,7 +7871,7 @@ given string into a table:
</pre>
<p>
-For this function, a '<code>^</code>' at the start of a pattern does not
+For this function, a caret '<code>^</code>' at the start of a pattern does not
work as an anchor, as this would prevent the iteration.
@@ -7884,6 +8018,17 @@ and <code>string.sub(s, -i)</code> returns a suffix of <code>s</code>
with length <code>i</code>.
+<p>
+If, after the translation of negative indices,
+<code>i</code> is less than zero,
+it is corrected to zero.
+If <code>j</code> is greater than the string length,
+it is corrected to that length.
+If, after these corrections,
+<code>i</code> is greater than <code>j</code>,
+the function returns the empty string.
+
+
<p>
@@ -8050,7 +8195,7 @@ they were the character '<code>\0</code>'.
<h4>Pattern:</h4><p>
A <em>pattern</em> is a sequence of pattern items.
-A '<code>^</code>' at the beginning of a pattern anchors the match at the
+A caret '<code>^</code>' at the beginning of a pattern anchors the match at the
beginning of the subject string.
A '<code>$</code>' at the end of a pattern anchors the match at the
end of the subject string.
@@ -8589,7 +8734,7 @@ result in zero or <code>0xFFFFFFFF</code> (all original bits are shifted out).
<p>
-Returns the bitwise and of its operands.
+Returns the bitwise <em>and</em> of its operands.
@@ -8614,7 +8759,7 @@ the following identity holds:
<p>
-Returns the bitwise or of its operands.
+Returns the bitwise <em>or</em> of its operands.
@@ -8625,7 +8770,7 @@ Returns the bitwise or of its operands.
<p>
Returns a boolean signaling
-whether the bitwise and of its operands is different from zero.
+whether the bitwise <em>and</em> of its operands is different from zero.
@@ -8635,7 +8780,7 @@ whether the bitwise and of its operands is different from zero.
<p>
-Returns the bitwise exclusive or of its operands.
+Returns the bitwise <em>exclusive or</em> of its operands.
@@ -8845,7 +8990,7 @@ instead of returning an error code.
<p>
-<hr><h3><a name="pdf-io.lines"><code>io.lines ([filename] &middot;&middot;&middot;)</code></a></h3>
+<hr><h3><a name="pdf-io.lines"><code>io.lines ([filename &middot;&middot;&middot;])</code></a></h3>
<p>
@@ -8863,6 +9008,11 @@ that is, it iterates over the lines of the default input file.
In this case it does not close the file when the loop ends.
+<p>
+In case of errors this function raises the error,
+instead of returning an error code.
+
+
<p>
@@ -9007,15 +9157,20 @@ each time it is called,
reads the file according to the given formats.
When no format is given,
uses "*l" as a default.
-Therefore, the construction
+As an example, the construction
<pre>
for c in file:lines(1) do <em>body</em> end
</pre><p>
will iterate over all characters of the file,
starting at the current position.
-(Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file
-when the loop ends.)
+Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file
+when the loop ends.
+
+
+<p>
+In case of errors this function raises the error,
+instead of returning an error code.
@@ -9062,7 +9217,7 @@ returning <b>nil</b> on end of file.
</li>
<li><b><em>number</em>: </b>
-reads a string with up to this number of characters,
+reads a string with up to this number of bytes,
returning <b>nil</b> on end of file.
If number is zero,
it reads nothing and returns an empty string,
@@ -9088,9 +9243,9 @@ specified by the string <code>whence</code>, as follows:
<li><b>"<code>cur</code>": </b> base is current position;</li>
<li><b>"<code>end</code>": </b> base is end of file;</li>
</ul><p>
-In case of success, function <code>seek</code> returns the final file position,
+In case of success, <code>seek</code> returns the final file position,
measured in bytes from the beginning of the file.
-If this function fails, it returns <b>nil</b>,
+If <code>seek</code> fails, it returns <b>nil</b>,
plus a string describing the error.
@@ -9123,8 +9278,8 @@ no buffering; the result of any output operation appears immediately.
<li><b>"<code>full</code>": </b>
full buffering; output operation is performed only
-when the buffer is full (or when you explicitly <code>flush</code> the file
-(see <a href="#pdf-io.flush"><code>io.flush</code></a>)).
+when the buffer is full or when
+you explicitly <code>flush</code> the file (see <a href="#pdf-io.flush"><code>io.flush</code></a>).
</li>
<li><b>"<code>line</code>": </b>
@@ -9146,11 +9301,8 @@ The default is an appropriate size.
<p>
-Writes the value of each of its arguments to
-the <code>file</code>.
+Writes the value of each of its arguments to <code>file</code>.
The arguments must be strings or numbers.
-To write other values,
-use <a href="#pdf-tostring"><code>tostring</code></a> or <a href="#pdf-string.format"><code>string.format</code></a> before <code>write</code>.
<p>
@@ -9202,8 +9354,8 @@ then the date is formatted in Coordinated Universal Time.
After this optional character,
if <code>format</code> is the string "<code>*t</code>",
then <code>date</code> returns a table with the following fields:
-<code>year</code> (four digits), <code>month</code> (1--12), <code>day</code> (1--31),
-<code>hour</code> (0--23), <code>min</code> (0--59), <code>sec</code> (0--61),
+<code>year</code> (four digits), <code>month</code> (1&ndash;12), <code>day</code> (1&ndash;31),
+<code>hour</code> (0&ndash;23), <code>min</code> (0&ndash;59), <code>sec</code> (0&ndash;61),
<code>wday</code> (weekday, Sunday is&nbsp;1),
<code>yday</code> (day of the year),
and <code>isdst</code> (daylight saving flag, a boolean).
@@ -9314,7 +9466,7 @@ or <b>nil</b> if the variable is not defined.
Deletes the file (or empty directory, on POSIX systems)
with the given name.
If this function fails, it returns <b>nil</b>,
-plus a string describing the error.
+plus a string describing the error and the error code.
@@ -9326,7 +9478,7 @@ plus a string describing the error.
<p>
Renames file or directory named <code>oldname</code> to <code>newname</code>.
If this function fails, it returns <b>nil</b>,
-plus a string describing the error.
+plus a string describing the error and the error code.
@@ -9337,7 +9489,7 @@ plus a string describing the error.
<p>
Sets the current locale of the program.
-<code>locale</code> is a string specifying a locale;
+<code>locale</code> is a system-dependent string specifying a locale;
<code>category</code> is an optional string describing which category to change:
<code>"all"</code>, <code>"collate"</code>, <code>"ctype"</code>,
<code>"monetary"</code>, <code>"numeric"</code>, or <code>"time"</code>;
@@ -9369,8 +9521,12 @@ for the given category.
Returns the current time when called without arguments,
or a time representing the date and time specified by the given table.
This table must have fields <code>year</code>, <code>month</code>, and <code>day</code>,
-and may have fields <code>hour</code>, <code>min</code>, <code>sec</code>, and <code>isdst</code>
-(for a description of these fields, see the <a href="#pdf-os.date"><code>os.date</code></a> function).
+and may have fields
+<code>hour</code> (default is 12),
+<code>min</code> (default is 0),
+<code>sec</code> (default is 0),
+and <code>isdst</code> (default is <b>nil</b>).
+For a description of these fields, see the <a href="#pdf-os.date"><code>os.date</code></a> function.
<p>
@@ -9380,7 +9536,7 @@ this number counts the number
of seconds since some given start time (the "epoch").
In other systems, the meaning is not specified,
and the number returned by <code>time</code> can be used only as an argument to
-<code>date</code> and <code>difftime</code>.
+<a href="#pdf-os.date"><code>os.date</code></a> and <a href="#pdf-os.difftime"><code>os.difftime</code></a>.
@@ -9421,9 +9577,9 @@ which automatically removes the file when the program ends.
<p>
This library provides
-the functionality of the debug interface to Lua programs.
+the functionality of the debug interface (<a href="#4.9">&sect;4.9</a>) to Lua programs.
You should exert care when using this library.
-Several of these functions
+Several of its functions
violate basic assumptions about Lua code
(e.g., that variables local to a function
cannot be accessed from outside;
@@ -9458,7 +9614,7 @@ so that the caller continues its execution.
<p>
Note that commands for <code>debug.debug</code> are not lexically nested
-within any function, and so have no direct access to local variables.
+within any function and so have no direct access to local variables.
@@ -9477,20 +9633,20 @@ and the current hook count
<p>
-<hr><h3><a name="pdf-debug.getinfo"><code>debug.getinfo ([thread,] function [, what])</code></a></h3>
+<hr><h3><a name="pdf-debug.getinfo"><code>debug.getinfo ([thread,] f [, what])</code></a></h3>
<p>
Returns a table with information about a function.
-You can give the function directly,
-or you can give a number as the value of <code>function</code>,
-which means the function running at level <code>function</code> of the call stack
+You can give the function directly
+or you can give a number as the value of <code>f</code>,
+which means the function running at level <code>f</code> of the call stack
of the given thread:
level&nbsp;0 is the current function (<code>getinfo</code> itself);
level&nbsp;1 is the function that called <code>getinfo</code>
(except for tail calls, which do not count on the stack);
and so on.
-If <code>function</code> is a number larger than the number of active functions,
+If <code>f</code> is a number larger than the number of active functions,
then <code>getinfo</code> returns <b>nil</b>.
@@ -9554,11 +9710,11 @@ In that case, <code>getlocal</code> returns only the name of function parameters
<p>
-<hr><h3><a name="pdf-debug.getmetatable"><code>debug.getmetatable (object)</code></a></h3>
+<hr><h3><a name="pdf-debug.getmetatable"><code>debug.getmetatable (value)</code></a></h3>
<p>
-Returns the metatable of the given <code>object</code>
+Returns the metatable of the given <code>value</code>
or <b>nil</b> if it does not have a metatable.
@@ -9575,12 +9731,12 @@ Returns the registry table (see <a href="#4.5">&sect;4.5</a>).
<p>
-<hr><h3><a name="pdf-debug.getupvalue"><code>debug.getupvalue (func, up)</code></a></h3>
+<hr><h3><a name="pdf-debug.getupvalue"><code>debug.getupvalue (f, up)</code></a></h3>
<p>
This function returns the name and the value of the upvalue
-with index <code>up</code> of the function <code>func</code>.
+with index <code>up</code> of the function <code>f</code>.
The function returns <b>nil</b> if there is no upvalue with the given index.
@@ -9662,24 +9818,24 @@ variable indices and names.
<p>
-<hr><h3><a name="pdf-debug.setmetatable"><code>debug.setmetatable (object, table)</code></a></h3>
+<hr><h3><a name="pdf-debug.setmetatable"><code>debug.setmetatable (value, table)</code></a></h3>
<p>
-Sets the metatable for the given <code>object</code> to the given <code>table</code>
+Sets the metatable for the given <code>value</code> to the given <code>table</code>
(which can be <b>nil</b>).
-Returns <code>object</code>.
+Returns <code>value</code>.
<p>
-<hr><h3><a name="pdf-debug.setupvalue"><code>debug.setupvalue (func, up, value)</code></a></h3>
+<hr><h3><a name="pdf-debug.setupvalue"><code>debug.setupvalue (f, up, value)</code></a></h3>
<p>
This function assigns the value <code>value</code> to the upvalue
-with index <code>up</code> of the function <code>func</code>.
+with index <code>up</code> of the function <code>f</code>.
The function returns <b>nil</b> if there is no upvalue
with the given index.
Otherwise, it returns the name of the upvalue.
@@ -9723,7 +9879,7 @@ to start the traceback
<p>
-<hr><h3><a name="pdf-debug.upvalueid"><code>debug.upvalueid (function, n)</code></a></h3>
+<hr><h3><a name="pdf-debug.upvalueid"><code>debug.upvalueid (f, n)</code></a></h3>
<p>
@@ -9743,12 +9899,12 @@ will return identical ids for those upvalue indices.
<p>
-<hr><h3><a name="pdf-debug.upvaluejoin"><code>debug.upvaluejoin (func1, n1, func2, n2)</code></a></h3>
+<hr><h3><a name="pdf-debug.upvaluejoin"><code>debug.upvaluejoin (f1, n1, f2, n2)</code></a></h3>
<p>
-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>.
+Make the <code>n1</code>-th upvalue of the Lua closure <code>f1</code>
+refer to the <code>n2</code>-th upvalue of the Lua closure <code>f2</code>.
@@ -9779,6 +9935,7 @@ The options are:
<li><b><code>-l <em>mod</em></code>: </b> "requires" <em>mod</em>;</li>
<li><b><code>-i</code>: </b> enters interactive mode after running <em>script</em>;</li>
<li><b><code>-v</code>: </b> prints version information;</li>
+<li><b><code>-E</code>: </b> ignores environment variables;</li>
<li><b><code>--</code>: </b> stops handling options;</li>
<li><b><code>-</code>: </b> executes <code>stdin</code> as a file and stops handling options.</li>
</ul><p>
@@ -9791,24 +9948,34 @@ and as <code>lua -</code> otherwise.
<p>
-Before running any argument,
+When called without option <code>-E</code>,
the interpreter checks for an environment variable <a name="pdf-LUA_INIT_5_2"><code>LUA_INIT_5_2</code></a>
-(or <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a> if it is not defined).
-If its format is <code>@<em>filename</em></code>,
+(or <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a> if it is not defined)
+before running any argument.
+If the variable content has the format <code>@<em>filename</em></code>,
then <code>lua</code> executes the file.
Otherwise, <code>lua</code> executes the string itself.
<p>
-All options are handled in order, except <code>-i</code>.
+When called with option <code>-E</code>,
+besides ignoring <code>LUA_INIT</code>,
+the interpreter also resets the values of
+<a href="#pdf-package.path"><code>package.path</code></a> and <a href="#pdf-package.cpath"><code>package.cpath</code></a>
+with the default paths defined in <code>luaconf.h</code>,
+in effect ignoring the values of <code>LUA_PATH</code> and <code>LUA_CPATH</code>.
+
+
+<p>
+All options are handled in order, except <code>-i</code> and <code>-E</code>.
For instance, an invocation like
<pre>
$ lua -e'a=1' -e 'print(a)' script.lua
</pre><p>
-will first set <code>a</code> to 1, then print the value of <code>a</code> (which is '<code>1</code>'),
+will first set <code>a</code> to 1, then print the value of <code>a</code>,
and finally run the file <code>script.lua</code> with no arguments.
-(Here <code>$</code> is the shell prompt. Your prompt can be different.)
+(Here <code>$</code> is the shell prompt. Your prompt may be different.)
<p>
@@ -9835,7 +10002,7 @@ then creates a table
[1] = "t1", [2] = "t2" }
</pre><p>
and finally runs the file <code>b.lua</code>.
-The script is called with <code>arg[1]</code>, <code>arg[2]</code>, &middot;&middot;&middot;
+The script is called with <code>arg[1]</code>, <code>arg[2]</code>, ...
as arguments;
it can also access these arguments with the vararg expression '<code>...</code>'.
@@ -9862,29 +10029,8 @@ the interpreter does not report the error.
When finishing normally,
the interpreter closes its main Lua state
(see <a href="#lua_close"><code>lua_close</code></a>).
-The script can avoid this step by terminating
-through <a href="#pdf-os.exit"><code>os.exit</code></a>.
-
-
-<p>
-If the global variable <a name="pdf-_PROMPT"><code>_PROMPT</code></a> contains a string,
-then its value is used as the prompt.
-Similarly, if the global variable <a name="pdf-_PROMPT2"><code>_PROMPT2</code></a> contains a string,
-its value is used as the secondary prompt
-(issued during incomplete statements).
-Therefore, both prompts can be changed directly on the command line
-or in any Lua programs by assigning to <code>_PROMPT</code>.
-See the next example:
-
-<pre>
- $ lua -e"_PROMPT='myprompt&gt; '" -i
-</pre><p>
-(The outer pair of quotes is for the shell,
-the inner pair is for Lua.)
-Note the use of <code>-i</code> to enter interactive mode;
-otherwise,
-the program would just end silently
-right after the assignment to <code>_PROMPT</code>.
+The script can avoid this step by
+calling <a href="#pdf-os.exit"><code>os.exit</code></a> to terminate.
<p>
@@ -9900,7 +10046,7 @@ as in
#!/usr/local/bin/lua
</pre><p>
(Of course,
-the location of the Lua interpreter can be different in your machine.
+the location of the Lua interpreter may be different in your machine.
If <code>lua</code> is in your <code>PATH</code>,
then
@@ -9914,9 +10060,9 @@ is a more portable solution.)
<h1>8 &ndash; <a name="8">Incompatibilities with the Previous Version</a></h1>
<p>
-Here we list the incompatibilities that you can find when moving a program
+Here we list the incompatibilities that you may find when moving a program
from Lua&nbsp;5.1 to Lua&nbsp;5.2.
-You can avoid some incompatibilities compiling Lua with
+You can avoid some incompatibilities by compiling Lua with
appropriate options (see file <code>luaconf.h</code>).
However,
all these compatibility options will be removed in the next version of Lua.
@@ -9934,7 +10080,7 @@ use the variable <code>_ENV</code> or the function <a href="#pdf-load"><code>loa
<p>
-C functions do not have environments any more.
+C functions no longer have environments.
Use an upvalue with a shared table if you need to keep
shared state among several C functions.
(You may use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> to open a C library
@@ -9964,8 +10110,8 @@ Weak tables with weak keys now perform like <em>ephemeron tables</em>.
<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 debugger can know there will
-not be a corresponding return event.
+<em>tail call</em>, so that the debugger can know that
+there will not be a corresponding return event.
</li>
<li>
@@ -9985,8 +10131,8 @@ observable difference to the new function.
<li>
Function <code>module</code> is deprecated.
-Modules are not expected to set global variables anymore,
-and it is easy to set up a module with regular Lua code.
+It is easy to set up a module with regular Lua code.
+Modules are not expected to set global variables.
</li>
<li>
@@ -10036,12 +10182,17 @@ So, all functions that load code
(<a href="#pdf-load"><code>load</code></a> and <a href="#pdf-loadfile"><code>loadfile</code></a>)
are potentially insecure when loading untrusted binary data.
(Actually, those functions were already insecure because
-of bugs in the verification algorithm.)
+of flaws in the verification algorithm.)
When in doubt,
use the <code>mode</code> argument in function <a href="#pdf-load"><code>load</code></a>
to restrict it to loading textual chunks.
</li>
+<li>
+The standard paths in the official distribution may
+change between versions.
+</li>
+
</ul>
@@ -10060,13 +10211,12 @@ You must get the global environment from the registry
Pseudoindex <code>LUA_ENVIRONINDEX</code>
and functions <code>lua_getfenv</code>/<code>lua_setfenv</code>
were removed,
-as C&nbsp;functions do not have environments any more.
+as C&nbsp;functions no longer have environments.
</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.
+Use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> so that your module does not create globals.
(Modules are not expected to set global variables anymore.)
</li>
@@ -10081,7 +10231,7 @@ the block is new.
<li>
Finalizers (<code>__gc</code> metamethods) for userdata are called in the
-reverse order that they were marked,
+reverse order that they were marked for finalization,
not that they were created (see <a href="#2.5.1">&sect;2.5.1</a>).
(Most userdata are marked immediately after they are created.)
Moreover,
@@ -10202,10 +10352,10 @@ Here is the complete syntax of Lua in extended BNF.
<HR>
<SMALL CLASS="footer">
Last update:
-Fri Jul 8 17:11:02 BRT 2011
+Thu Nov 24 11:54:31 BRST 2011
</SMALL>
<!--
-Last change: revised for Lua 5.2.0 (beta)
+Last change: revised for Lua 5.2.0
-->
</body></html>
diff --git a/doc/readme.html b/doc/readme.html
index 5cb41d49..f0c77a16 100644
--- a/doc/readme.html
+++ b/doc/readme.html
@@ -6,18 +6,21 @@
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
<STYLE TYPE="text/css">
blockquote, .display {
- color: black ;
- padding: 8px ;
border: solid #a0a0a0 2px ;
- xbackground-color: #EFEFFF ;
- margin-left: 0px ;
+ padding: 1em ;
+ margin: 0px ;
+}
+
+.display {
+ word-spacing: 0.25em ;
+}
+
+dl.display dd {
+ padding-bottom: 0.2em ;
}
tt, kbd, code {
- font-size: 120% ;
- xcolor: black ;
- xpadding: 4px ;
- xbackground-color: #E0E0E0 ;
+ font-size: 12pt ;
}
</STYLE>
</HEAD>
@@ -27,15 +30,10 @@ 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 (beta)
+Welcome to Lua 5.2
</H1>
<P>
-<IMG SRC="alert.png" ALIGN="absbottom" ALT="[!]">
-<EM>This is a beta version of Lua 5.2.
-Some details may change in the final version.</EM>
-
-<P>
<A HREF="#about">about</A>
&middot;
<A HREF="#install">installation</A>
@@ -86,7 +84,7 @@ form.
You need to build it before using it.
Building Lua should be straightforward
because
-Lua is implemented in pure ANSI C, and compiles unmodified in all known
+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++.
The instructions given below for building Lua are for Unix-like platforms.
@@ -120,15 +118,16 @@ Here are the details.
<OL>
<LI>
Open a terminal window and move to
-the top-level directory, which is named lua-5.2.0.
+the top-level directory, which is named <TT>lua-5.2.0</TT>.
The Makefile there controls both the build process and the installation process.
<P>
<LI>
Do "<KBD>make</KBD>" and see if your platform is listed.
The platforms currently supported are:
-<BLOCKQUOTE>
- aix ansi bsd freebsd generic linux macosx mingw posix solaris
-</BLOCKQUOTE>
+<P>
+<P CLASS="display">
+ aix ansi bsd freebsd generic linux macosx mingw posix solaris
+</P>
<P>
If your platform is listed, just do "<KBD>make xxx</KBD>", where xxx
is your platform name.
@@ -138,7 +137,7 @@ The Makefile there controls both the build process and the installation process.
<P>
<LI>
The compilation takes only a few moments
-and produces three files in the src directory:
+and produces three files in the <TT>src</TT> directory:
lua (the interpreter),
luac (the compiler),
and liblua.a (the library).
@@ -147,12 +146,15 @@ and liblua.a (the library).
To check that Lua has been built correctly, do "<KBD>make test</KBD>"
after building Lua. This will run the interpreter and print its version string.
</OL>
+<P>
+If you're running Linux and get compilation errors,
+make sure you have installed the <TT>readline</TT> development package.
<H3>Installing Lua</H3>
<P>
Once you have built Lua, you may want to install it in an official
place in your system. In this case, do "<KBD>make install</KBD>". The official
- place and the way to install files are defined in Makefile. You'll
+ place and the way to install files are defined in the Makefile. You'll
probably need the right permissions to install files.
<P>
@@ -198,9 +200,9 @@ and liblua.a (the library).
<P>
Three kinds of things can be customized by editing a file:
<UL>
- <LI> Where and how to install Lua &mdash; edit Makefile.
- <LI> How to build Lua &mdash; edit src/Makefile.
- <LI> Lua features &mdash; edit src/luaconf.h.
+ <LI> Where and how to install Lua &mdash; edit <TT>Makefile</TT>.
+ <LI> How to build Lua &mdash; edit <TT>src/Makefile</TT>.
+ <LI> Lua features &mdash; edit <TT>src/luaconf.h</TT>.
</UL>
<P>
@@ -211,13 +213,13 @@ and liblua.a (the library).
<P>
On the other hand, if you need to customize some Lua features, you'll need
- to edit src/luaconf.h before building and installing Lua.
+ to edit <TT>src/luaconf.h</TT> before building and installing Lua.
The edited file will be the one installed, and
it will be used by any Lua clients that you build, to ensure consistency.
Further customization is available to experts by editing the Lua sources.
<P>
- We strongly recommend that you enable dynamic loading in src/luaconf.h.
+ We strongly recommend that you enable dynamic loading in <TT>src/luaconf.h</TT>.
This is done automatically for all platforms listed above that have
this feature and also for Windows.
@@ -238,7 +240,6 @@ lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c
ltm.c lundump.c lvm.c lzio.c
lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c
lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c
-
<DT>
interpreter:
<DD>
@@ -257,11 +258,11 @@ compiler:
those dynamic libraries &mdash; but <EM>don't</EM> link the Lua library
into each dynamic library. For Unix, we recommend that the Lua library
be linked statically into the host program and its symbols exported for
- dynamic linking; src/Makefile does this for the Lua interpreter.
+ dynamic linking; <TT>src/Makefile</TT> does this for the Lua interpreter.
For Windows, we recommend that the Lua library be a DLL.
<P>
- As mentioned above, you may edit src/luaconf.h to customize
+ As mentioned above, you may edit <TT>src/luaconf.h</TT> to customize
some features before building Lua.
<H2><A NAME="changes">Changes since Lua 5.1</A></H2>
@@ -290,7 +291,7 @@ Here are the other changes introduced in Lua 5.2:
<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> hex and <CODE>\z</CODE> escapes in strings
<LI> support for hexadecimal floats
<LI> order metamethods work for different types
<LI> no more verification of opcode consistency
@@ -302,8 +303,8 @@ Here are the other changes introduced in Lua 5.2:
<H3>Libraries</H3>
<UL>
<LI> arguments for function called through <CODE>xpcall</CODE>
-<LI> optional 'mode' argument to load (to control binary x text)
-<LI> optional 'env' argument to load (environment for loaded chunk)
+<LI> optional 'mode' argument to load and loadfile (to control binary x text)
+<LI> optional 'env' argument to load and loadfile (environment for loaded chunk)
<LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL)
<LI> new function <CODE>package.searchpath</CODE>
<LI> modules receive their paths when loaded
@@ -324,15 +325,23 @@ Here are the other changes introduced in Lua 5.2:
<H3>C API</H3>
<UL>
<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_checkversion</CODE>
+<LI> new functions
+<CODE>lua_absindex</CODE>,
+<CODE>lua_arith</CODE>,
+<CODE>lua_compare</CODE>,
+<CODE>lua_copy</CODE>,
+<CODE>lua_len</CODE>,
+<CODE>lua_rawgetp</CODE>,
+<CODE>lua_rawsetp</CODE>,
+<CODE>lua_upvalueid</CODE>,
+<CODE>lua_upvaluejoin</CODE>,
+<CODE>lua_version</CODE>.
+<LI> new functions
+<CODE>luaL_checkversion</CODE>,
+<CODE>luaL_setmetatable</CODE>,
+<CODE>luaL_testudata</CODE>,
+<CODE>luaL_tolstring</CODE>.
<LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string
-<LI> new <CODE>luaL_testudata</CODE> and <CODE>luaL_setmetatable</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>isvararg</CODE> available in debug API
<LI> new <CODE>lua_Unsigned</CODE>
</UL>
@@ -340,15 +349,17 @@ Here are the other changes introduced in Lua 5.2:
<H3>Implementation</H3>
<UL>
<LI> max constants per function raised to 2<SUP>26</SUP>
+<LI> generational mode for garbage collection (experimental)
+<LI> NaN trick (experimental)
<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)
-<LI> NaN trick (experimental)
+</UL>
+
+<H3>Lua standalone interpreter</H3>
+<UL>
+<LI> new <CODE>-E</CODE> option to avoid environment variables
+<LI> handling of non-string error messages
</UL>
<H2><A NAME="license">License</A></H2>
@@ -369,7 +380,7 @@ then you should give us credit by including the appropriate copyright notice som
For details, see
<A HREF="http://www.lua.org/license.html">this</A>.
-<BLOCKQUOTE>
+<BLOCKQUOTE STYLE="padding-bottom: 0em">
Copyright &copy; 1994&ndash;2011 Lua.org, PUC-Rio.
<P>
@@ -393,14 +404,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
</BLOCKQUOTE>
+<P>
<HR>
<SMALL CLASS="footer">
Last update:
-Fri Jun 24 11:30:57 BRT 2011
+Wed Nov 23 16:17:22 BRST 2011
</SMALL>
<!--
-Last change: revised for Lua 5.2.0 (beta)
+Last change: revised for Lua 5.2.0
-->
</BODY>
diff --git a/src/Makefile b/src/Makefile
index a77f35db..bba1693f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -112,6 +112,7 @@ mingw:
$(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \
"AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
"SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
+ $(MAKE) "LUAC_T=luac.exe" luac.exe
posix:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
diff --git a/src/lapi.c b/src/lapi.c
index 7761419e..5437fb0c 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.149 2011/06/13 14:13:06 roberto Exp $
+** $Id: lapi.c,v 2.157 2011/11/16 18:51:36 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -34,9 +34,13 @@ const char lua_ident[] =
"$LuaAuthors: " LUA_AUTHORS " $";
+/* value at a non-valid index */
+#define NONVALIDVALUE cast(TValue *, luaO_nilobject)
-#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject, \
- "invalid index")
+/* corresponding test */
+#define isvalid(o) ((o) != luaO_nilobject)
+
+#define api_checkvalidindex(L, i) api_check(L, isvalid(i), "invalid index")
static TValue *index2addr (lua_State *L, int idx) {
@@ -44,7 +48,7 @@ static TValue *index2addr (lua_State *L, int idx) {
if (idx > 0) {
TValue *o = ci->func + idx;
api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
- if (o >= L->top) return cast(TValue *, luaO_nilobject);
+ if (o >= L->top) return NONVALIDVALUE;
else return o;
}
else if (idx > LUA_REGISTRYINDEX) {
@@ -57,12 +61,10 @@ static TValue *index2addr (lua_State *L, int idx) {
idx = LUA_REGISTRYINDEX - idx;
api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
if (ttislcf(ci->func)) /* light C function? */
- return cast(TValue *, luaO_nilobject); /* it has no upvalues */
+ return NONVALIDVALUE; /* it has no upvalues */
else {
CClosure *func = clCvalue(ci->func);
- return (idx <= func->nupvalues)
- ? &func->upvalue[idx-1]
- : cast(TValue *, luaO_nilobject);
+ return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
}
}
}
@@ -237,7 +239,7 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
LUA_API int lua_type (lua_State *L, int idx) {
StkId o = index2addr(L, idx);
- return (o == luaO_nilobject) ? LUA_TNONE : ttypenv(o);
+ return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
}
@@ -275,8 +277,7 @@ LUA_API int lua_isuserdata (lua_State *L, int idx) {
LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
StkId o1 = index2addr(L, index1);
StkId o2 = index2addr(L, index2);
- return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
- : luaV_rawequalobj(o1, o2);
+ return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
}
@@ -305,17 +306,17 @@ LUA_API void lua_arith (lua_State *L, int op) {
LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
StkId o1, o2;
- int i;
+ int i = 0;
lua_lock(L); /* may call tag method */
o1 = index2addr(L, index1);
o2 = index2addr(L, index2);
- if (o1 == luaO_nilobject || o2 == luaO_nilobject)
- i = 0;
- else switch (op) {
- case LUA_OPEQ: i = equalobj(L, o1, o2); break;
- case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
- case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
- default: api_check(L, 0, "invalid option"); i = 0;
+ if (isvalid(o1) && isvalid(o2)) {
+ switch (op) {
+ case LUA_OPEQ: i = equalobj(L, o1, o2); break;
+ case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
+ case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
+ default: api_check(L, 0, "invalid option");
+ }
}
lua_unlock(L);
return i;
@@ -595,6 +596,17 @@ LUA_API int lua_pushthread (lua_State *L) {
*/
+LUA_API void lua_getglobal (lua_State *L, const char *var) {
+ Table *reg = hvalue(&G(L)->l_registry);
+ const TValue *gt; /* global table */
+ lua_lock(L);
+ gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+ setsvalue2s(L, L->top++, luaS_new(L, var));
+ luaV_gettable(L, gt, L->top - 1, L->top - 1);
+ lua_unlock(L);
+}
+
+
LUA_API void lua_gettable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
@@ -628,11 +640,24 @@ LUA_API void lua_rawget (lua_State *L, int idx) {
LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
- StkId o;
+ StkId t;
lua_lock(L);
- o = index2addr(L, idx);
- api_check(L, ttistable(o), "table expected");
- setobj2s(L, L->top, luaH_getint(hvalue(o), n));
+ t = index2addr(L, idx);
+ api_check(L, ttistable(t), "table expected");
+ setobj2s(L, L->top, luaH_getint(hvalue(t), n));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) {
+ StkId t;
+ TValue k;
+ lua_lock(L);
+ t = index2addr(L, idx);
+ api_check(L, ttistable(t), "table expected");
+ setpvalue(&k, cast(void *, p));
+ setobj2s(L, L->top, luaH_get(hvalue(t), &k));
api_incr_top(L);
lua_unlock(L);
}
@@ -700,6 +725,19 @@ LUA_API void lua_getuservalue (lua_State *L, int idx) {
*/
+LUA_API void lua_setglobal (lua_State *L, const char *var) {
+ Table *reg = hvalue(&G(L)->l_registry);
+ const TValue *gt; /* global table */
+ lua_lock(L);
+ api_checknelems(L, 1);
+ gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+ setsvalue2s(L, L->top++, luaS_new(L, var));
+ luaV_settable(L, gt, L->top - 1, L->top - 2);
+ L->top -= 2; /* pop value and key */
+ lua_unlock(L);
+}
+
+
LUA_API void lua_settable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
@@ -732,6 +770,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
t = index2addr(L, idx);
api_check(L, ttistable(t), "table expected");
setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
+ invalidateTMcache(hvalue(t));
luaC_barrierback(L, gcvalue(t), L->top-1);
L->top -= 2;
lua_unlock(L);
@@ -739,13 +778,28 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
- StkId o;
+ StkId t;
lua_lock(L);
api_checknelems(L, 1);
- o = index2addr(L, idx);
- api_check(L, ttistable(o), "table expected");
- setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1);
- luaC_barrierback(L, gcvalue(o), L->top-1);
+ t = index2addr(L, idx);
+ api_check(L, ttistable(t), "table expected");
+ luaH_setint(L, hvalue(t), n, L->top - 1);
+ luaC_barrierback(L, gcvalue(t), L->top-1);
+ L->top--;
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
+ StkId t;
+ TValue k;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ t = index2addr(L, idx);
+ api_check(L, ttistable(t), "table expected");
+ setpvalue(&k, cast(void *, p));
+ setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
+ luaC_barrierback(L, gcvalue(t), L->top - 1);
L->top--;
lua_unlock(L);
}
@@ -1128,7 +1182,6 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
-
static const char *aux_upvalue (StkId fi, int n, TValue **val,
GCObject **owner) {
switch (ttype(fi)) {
@@ -1141,15 +1194,13 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
}
case LUA_TLCL: { /* Lua closure */
LClosure *f = clLvalue(fi);
- const char *name;
+ TString *name;
Proto *p = f->p;
if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
*val = f->upvals[n-1]->v;
if (owner) *owner = obj2gco(f->upvals[n - 1]);
- name = getstr(p->upvalues[n-1].name);
- if (name == NULL) /* no debug information? */
- name = "";
- return name;
+ name = p->upvalues[n-1].name;
+ return (name == NULL) ? "" : getstr(name);
}
default: return NULL; /* not a closure */
}
@@ -1158,7 +1209,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
const char *name;
- TValue *val;
+ TValue *val = NULL; /* initialized to avoid warnings */
lua_lock(L);
name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
if (name) {
@@ -1172,8 +1223,8 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
const char *name;
- TValue *val;
- GCObject *owner;
+ TValue *val = NULL; /* initialized to avoid warnings */
+ GCObject *owner = NULL; /* initialized to avoid warnings */
StkId fi;
lua_lock(L);
fi = index2addr(L, funcindex);
diff --git a/src/lauxlib.c b/src/lauxlib.c
index b765cfdd..d61a8ef8 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.233 2011/06/16 14:11:04 roberto Exp $
+** $Id: lauxlib.c,v 1.236 2011/11/14 17:10:24 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -41,11 +41,10 @@
** return 1 + string at top if find a good name.
*/
static int findfield (lua_State *L, int objidx, int level) {
- int found = 0;
if (level == 0 || !lua_istable(L, -1))
return 0; /* not found */
lua_pushnil(L); /* start 'next' loop */
- while (!found && lua_next(L, -2)) { /* for each pair in table */
+ while (lua_next(L, -2)) { /* for each pair in table */
if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
if (lua_rawequal(L, objidx, -1)) { /* found object? */
lua_pop(L, 1); /* remove value (but keep name) */
@@ -86,7 +85,7 @@ static void pushfuncname (lua_State *L, lua_Debug *ar) {
lua_pushfstring(L, "function " LUA_QS, ar->name);
else if (*ar->what == 'm') /* main? */
lua_pushfstring(L, "main chunk");
- else if (*ar->what == 'C' || *ar->what == 't') {
+ else if (*ar->what == 'C') {
if (pushglobalfuncname(L, ar)) {
lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
lua_remove(L, -2); /* remove name */
@@ -331,7 +330,9 @@ LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
- if (!lua_checkstack(L, space)) {
+ /* keep some extra space to run error routines, if needed */
+ const int extra = LUA_MINSTACK;
+ if (!lua_checkstack(L, space + extra)) {
if (msg)
luaL_error(L, "stack overflow (%s)", msg);
else
@@ -591,6 +592,16 @@ static int errfile (lua_State *L, const char *what, int fnameindex) {
}
+static int checkmode (lua_State *L, const char *mode, const char *x) {
+ if (mode && strchr(mode, x[0]) == NULL) {
+ lua_pushfstring(L,
+ "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode);
+ return LUA_ERRFILE;
+ }
+ else return LUA_OK;
+}
+
+
static int skipBOM (LoadF *lf) {
const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */
int c;
@@ -623,7 +634,8 @@ static int skipcomment (LoadF *lf, int *cp) {
}
-LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
+LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
+ const char *mode) {
LoadF lf;
int status, readstatus;
int c;
@@ -639,14 +651,23 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
}
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);
- skipcomment(&lf, &c); /* re-read initial portion */
+ if (c == LUA_SIGNATURE[0]) { /* binary file? */
+ if ((status = checkmode(L, mode, "binary")) != LUA_OK)
+ goto closefile;
+ if (filename) {
+ lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
+ if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
+ skipcomment(&lf, &c); /* re-read initial portion */
+ }
+ }
+ else { /* text file */
+ if ((status = checkmode(L, mode, "text")) != LUA_OK)
+ goto closefile;
}
if (c != EOF)
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
status = lua_load(L, getF, &lf, lua_tostring(L, -1));
+ closefile:
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
diff --git a/src/lauxlib.h b/src/lauxlib.h
index a7aa0d76..48b1afa0 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.117 2011/06/16 14:10:12 roberto Exp $
+** $Id: lauxlib.h,v 1.119 2011/11/14 17:10:24 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -72,7 +72,11 @@ LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
-LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
+LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
+ const char *mode);
+
+#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL)
+
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
@@ -163,6 +167,31 @@ LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
/* }====================================================== */
+
+/*
+** {======================================================
+** File handles for IO library
+** =======================================================
+*/
+
+/*
+** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
+** initial structure 'luaL_Stream' (it may contain other fields
+** after that initial structure).
+*/
+
+#define LUA_FILEHANDLE "FILE*"
+
+
+typedef struct luaL_Stream {
+ FILE *f; /* stream (NULL for incompletely created streams) */
+ lua_CFunction closef; /* to close stream (NULL for closed streams) */
+} luaL_Stream;
+
+/* }====================================================== */
+
+
+
/* compatibility with old module system */
#if defined(LUA_COMPAT_MODULE)
diff --git a/src/lbaselib.c b/src/lbaselib.c
index e4daf5d4..472a96c8 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.264 2011/07/05 12:49:35 roberto Exp $
+** $Id: lbaselib.c,v 1.270 2011/11/23 17:29:04 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -46,20 +46,22 @@ static int luaB_print (lua_State *L) {
#define SPACECHARS " \f\n\r\t\v"
static int luaB_tonumber (lua_State *L) {
- int base = luaL_optint(L, 2, 10);
- luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
- if (base == 10) { /* standard conversion */
- luaL_checkany(L, 1);
- if (lua_isnumber(L, 1)) {
- lua_pushnumber(L, lua_tonumber(L, 1));
+ if (lua_isnoneornil(L, 2)) { /* standard conversion */
+ int isnum;
+ lua_Number n = lua_tonumberx(L, 1, &isnum);
+ if (isnum) {
+ lua_pushnumber(L, n);
return 1;
- } /* else not a number */
+ } /* else not a number; must be something */
+ luaL_checkany(L, 1);
}
else {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
const char *e = s + l; /* end point for 's' */
+ int base = luaL_checkint(L, 2);
int neg = 0;
+ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
s += strspn(s, SPACECHARS); /* skip initial spaces */
if (*s == '-') { s++; neg = 1; } /* handle signal */
else if (*s == '+') s++;
@@ -158,7 +160,7 @@ 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",
- "setmajorinc", "isrunning", "gen", "inc", NULL};
+ "setmajorinc", "isrunning", "generational", "incremental", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
@@ -253,7 +255,14 @@ static int load_aux (lua_State *L, int status) {
static int luaB_loadfile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
- return load_aux(L, luaL_loadfile(L, fname));
+ const char *mode = luaL_optstring(L, 2, NULL);
+ int env = !lua_isnone(L, 3); /* 'env' parameter? */
+ int status = luaL_loadfilex(L, fname, mode);
+ if (status == LUA_OK && env) { /* 'env' parameter? */
+ lua_pushvalue(L, 3);
+ lua_setupvalue(L, -2, 1); /* set it as 1st upvalue of loaded chunk */
+ }
+ return load_aux(L, status);
}
@@ -265,7 +274,6 @@ static int luaB_loadfile (lua_State *L) {
typedef struct {
-char c;
const char *mode;
} loaddata;
@@ -276,11 +284,11 @@ char c;
** pushed on the stack) in case of errors.
*/
static const char *checkrights (lua_State *L, const char *mode, const char *s) {
- if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0])
- return lua_pushstring(L, "attempt to load a binary chunk");
- if (strchr(mode, 't') == NULL && *s != LUA_SIGNATURE[0])
- return lua_pushstring(L, "attempt to load a text chunk");
- return NULL; /* chunk in allowed format */
+ const char *x = (*s == LUA_SIGNATURE[0]) ? "binary" : "text";
+ if (strchr(mode, x[0]) == NULL)
+ return lua_pushfstring(L,
+ "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode);
+ else return NULL;
}
@@ -390,27 +398,32 @@ static int luaB_select (lua_State *L) {
}
-static int pcallcont (lua_State *L) {
- int errfunc = 0; /* =0 to avoid warnings */
- int status = lua_getctx(L, &errfunc);
- lua_assert(status != LUA_OK);
- lua_pushboolean(L, (status == LUA_YIELD)); /* first result (status) */
- if (errfunc) /* came from xpcall? */
- lua_replace(L, 1); /* put first result in place of error function */
- else /* came from pcall */
- lua_insert(L, 1); /* open space for first result */
+static int finishpcall (lua_State *L, int status) {
+ if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */
+ lua_settop(L, 0); /* create space for return values */
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, "stack overflow");
+ return 2; /* return false, msg */
+ }
+ lua_pushboolean(L, status); /* first result (status) */
+ lua_replace(L, 1); /* put first result in first slot */
return lua_gettop(L);
}
+static int pcallcont (lua_State *L) {
+ int status = lua_getctx(L, NULL);
+ return finishpcall(L, (status == LUA_YIELD));
+}
+
+
static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
- status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, pcallcont);
- luaL_checkstack(L, 1, NULL);
- lua_pushboolean(L, (status == LUA_OK));
- lua_insert(L, 1);
- return lua_gettop(L); /* return status + all results */
+ lua_pushnil(L);
+ lua_insert(L, 1); /* create space for status result */
+ status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
+ return finishpcall(L, (status == LUA_OK));
}
@@ -421,11 +434,8 @@ static int luaB_xpcall (lua_State *L) {
lua_pushvalue(L, 1); /* exchange function... */
lua_copy(L, 2, 1); /* ...and error handler */
lua_replace(L, 2);
- status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 1, pcallcont);
- luaL_checkstack(L, 1, NULL);
- lua_pushboolean(L, (status == LUA_OK));
- lua_replace(L, 1);
- return lua_gettop(L); /* return status + all results */
+ status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
+ return finishpcall(L, (status == LUA_OK));
}
diff --git a/src/lcode.c b/src/lcode.c
index 00966a12..614e452f 100644
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 2.56 2011/05/31 18:27:56 roberto Exp $
+** $Id: lcode.c,v 2.60 2011/08/30 16:26:41 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -44,8 +44,8 @@ void luaK_nil (FuncState *fs, int from, int n) {
int pl = pfrom + GETARG_B(*previous);
if ((pfrom <= from && from <= pl + 1) ||
(from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
- if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
- if (pl > l) l = pl; /* l = max(l, pl) */
+ if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
+ if (pl > l) l = pl; /* l = max(l, pl) */
SETARG_A(*previous, from);
SETARG_B(*previous, l - from);
return;
@@ -213,11 +213,11 @@ static int luaK_code (FuncState *fs, Instruction i) {
Proto *f = fs->f;
dischargejpc(fs); /* `pc' will change */
/* put new instruction in code array */
- luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
+ luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
MAX_INT, "opcodes");
f->code[fs->pc] = i;
/* save corresponding line information */
- luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
+ luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
MAX_INT, "opcodes");
f->lineinfo[fs->pc] = fs->ls->lastline;
return fs->pc++;
@@ -289,7 +289,7 @@ static void freeexp (FuncState *fs, expdesc *e) {
static int addk (FuncState *fs, TValue *key, TValue *v) {
- lua_State *L = fs->L;
+ lua_State *L = fs->ls->L;
TValue *idx = luaH_set(L, fs->h, key);
Proto *f = fs->f;
int k, oldsize;
@@ -304,6 +304,8 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
/* constant not found; create a new entry */
oldsize = f->sizek;
k = fs->nk;
+ /* numerical value does not need GC barrier;
+ table has no metatable, so it does not need to invalidate cache */
setnvalue(idx, cast_num(k));
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
@@ -316,14 +318,14 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
int luaK_stringK (FuncState *fs, TString *s) {
TValue o;
- setsvalue(fs->L, &o, s);
+ setsvalue(fs->ls->L, &o, s);
return addk(fs, &o, &o);
}
int luaK_numberK (FuncState *fs, lua_Number r) {
int n;
- lua_State *L = fs->L;
+ lua_State *L = fs->ls->L;
TValue o;
setnvalue(&o, r);
if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
@@ -350,7 +352,7 @@ static int nilK (FuncState *fs) {
TValue k, v;
setnilvalue(&v);
/* cannot use nil as key; instead use table itself to represent nil */
- sethvalue(fs->L, &k, fs->h);
+ sethvalue(fs->ls->L, &k, fs->h);
return addk(fs, &k, &v);
}
@@ -641,7 +643,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
}
-static void luaK_goiffalse (FuncState *fs, expdesc *e) {
+void luaK_goiffalse (FuncState *fs, expdesc *e) {
int pc; /* pc of last jump */
luaK_dischargevars(fs, e);
switch (e->k) {
diff --git a/src/lcode.h b/src/lcode.h
index 26a5daaf..5a1fa9fe 100644
--- a/src/lcode.h
+++ b/src/lcode.h
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.h,v 1.57 2011/04/07 18:14:12 roberto Exp $
+** $Id: lcode.h,v 1.58 2011/08/30 16:26:41 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -62,6 +62,7 @@ LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
diff --git a/src/lcorolib.c b/src/lcorolib.c
index 981ca381..0edde26d 100644
--- a/src/lcorolib.c
+++ b/src/lcorolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcorolib.c,v 1.2 2010/07/02 11:38:13 roberto Exp $
+** $Id: lcorolib.c,v 1.3 2011/08/23 17:24:34 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
@@ -28,7 +28,7 @@ static int auxresume (lua_State *L, lua_State *co, int narg) {
return -1; /* error flag */
}
lua_xmove(L, co, narg);
- status = lua_resume(co, narg);
+ status = lua_resume(co, L, narg);
if (status == LUA_OK || status == LUA_YIELD) {
int nres = lua_gettop(co);
if (!lua_checkstack(L, nres + 1)) {
diff --git a/src/lctype.c b/src/lctype.c
index 387c93aa..55e433a5 100644
--- a/src/lctype.c
+++ b/src/lctype.c
@@ -1,9 +1,12 @@
/*
-** $Id: lctype.c,v 1.10 2011/06/24 12:25:33 roberto Exp $
+** $Id: lctype.c,v 1.11 2011/10/03 16:19:23 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
+#define lctype_c
+#define LUA_CORE
+
#include "lctype.h"
#if !LUA_USE_CTYPE /* { */
diff --git a/src/lctype.h b/src/lctype.h
index b24d9250..99c7d122 100644
--- a/src/lctype.h
+++ b/src/lctype.h
@@ -1,5 +1,5 @@
/*
-** $Id: lctype.h,v 1.11 2011/06/27 18:22:46 roberto Exp $
+** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
@@ -11,7 +11,7 @@
/*
-** WARNING: the functions defined here do not necessarily correspond
+** WARNING: the functions defined here do not necessarily correspond
** to the similar functions in the standard C ctype.h. They are
** optimized for the specific needs of Lua
*/
diff --git a/src/ldblib.c b/src/ldblib.c
index 78f6cc06..3c2f1595 100644
--- a/src/ldblib.c
+++ b/src/ldblib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldblib.c,v 1.130 2011/04/08 19:17:36 roberto Exp $
+** $Id: ldblib.c,v 1.131 2011/10/24 14:54:05 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -260,8 +260,7 @@ static void hookf (lua_State *L, lua_Debug *ar) {
static const char *const hooknames[] =
{"call", "return", "line", "count", "tail call"};
gethooktable(L);
- lua_pushlightuserdata(L, L);
- lua_rawget(L, -2);
+ lua_rawgetp(L, -1, L);
if (lua_isfunction(L, -1)) {
lua_pushstring(L, hooknames[(int)ar->event]);
if (ar->currentline >= 0)
@@ -308,9 +307,8 @@ static int db_sethook (lua_State *L) {
func = hookf; mask = makemask(smask, count);
}
gethooktable(L);
- lua_pushlightuserdata(L, L1);
lua_pushvalue(L, arg+1);
- lua_rawset(L, -3); /* set new hook */
+ lua_rawsetp(L, -2, L1); /* set new hook */
lua_pop(L, 1); /* remove hook table */
lua_sethook(L1, func, mask, count); /* set hooks */
return 0;
@@ -327,8 +325,7 @@ static int db_gethook (lua_State *L) {
lua_pushliteral(L, "external hook");
else {
gethooktable(L);
- lua_pushlightuserdata(L, L1);
- lua_rawget(L, -2); /* get hook */
+ lua_rawgetp(L, -1, L1); /* get hook */
lua_remove(L, -2); /* remove hook table */
}
lua_pushstring(L, unmakemask(mask, buff));
diff --git a/src/ldebug.c b/src/ldebug.c
index a2565cf5..786dcd04 100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.82 2011/06/02 19:31:40 roberto Exp $
+** $Id: ldebug.c,v 2.87 2011/10/07 20:45:19 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -94,6 +94,13 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
}
+static const char *upvalname (Proto *p, int uv) {
+ TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
+ if (s == NULL) return "?";
+ else return getstr(s);
+}
+
+
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams;
if (n >= ci->u.l.base - ci->func - nparams)
@@ -190,12 +197,14 @@ static void collectvalidlines (lua_State *L, Closure *f) {
}
else {
int i;
+ TValue v;
int *lineinfo = f->l.p->lineinfo;
- Table *t = luaH_new(L);
- sethvalue(L, L->top, t);
+ Table *t = luaH_new(L); /* new table to store active lines */
+ sethvalue(L, L->top, t); /* push it on stack */
incr_top(L);
- for (i=0; i<f->l.p->sizelineinfo; i++)
- setbvalue(luaH_setint(L, t, lineinfo[i]), 1);
+ setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
+ for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
+ luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
}
}
@@ -230,7 +239,11 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
break;
}
case 'n': {
- ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
+ /* calling function is a known Lua function? */
+ if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
+ ar->namewhat = getfuncname(L, ci->previous, &ar->name);
+ else
+ ar->namewhat = NULL;
if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */
ar->name = NULL;
@@ -284,17 +297,16 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
** =======================================================
*/
-static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
+static const char *getobjname (Proto *p, int lastpc, int reg,
const char **name);
/*
** find a "name" for the RK value 'c'
*/
-static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
- const char *what, const char **name) {
+static void kname (Proto *p, int pc, int c, const char **name) {
if (ISK(c)) { /* is 'c' a constant? */
- TValue *kvalue = &ci_func(ci)->p->k[INDEXK(c)];
+ TValue *kvalue = &p->k[INDEXK(c)];
if (ttisstring(kvalue)) { /* literal constant? */
*name = svalue(kvalue); /* it is its own name */
return;
@@ -302,8 +314,7 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
/* else no reasonable name found */
}
else { /* 'c' is a register */
- if (c != oreg) /* not the original register? */
- what = getobjname(L, ci, c, name); /* search for 'c' */
+ const char *what = getobjname(p, pc, c, name); /* search for 'c' */
if (what && *what == 'c') { /* found a constant name? */
return; /* 'name' already filled */
}
@@ -313,85 +324,30 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
}
-static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
- const char **name) {
- Proto *p = ci_func(ci)->p;
- const char *what = NULL;
- int lastpc = currentpc(ci);
+/*
+** try to find last instruction before 'lastpc' that modified register 'reg'
+*/
+static int findsetreg (Proto *p, int lastpc, int reg) {
int pc;
- *name = luaF_getlocalname(p, reg + 1, lastpc);
- if (*name) /* is a local? */
- return "local";
- /* else try symbolic execution */
+ int setreg = -1; /* keep last instruction that changed 'reg' */
for (pc = 0; pc < lastpc; pc++) {
Instruction i = p->code[pc];
OpCode op = GET_OPCODE(i);
int a = GETARG_A(i);
switch (op) {
- case OP_MOVE: {
- if (reg == a) {
- int b = GETARG_B(i); /* move from 'b' to 'a' */
- if (b < a)
- what = getobjname(L, ci, b, name); /* get name for 'b' */
- else what = NULL;
- }
- break;
- }
- case OP_GETTABUP:
- case OP_GETTABLE: {
- if (reg == a) {
- int k = GETARG_C(i); /* key index */
- int t = GETARG_B(i);
- const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
- ? luaF_getlocalname(p, t + 1, pc)
- : getstr(p->upvalues[t].name);
- kname(L, ci, k, a, what, name);
- what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
- }
- break;
- }
- case OP_GETUPVAL: {
- if (reg == a) {
- int u = GETARG_B(i); /* upvalue index */
- TString *tn = p->upvalues[u].name;
- *name = tn ? getstr(tn) : "?";
- what = "upvalue";
- }
- break;
- }
- case OP_LOADK:
- case OP_LOADKX: {
- if (reg == a) {
- int b = (op == OP_LOADK) ? GETARG_Bx(i)
- : GETARG_Ax(p->code[pc + 1]);
- if (ttisstring(&p->k[b])) {
- what = "constant";
- *name = svalue(&p->k[b]);
- }
- }
- break;
- }
case OP_LOADNIL: {
int b = GETARG_B(i);
if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
- what = NULL;
- break;
- }
- case OP_SELF: {
- if (reg == a) {
- int k = GETARG_C(i); /* key index */
- kname(L, ci, k, a, what, name);
- what = "method";
- }
+ setreg = pc;
break;
}
case OP_TFORCALL: {
- if (reg >= a + 2) what = NULL; /* affect all regs above its base */
+ if (reg >= a + 2) setreg = pc; /* affect all regs above its base */
break;
}
case OP_CALL:
case OP_TAILCALL: {
- if (reg >= a) what = NULL; /* affect all registers above base */
+ if (reg >= a) setreg = pc; /* affect all registers above base */
break;
}
case OP_JMP: {
@@ -403,35 +359,87 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
break;
}
case OP_TEST: {
- if (reg == a) what = NULL; /* jumped code can change 'a' */
+ if (reg == a) setreg = pc; /* jumped code can change 'a' */
break;
}
default:
- if (testAMode(op) && reg == a) what = NULL;
+ if (testAMode(op) && reg == a) /* any instruction that set A */
+ setreg = pc;
break;
}
}
- return what;
+ return setreg;
+}
+
+
+static const char *getobjname (Proto *p, int lastpc, int reg,
+ const char **name) {
+ int pc;
+ *name = luaF_getlocalname(p, reg + 1, lastpc);
+ if (*name) /* is a local? */
+ return "local";
+ /* else try symbolic execution */
+ pc = findsetreg(p, lastpc, reg);
+ if (pc != -1) { /* could find instruction? */
+ Instruction i = p->code[pc];
+ OpCode op = GET_OPCODE(i);
+ switch (op) {
+ case OP_MOVE: {
+ int b = GETARG_B(i); /* move from 'b' to 'a' */
+ if (b < GETARG_A(i))
+ return getobjname(p, pc, b, name); /* get name for 'b' */
+ break;
+ }
+ case OP_GETTABUP:
+ case OP_GETTABLE: {
+ int k = GETARG_C(i); /* key index */
+ int t = GETARG_B(i); /* table index */
+ const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
+ ? luaF_getlocalname(p, t + 1, pc)
+ : upvalname(p, t);
+ kname(p, pc, k, name);
+ return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
+ }
+ case OP_GETUPVAL: {
+ *name = upvalname(p, GETARG_B(i));
+ return "upvalue";
+ }
+ case OP_LOADK:
+ case OP_LOADKX: {
+ int b = (op == OP_LOADK) ? GETARG_Bx(i)
+ : GETARG_Ax(p->code[pc + 1]);
+ if (ttisstring(&p->k[b])) {
+ *name = svalue(&p->k[b]);
+ return "constant";
+ }
+ break;
+ }
+ case OP_SELF: {
+ int k = GETARG_C(i); /* key index */
+ kname(p, pc, k, name);
+ return "method";
+ }
+ default: break; /* go through to return NULL */
+ }
+ }
+ return NULL; /* could not find reasonable name */
}
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
TMS tm;
- Instruction i;
- if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous))
- return NULL; /* calling function is not Lua (or is unknown) */
- ci = ci->previous; /* calling function */
- i = ci_func(ci)->p->code[currentpc(ci)];
- if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */
- i = ci_func(ci)->p->code[currentpc(ci) - 1]; /* get 'real' instruction */
+ Proto *p = ci_func(ci)->p; /* calling function */
+ int pc = currentpc(ci); /* calling instruction index */
+ Instruction i = p->code[pc]; /* calling instruction */
switch (GET_OPCODE(i)) {
case OP_CALL:
- case OP_TAILCALL:
- return getobjname(L, ci, GETARG_A(i), name);
- case OP_TFORCALL: {
+ case OP_TAILCALL: /* get function name */
+ return getobjname(p, pc, GETARG_A(i), name);
+ case OP_TFORCALL: { /* for iterator */
*name = "for iterator";
return "for iterator";
}
+ /* all other instructions can call only through metamethods */
case OP_SELF:
case OP_GETTABUP:
case OP_GETTABLE: tm = TM_INDEX; break;
@@ -473,12 +481,12 @@ static int isinstack (CallInfo *ci, const TValue *o) {
static const char *getupvalname (CallInfo *ci, const TValue *o,
- const char **name) {
+ const char **name) {
LClosure *c = ci_func(ci);
int i;
for (i = 0; i < c->nupvalues; i++) {
if (c->upvals[i]->v == o) {
- *name = getstr(c->p->upvalues[i].name);
+ *name = upvalname(c->p, i);
return "upvalue";
}
}
@@ -494,7 +502,8 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
if (isLua(ci)) {
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
if (!kind && isinstack(ci, o)) /* no? try a register */
- kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name);
+ kind = getobjname(ci_func(ci)->p, currentpc(ci),
+ cast_int(o - ci->u.l.base), &name);
}
if (kind)
luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
@@ -511,7 +520,7 @@ void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
}
-void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
+l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
TValue temp;
if (luaV_tonumber(p1, &temp) == NULL)
p2 = p1; /* first operand is wrong */
@@ -519,14 +528,13 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
}
-int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
+l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = objtypename(p1);
const char *t2 = objtypename(p2);
if (t1 == t2)
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
- return 0;
}
@@ -546,7 +554,7 @@ static void addinfo (lua_State *L, const char *msg) {
}
-void luaG_errormsg (lua_State *L) {
+l_noret luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
@@ -559,7 +567,7 @@ void luaG_errormsg (lua_State *L) {
}
-void luaG_runerror (lua_State *L, const char *fmt, ...) {
+l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
addinfo(L, luaO_pushvfstring(L, fmt, argp));
diff --git a/src/ldebug.h b/src/ldebug.h
index 6590c56b..fe39556b 100644
--- a/src/ldebug.h
+++ b/src/ldebug.h
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.h,v 2.6 2011/06/02 19:31:40 roberto Exp $
+** $Id: ldebug.h,v 2.7 2011/10/07 20:45:19 roberto Exp $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
@@ -21,14 +21,14 @@
#define ci_func(ci) (clLvalue((ci)->func))
-LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
- const char *opname);
-LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
-LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
- const TValue *p2);
-LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
- const TValue *p2);
-LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
-LUAI_FUNC void luaG_errormsg (lua_State *L);
+LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
+ const char *opname);
+LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2);
+LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1,
+ const TValue *p2);
+LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
+ const TValue *p2);
+LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
+LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
#endif
diff --git a/src/ldo.c b/src/ldo.c
index a34b0d0b..0f8c26ea 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.98 2011/06/28 15:42:04 roberto Exp $
+** $Id: ldo.c,v 2.101 2011/10/07 20:45:19 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -100,7 +100,7 @@ static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
}
-void luaD_throw (lua_State *L, int errcode) {
+l_noret luaD_throw (lua_State *L, int errcode) {
if (L->errorJmp) { /* thread has an error handler? */
L->errorJmp->status = errcode; /* set status */
LUAI_THROW(L, L->errorJmp); /* jump to it */
@@ -123,7 +123,7 @@ void luaD_throw (lua_State *L, int errcode) {
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
- unsigned short oldnCcalls = G(L)->nCcalls;
+ unsigned short oldnCcalls = L->nCcalls;
struct lua_longjmp lj;
lj.status = LUA_OK;
lj.previous = L->errorJmp; /* chain new error handler */
@@ -132,7 +132,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
(*f)(L, ud);
);
L->errorJmp = lj.previous; /* restore old error handler */
- G(L)->nCcalls = oldnCcalls;
+ L->nCcalls = oldnCcalls;
return lj.status;
}
@@ -344,7 +344,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
}
default: { /* not a function */
func = tryfuncTM(L, func); /* retry with 'function' tag method */
- return luaD_precall(L, func, nresults);
+ return luaD_precall(L, func, nresults); /* now it must be a function */
}
}
}
@@ -382,18 +382,17 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
** function position.
*/
void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
- global_State *g = G(L);
- if (++g->nCcalls >= LUAI_MAXCCALLS) {
- if (g->nCcalls == LUAI_MAXCCALLS)
+ if (++L->nCcalls >= LUAI_MAXCCALLS) {
+ if (L->nCcalls == LUAI_MAXCCALLS)
luaG_runerror(L, "C stack overflow");
- else if (g->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
+ else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
if (!allowyield) L->nny++;
if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
luaV_execute(L); /* call it */
if (!allowyield) L->nny--;
- g->nCcalls--;
+ L->nCcalls--;
luaC_checkGC(L);
}
@@ -404,7 +403,7 @@ static void finishCcall (lua_State *L) {
lua_assert(ci->u.c.k != NULL); /* must have a continuation */
lua_assert(L->nny == 0);
/* finish 'luaD_call' */
- G(L)->nCcalls--;
+ L->nCcalls--;
/* finish 'lua_callk' */
adjustresults(L, ci->nresults);
/* call continuation function */
@@ -473,7 +472,7 @@ static int recover (lua_State *L, int status) {
** coroutine itself. (Such errors should not be handled by any coroutine
** error handler and should not kill the coroutine.)
*/
-static void resume_error (lua_State *L, const char *msg, StkId firstArg) {
+static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
L->top = firstArg; /* remove args from the stack */
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
incr_top(L);
@@ -487,7 +486,7 @@ static void resume_error (lua_State *L, const char *msg, StkId firstArg) {
static void resume (lua_State *L, void *ud) {
StkId firstArg = cast(StkId, ud);
CallInfo *ci = L->ci;
- if (G(L)->nCcalls >= LUAI_MAXCCALLS)
+ if (L->nCcalls >= LUAI_MAXCCALLS)
resume_error(L, "C stack overflow", firstArg);
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (ci != &L->base_ci) /* not in base level? */
@@ -514,7 +513,7 @@ static void resume (lua_State *L, void *ud) {
api_checknelems(L, n);
firstArg = L->top - n; /* yield results come from continuation */
}
- G(L)->nCcalls--; /* finish 'luaD_call' */
+ L->nCcalls--; /* finish 'luaD_call' */
luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
}
unroll(L, NULL);
@@ -522,11 +521,11 @@ static void resume (lua_State *L, void *ud) {
}
-LUA_API int lua_resume (lua_State *L, int nargs) {
+LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
int status;
lua_lock(L);
luai_userstateresume(L, nargs);
- ++G(L)->nCcalls; /* count resume */
+ L->nCcalls = (from) ? from->nCcalls + 1 : 1;
L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
status = luaD_rawrunprotected(L, resume, L->top - nargs);
@@ -546,7 +545,8 @@ LUA_API int lua_resume (lua_State *L, int nargs) {
lua_assert(status == L->status);
}
L->nny = 1; /* do not allow yields */
- --G(L)->nCcalls;
+ L->nCcalls--;
+ lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
lua_unlock(L);
return status;
}
diff --git a/src/ldo.h b/src/ldo.h
index 88962d9c..edfe0070 100644
--- a/src/ldo.h
+++ b/src/ldo.h
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.h,v 2.18 2009/12/17 12:28:57 roberto Exp $
+** $Id: ldo.h,v 2.19 2011/10/07 20:45:19 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -38,7 +38,7 @@ LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
-LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
+LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
#endif
diff --git a/src/ldump.c b/src/ldump.c
index 77b578d7..699e1dc4 100644
--- a/src/ldump.c
+++ b/src/ldump.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldump.c,v 1.18 2011/05/06 13:35:17 lhf Exp $
+** $Id: ldump.c,v 1.19 2011/11/23 17:48:18 lhf Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -111,8 +111,8 @@ static void DumpUpvalues(const Proto* f, DumpState* D)
DumpInt(n,D);
for (i=0; i<n; i++)
{
- DumpChar(f->upvalues[i].instack, D);
- DumpChar(f->upvalues[i].idx, D);
+ DumpChar(f->upvalues[i].instack,D);
+ DumpChar(f->upvalues[i].idx,D);
}
}
diff --git a/src/lgc.c b/src/lgc.c
index 598cc71c..37de55ca 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.109 2011/05/05 19:42:25 roberto Exp $
+** $Id: lgc.c,v 2.114 2011/10/03 17:54:25 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -100,12 +100,13 @@ static void reallymarkobject (global_State *g, GCObject *o);
/*
-** mark a table entry as dead (therefore removing it from the table)
+** if key is not marked, mark its entry as dead (therefore removing it
+** from the table)
*/
static void removeentry (Node *n) {
lua_assert(ttisnil(gval(n)));
- if (iscollectable(gkey(n)))
- setdeadvalue(gkey(n)); /* dead key; remove it */
+ if (valiswhite(gkey(n)))
+ setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */
}
@@ -116,13 +117,13 @@ static void removeentry (Node *n) {
** other objects: if really collected, cannot keep them; for objects
** being finalized, keep them in keys, but not in values
*/
-static int iscleared (const TValue *o, int iskey) {
+static int iscleared (const TValue *o) {
if (!iscollectable(o)) return 0;
else if (ttisstring(o)) {
stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
return 0;
}
- else return iswhite(gcvalue(o)) || (!iskey && isfinalized(gcvalue(o)));
+ else return iswhite(gcvalue(o));
}
@@ -152,7 +153,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
*/
void luaC_barrierback_ (lua_State *L, GCObject *o) {
global_State *g = G(L);
- lua_assert(isblack(o) && !isdead(g, o));
+ lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE);
black2gray(o); /* make object gray (again) */
gco2t(o)->gclist = g->grayagain;
g->grayagain = o;
@@ -342,6 +343,9 @@ static void markroot (global_State *g) {
static void traverseweakvalue (global_State *g, Table *h) {
Node *n, *limit = gnode(h, sizenode(h));
+ /* if there is array part, assume it may have white values (do not
+ traverse it just to check) */
+ int hasclears = (h->sizearray > 0);
for (n = gnode(h, 0); n < limit; n++) {
checkdeadkey(n);
if (ttisnil(gval(n))) /* entry is empty? */
@@ -349,15 +353,21 @@ static void traverseweakvalue (global_State *g, Table *h) {
else {
lua_assert(!ttisnil(gkey(n)));
markvalue(g, gkey(n)); /* mark key */
+ if (!hasclears && iscleared(gval(n))) /* is there a white value? */
+ hasclears = 1; /* table will have to be cleared */
}
}
- linktable(h, &g->weak); /* link into appropriate list */
+ if (hasclears)
+ linktable(h, &g->weak); /* has to be cleared later */
+ else /* no white values */
+ linktable(h, &g->grayagain); /* no need to clean */
}
static int traverseephemeron (global_State *g, Table *h) {
int marked = 0; /* true if an object is marked in this traversal */
- int hasclears = 0; /* true if table has unmarked pairs */
+ int hasclears = 0; /* true if table has white keys */
+ int prop = 0; /* true if table has entry "white-key -> white-value" */
Node *n, *limit = gnode(h, sizenode(h));
int i;
/* traverse array part (numeric keys are 'strong') */
@@ -372,19 +382,22 @@ static int traverseephemeron (global_State *g, Table *h) {
checkdeadkey(n);
if (ttisnil(gval(n))) /* entry is empty? */
removeentry(n); /* remove it */
+ else if (iscleared(gkey(n))) { /* key is not marked (yet)? */
+ hasclears = 1; /* table must be cleared */
+ if (valiswhite(gval(n))) /* value not marked yet? */
+ prop = 1; /* must propagate again */
+ }
else if (valiswhite(gval(n))) { /* value not marked yet? */
- if (iscleared(gkey(n), 1)) /* key is not marked (yet)? */
- hasclears = 1; /* may have to propagate mark from key to value */
- else { /* key is marked, so mark value */
- marked = 1; /* value was not marked */
- reallymarkobject(g, gcvalue(gval(n)));
- }
+ marked = 1;
+ reallymarkobject(g, gcvalue(gval(n))); /* mark it now */
}
}
- if (hasclears) /* does table have unmarked pairs? */
- linktable(h, &g->ephemeron); /* will have to propagate again */
- else /* nothing to propagate */
- linktable(h, &g->weak); /* avoid convergence phase */
+ if (prop)
+ linktable(h, &g->ephemeron); /* have to propagate again */
+ else if (hasclears) /* does table have white keys? */
+ linktable(h, &g->allweak); /* may have to clean white keys */
+ else /* no white keys */
+ linktable(h, &g->grayagain); /* no need to clean */
return marked;
}
@@ -526,11 +539,26 @@ static void propagateall (global_State *g) {
}
-static void traverselistofgrays (global_State *g, GCObject **l) {
+static void propagatelist (global_State *g, GCObject *l) {
lua_assert(g->gray == NULL); /* no grays left */
- g->gray = *l; /* now 'l' is new gray list */
- *l = NULL;
- propagateall(g);
+ g->gray = l;
+ propagateall(g); /* traverse all elements from 'l' */
+}
+
+/*
+** retraverse all gray lists. Because tables may be reinserted in other
+** lists when traversed, traverse the original lists to avoid traversing
+** twice the same table (which is not wrong, but inefficient)
+*/
+static void retraversegrays (global_State *g) {
+ GCObject *weak = g->weak; /* save original lists */
+ GCObject *grayagain = g->grayagain;
+ GCObject *ephemeron = g->ephemeron;
+ g->weak = g->grayagain = g->ephemeron = NULL;
+ propagateall(g); /* traverse main gray list */
+ propagatelist(g, grayagain);
+ propagatelist(g, weak);
+ propagatelist(g, ephemeron);
}
@@ -562,21 +590,39 @@ static void convergeephemerons (global_State *g) {
/*
-** clear collected entries from all weaktables in list 'l'
+** clear entries with unmarked keys from all weaktables in list 'l' up
+** to element 'f'
+*/
+static void clearkeys (GCObject *l, GCObject *f) {
+ for (; l != f; l = gco2t(l)->gclist) {
+ Table *h = gco2t(l);
+ Node *n, *limit = gnode(h, sizenode(h));
+ for (n = gnode(h, 0); n < limit; n++) {
+ if (!ttisnil(gval(n)) && (iscleared(gkey(n)))) {
+ setnilvalue(gval(n)); /* remove value ... */
+ removeentry(n); /* and remove entry from table */
+ }
+ }
+ }
+}
+
+
+/*
+** clear entries with unmarked values from all weaktables in list 'l' up
+** to element 'f'
*/
-static void cleartable (GCObject *l) {
- for (; l != NULL; l = gco2t(l)->gclist) {
+static void clearvalues (GCObject *l, GCObject *f) {
+ for (; l != f; l = gco2t(l)->gclist) {
Table *h = gco2t(l);
Node *n, *limit = gnode(h, sizenode(h));
int i;
for (i = 0; i < h->sizearray; i++) {
TValue *o = &h->array[i];
- if (iscleared(o, 0)) /* value was collected? */
+ if (iscleared(o)) /* value was collected? */
setnilvalue(o); /* remove value */
}
for (n = gnode(h, 0); n < limit; n++) {
- if (!ttisnil(gval(n)) && /* non-empty entry? */
- (iscleared(gkey(n), 1) || iscleared(gval(n), 0))) {
+ if (!ttisnil(gval(n)) && iscleared(gval(n))) {
setnilvalue(gval(n)); /* remove value ... */
removeentry(n); /* and remove entry from table */
}
@@ -743,10 +789,10 @@ static void GCTM (lua_State *L, int propagateerrors) {
/*
-** move all unreachable objects that need finalization from list 'finobj'
-** to list 'tobefnz'
+** move all unreachable objects (or 'all' objects) that need
+** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
*/
-void luaC_separateudata (lua_State *L, int all) {
+static void separatetobefnz (lua_State *L, int all) {
global_State *g = G(L);
GCObject **p = &g->finobj;
GCObject *curr;
@@ -842,14 +888,13 @@ static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
void luaC_freeallobjects (lua_State *L) {
global_State *g = G(L);
int i;
+ separatetobefnz(L, 1); /* separate all objects with finalizers */
+ lua_assert(g->finobj == NULL);
callallpendingfinalizers(L, 0);
- /* following "white" makes all objects look dead */
- g->currentwhite = WHITEBITS;
+ g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
g->gckind = KGC_NORMAL;
- sweepwholelist(L, &g->finobj);
- lua_assert(g->finobj == NULL);
+ sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */
sweepwholelist(L, &g->allgc);
- lua_assert(g->allgc == NULL);
for (i = 0; i < g->strt.size; i++) /* free all string lists */
sweepwholelist(L, &g->strt.hash[i]);
lua_assert(g->strt.nuse == 0);
@@ -858,6 +903,7 @@ void luaC_freeallobjects (lua_State *L) {
static void atomic (lua_State *L) {
global_State *g = G(L);
+ GCObject *origweak, *origall;
lua_assert(!iswhite(obj2gco(g->mainthread)));
markobject(g, L); /* mark running thread */
/* registry and global metatables may be changed by API */
@@ -866,20 +912,24 @@ static void atomic (lua_State *L) {
/* remark occasional upvalues of (maybe) dead threads */
remarkupvals(g);
/* traverse objects caught by write barrier and by 'remarkupvals' */
- propagateall(g);
- traverselistofgrays(g, &g->weak); /* remark weak tables */
- traverselistofgrays(g, &g->ephemeron); /* remark ephemeron tables */
- traverselistofgrays(g, &g->grayagain); /* remark gray again */
+ retraversegrays(g);
convergeephemerons(g);
/* at this point, all strongly accessible objects are marked. */
- luaC_separateudata(L, 0); /* separate userdata to be finalized */
+ /* clear values from weak tables, before checking finalizers */
+ clearvalues(g->weak, NULL);
+ clearvalues(g->allweak, NULL);
+ origweak = g->weak; origall = g->allweak;
+ separatetobefnz(L, 0); /* separate objects to be finalized */
markbeingfnz(g); /* mark userdata that will be finalized */
propagateall(g); /* remark, to propagate `preserveness' */
convergeephemerons(g);
- /* remove collected objects from weak tables */
- cleartable(g->weak);
- cleartable(g->ephemeron);
- cleartable(g->allweak);
+ /* at this point, all resurrected objects are marked. */
+ /* remove dead objects from weak tables */
+ clearkeys(g->ephemeron, NULL); /* clear keys from all ephemeron tables */
+ clearkeys(g->allweak, NULL); /* clear keys from all allweak tables */
+ /* clear values from resurrected weak tables */
+ clearvalues(g->weak, origweak);
+ clearvalues(g->allweak, origall);
g->sweepstrgc = 0; /* prepare to sweep strings */
g->gcstate = GCSsweepstring;
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
diff --git a/src/lgc.h b/src/lgc.h
index 0fae4dd2..aa5dfce2 100644
--- a/src/lgc.h
+++ b/src/lgc.h
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.h,v 2.50 2011/01/26 16:30:02 roberto Exp $
+** $Id: lgc.h,v 2.52 2011/10/03 17:54:25 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -63,9 +63,6 @@
#define l_setbit(x,b) setbits(x, bitmask(b))
#define resetbit(x,b) resetbits(x, bitmask(b))
#define testbit(x,b) testbits(x, bitmask(b))
-#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
-#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
-
/* Layout for bit use in `marked' field: */
@@ -125,7 +122,6 @@
#define luaC_barrierproto(L,p,c) \
{ if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
-LUAI_FUNC void luaC_separateudata (lua_State *L, int all);
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_forcestep (lua_State *L);
diff --git a/src/liolib.c b/src/liolib.c
index 41e7ec55..0c9314c7 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,10 +1,20 @@
/*
-** $Id: liolib.c,v 2.101 2011/06/27 19:42:31 roberto Exp $
+** $Id: liolib.c,v 2.107 2011/11/14 16:55:35 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
+/*
+** POSIX idiosyncrasy!
+** This definition must come before the inclusion of 'stdio.h'; it
+** should not affect non-POSIX systems
+*/
+#if !defined(_FILE_OFFSET_BITS)
+#define _FILE_OFFSET_BITS 64
+#endif
+
+
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -21,9 +31,12 @@
/*
-** lua_popen spawns a new process connected to the current one through
-** the file streams.
+** {======================================================
+** lua_popen spawns a new process connected to the current
+** one through the file streams.
+** =======================================================
*/
+
#if !defined(lua_popen) /* { */
#if defined(LUA_USE_POPEN) /* { */
@@ -48,22 +61,48 @@
#endif /* } */
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** lua_fseek/lua_ftell: configuration for longer offsets
+** =======================================================
+*/
+
+#if !defined(lua_fseek) /* { */
+
+#if defined(LUA_USE_POSIX)
+
+#define l_fseek(f,o,w) fseeko(f,o,w)
+#define l_ftell(f) ftello(f)
+#define l_seeknum off_t
+
+#elif defined(LUA_WIN)
+
+#define l_fseek(f,o,w) _fseeki64(f,o,w)
+#define l_ftell(f) _ftelli64(f)
+#define l_seeknum __int64
+
+#else
+
+#define l_fseek(f,o,w) fseek(f,o,w)
+#define l_ftell(f) ftell(f)
+#define l_seeknum long
+
+#endif
+
+#endif /* } */
+
+/* }====================================================== */
+
#define IO_PREFIX "_IO_"
#define IO_INPUT (IO_PREFIX "input")
#define IO_OUTPUT (IO_PREFIX "output")
-typedef struct LStream {
- FILE *f; /* stream */
- lua_CFunction closef; /* to close stream (NULL for closed streams) */
-} LStream;
-
-
-static void fileerror (lua_State *L, int arg, const char *filename) {
- lua_pushfstring(L, "%s: %s", filename, strerror(errno));
- luaL_argerror(L, arg, lua_tostring(L, -1));
-}
+typedef luaL_Stream LStream;
#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
@@ -159,6 +198,14 @@ static LStream *newfile (lua_State *L) {
}
+static void opencheck (lua_State *L, const char *fname, const char *mode) {
+ LStream *p = newfile(L);
+ p->f = fopen(fname, mode);
+ if (p->f == NULL)
+ luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
+}
+
+
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
@@ -169,7 +216,7 @@ static int io_open (lua_State *L) {
(mode[i] != '+' || ++i) && /* skip if char is '+' */
(mode[i] != 'b' || ++i) && /* skip if char is 'b' */
(mode[i] == '\0')))
- return luaL_error(L, "invalid mode " LUA_QL("%s")
+ return luaL_error(L, "invalid mode " LUA_QS
" (should match " LUA_QL("[rwa]%%+?b?") ")", mode);
p->f = fopen(filename, mode);
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
@@ -215,12 +262,8 @@ static FILE *getiofile (lua_State *L, const char *findex) {
static int g_iofile (lua_State *L, const char *f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
- if (filename) {
- LStream *p = newfile(L);
- p->f = fopen(filename, mode);
- if (p->f == NULL)
- fileerror(L, 1, filename);
- }
+ if (filename)
+ opencheck(L, filename, mode);
else {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
@@ -277,10 +320,7 @@ static int io_lines (lua_State *L) {
}
else { /* open a new file */
const char *filename = luaL_checkstring(L, 1);
- LStream *p = newfile(L);
- p->f = fopen(filename, "r");
- if (p->f == NULL)
- fileerror(L, 1, filename);
+ opencheck(L, filename, "r");
lua_replace(L, 1); /* put file at index 1 */
toclose = 1; /* close it after iteration */
}
@@ -444,9 +484,10 @@ static int io_readline (lua_State *L) {
if (!lua_isnil(L, -n)) /* read at least one value? */
return n; /* return them */
else { /* first result is nil: EOF or error */
- if (!lua_isnil(L, -1)) /* is there error information? */
- return luaL_error(L, "%s", lua_tostring(L, -1)); /* error */
- /* else EOF */
+ if (n > 1) { /* is there error information? */
+ /* 2nd result is error message */
+ return luaL_error(L, "%s", lua_tostring(L, -n + 1));
+ }
if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
@@ -496,12 +537,15 @@ static int f_seek (lua_State *L) {
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames);
- long offset = luaL_optlong(L, 3, 0);
- op = fseek(f, offset, mode[op]);
+ lua_Number p3 = luaL_optnumber(L, 3, 0);
+ l_seeknum offset = (l_seeknum)p3;
+ luaL_argcheck(L, (lua_Number)offset == p3, 3,
+ "not an integer in proper range");
+ op = l_fseek(f, offset, mode[op]);
if (op)
return luaL_fileresult(L, 0, NULL); /* error */
else {
- lua_pushinteger(L, ftell(f));
+ lua_pushnumber(L, (lua_Number)l_ftell(f));
return 1;
}
}
diff --git a/src/llex.c b/src/llex.c
index 289abfd8..f73f74b2 100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 2.53 2011/07/08 20:01:38 roberto Exp $
+** $Id: llex.c,v 2.58 2011/08/15 19:41:58 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -126,8 +126,10 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
TValue *o; /* entry for `str' */
TString *ts = luaS_newlstr(L, str, l); /* create new string */
setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
- o = luaH_setstr(L, ls->fs->h, ts);
- if (ttisnil(o)) {
+ o = luaH_set(L, ls->fs->h, L->top - 1);
+ if (ttisnil(o)) { /* not in use yet? (see 'addK') */
+ /* boolean value does not need GC barrier;
+ table has no metatable, so it does not need to invalidate cache */
setbvalue(o, 1); /* t[string] = true */
luaC_checkGC(L);
}
@@ -297,39 +299,29 @@ static void escerror (LexState *ls, int *c, int n, const char *msg) {
static int readhexaesc (LexState *ls) {
- int c[3]; /* keep input for error message */
- int i = 2; /* at least 'x?' will go to error message */
- c[0] = 'x';
- c[1] = next(ls); /* first hexa digit */
- if (lisxdigit(c[1])) {
- c[i++] = next(ls); /* second hexa digit */
- if (lisxdigit(c[2]))
- return (luaO_hexavalue(c[1]) << 4) + luaO_hexavalue(c[2]);
- /* else go through to error */
+ int c[3], i; /* keep input for error message */
+ int r = 0; /* result accumulator */
+ c[0] = 'x'; /* for error message */
+ for (i = 1; i < 3; i++) { /* read two hexa digits */
+ c[i] = next(ls);
+ if (!lisxdigit(c[i]))
+ escerror(ls, c, i + 1, "hexadecimal digit expected");
+ r = (r << 4) + luaO_hexavalue(c[i]);
}
- escerror(ls, c, i, "hexadecimal digit expected");
- return 0; /* to avoid warnings */
+ return r;
}
static int readdecesc (LexState *ls) {
- int c[3], r;
- int i = 2; /* at least two chars will be read */
- c[0] = ls->current; /* first char must be a digit */
- c[1] = next(ls); /* read second char */
- r = c[0] - '0'; /* partial result */
- if (lisdigit(c[1])) {
- c[i++] = next(ls); /* read third char */
- r = 10*r + c[1] - '0'; /* update result */
- if (lisdigit(c[2])) {
- r = 10*r + c[2] - '0'; /* update result */
- if (r > UCHAR_MAX)
- escerror(ls, c, i, "decimal escape too large");
- return r;
- }
+ int c[3], i;
+ int r = 0; /* result accumulator */
+ for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */
+ c[i] = ls->current;
+ r = 10*r + c[i] - '0';
+ next(ls);
}
- /* else, has read one character that was not a digit */
- zungetc(ls->z); /* return it to input stream */
+ if (r > UCHAR_MAX)
+ escerror(ls, c, i, "decimal escape too large");
return r;
}
@@ -349,37 +341,38 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) {
int c; /* final character to be saved */
next(ls); /* do not save the `\' */
switch (ls->current) {
- case 'a': c = '\a'; break;
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'v': c = '\v'; break;
- case 'x': c = readhexaesc(ls); break;
- case '\n':
- case '\r': save(ls, '\n'); inclinenumber(ls); continue;
- case '\\': case '\"': case '\'': c = ls->current; break;
- case EOZ: continue; /* will raise an error next loop */
+ case 'a': c = '\a'; goto read_save;
+ case 'b': c = '\b'; goto read_save;
+ case 'f': c = '\f'; goto read_save;
+ case 'n': c = '\n'; goto read_save;
+ case 'r': c = '\r'; goto read_save;
+ case 't': c = '\t'; goto read_save;
+ case 'v': c = '\v'; goto read_save;
+ case 'x': c = readhexaesc(ls); goto read_save;
+ case '\n': case '\r':
+ inclinenumber(ls); c = '\n'; goto only_save;
+ case '\\': case '\"': case '\'':
+ c = ls->current; goto read_save;
+ case EOZ: goto no_save; /* will raise an error next loop */
case 'z': { /* zap following span of spaces */
next(ls); /* skip the 'z' */
while (lisspace(ls->current)) {
if (currIsNewline(ls)) inclinenumber(ls);
else next(ls);
}
- continue; /* do not save 'c' */
+ goto no_save;
}
default: {
if (!lisdigit(ls->current))
escerror(ls, &ls->current, 1, "invalid escape sequence");
/* digital escape \ddd */
c = readdecesc(ls);
- break;
+ goto only_save;
}
}
- next(ls);
- save(ls, c);
- break;
+ read_save: next(ls); /* read next character */
+ only_save: save(ls, c); /* save 'c' */
+ no_save: break;
}
default:
save_and_next(ls);
diff --git a/src/llimits.h b/src/llimits.h
index b64c7b7d..17293ca0 100644
--- a/src/llimits.h
+++ b/src/llimits.h
@@ -1,5 +1,5 @@
/*
-** $Id: llimits.h,v 1.90 2011/07/02 15:57:25 roberto Exp $
+** $Id: llimits.h,v 1.93 2011/10/07 20:45:19 roberto Exp $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -30,7 +30,6 @@ typedef unsigned char lu_byte;
#define MAX_SIZET ((size_t)(~(size_t)0)-2)
#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
-#define MIN_LMEM ((l_mem)~((~(lu_mem)0)>>1))
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
@@ -62,9 +61,9 @@ typedef LUAI_UACNUMBER l_uacNumber;
/* to avoid problems with conditions too long */
#define lua_longassert(c) { if (!(c)) lua_assert(0); }
#else
-#define lua_assert(c) /* empty */
+#define lua_assert(c) ((void)0)
#define check_exp(c,e) (e)
-#define lua_longassert(c) /* empty */
+#define lua_longassert(c) ((void)0)
#endif
/*
@@ -98,6 +97,19 @@ typedef LUAI_UACNUMBER l_uacNumber;
/*
+** non-return type
+*/
+#if defined(__GNUC__)
+#define l_noret void __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define l_noret void __declspec(noreturn)
+#else
+#define l_noret void
+#endif
+
+
+
+/*
** maximum depth for nested C calls and syntactical nested non-terminals
** in a program. (Value must fit in an unsigned short int.)
*/
diff --git a/src/lmem.c b/src/lmem.c
index c3775dfb..3e8fa8ac 100644
--- a/src/lmem.c
+++ b/src/lmem.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmem.c,v 1.81 2010/12/20 19:40:07 roberto Exp $
+** $Id: lmem.c,v 1.82 2011/09/20 19:25:23 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -106,7 +106,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
if ((total % 200) == 0) {
if (f == NULL) f = fopen(TRACEMEM, "w");
fprintf(f, "%lu %u %d %d\n", total,
- g->totalbytes, g->GCdebt, g->gcstate * 1000);
+ gettotalbytes(g), g->GCdebt, g->gcstate * 10000);
}
}
#endif
diff --git a/src/loadlib.c b/src/loadlib.c
index 0313d8e4..acf5af6b 100644
--- a/src/loadlib.c
+++ b/src/loadlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.100 2011/07/05 12:49:35 roberto Exp $
+** $Id: loadlib.c,v 1.104 2011/11/10 11:42:58 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -9,6 +9,14 @@
*/
+/*
+** if needed, includes windows header before everything else
+*/
+#if defined(LUA_DL_DLL)
+#include <windows.h>
+#endif
+
+
#include <stdlib.h>
#include <string.h>
@@ -62,6 +70,20 @@
#endif
+/*
+** LUA_CSUBSEP is the character that replaces dots in submodule names
+** when searching for a C loader.
+** LUA_LSUBSEP is the character that replaces dots in submodule names
+** when searching for a Lua loader.
+*/
+#if !defined(LUA_CSUBSEP)
+#define LUA_CSUBSEP LUA_DIRSEP
+#endif
+
+#if !defined(LUA_LSUBSEP)
+#define LUA_LSUBSEP LUA_DIRSEP
+#endif
+
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
@@ -133,8 +155,6 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
** =======================================================================
*/
-#include <windows.h>
-
#undef setprogdir
/*
@@ -322,10 +342,12 @@ static const char *pushnexttemplate (lua_State *L, const char *path) {
static const char *searchpath (lua_State *L, const char *name,
const char *path,
- const char *sep) {
+ const char *sep,
+ const char *dirsep) {
+ luaL_Buffer msg; /* to build error message */
+ luaL_buffinit(L, &msg);
if (*sep != '\0') /* non-empty separator? */
- name = luaL_gsub(L, name, sep, LUA_DIRSEP); /* replace it by proper one */
- lua_pushliteral(L, ""); /* error accumulator */
+ name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
LUA_PATH_MARK, name);
@@ -334,8 +356,9 @@ static const char *searchpath (lua_State *L, const char *name,
return filename; /* return that file name */
lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
lua_remove(L, -2); /* remove file name */
- lua_concat(L, 2); /* add entry to possible error message */
+ luaL_addvalue(&msg); /* concatenate error msg. entry */
}
+ luaL_pushresult(&msg); /* create error message */
return NULL; /* not found */
}
@@ -343,7 +366,8 @@ static const char *searchpath (lua_State *L, const char *name,
static int ll_searchpath (lua_State *L) {
const char *f = searchpath(L, luaL_checkstring(L, 1),
luaL_checkstring(L, 2),
- luaL_optstring(L, 3, "."));
+ luaL_optstring(L, 3, "."),
+ luaL_optstring(L, 4, LUA_DIRSEP));
if (f != NULL) return 1;
else { /* error message is on top of the stack */
lua_pushnil(L);
@@ -354,13 +378,14 @@ static int ll_searchpath (lua_State *L) {
static const char *findfile (lua_State *L, const char *name,
- const char *pname) {
+ const char *pname,
+ const char *dirsep) {
const char *path;
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
- return searchpath(L, name, path, ".");
+ return searchpath(L, name, path, ".", dirsep);
}
@@ -379,7 +404,7 @@ static int checkload (lua_State *L, int stat, const char *filename) {
static int searcher_Lua (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
- filename = findfile(L, name, "path");
+ filename = findfile(L, name, "path", LUA_LSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
}
@@ -405,7 +430,7 @@ static int loadfunc (lua_State *L, const char *filename, const char *modname) {
static int searcher_C (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
- const char *filename = findfile(L, name, "cpath");
+ const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (loadfunc(L, filename, name) == 0), filename);
}
@@ -418,7 +443,7 @@ static int searcher_Croot (lua_State *L) {
int stat;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name);
- filename = findfile(L, lua_tostring(L, -1), "cpath");
+ filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* root not found */
if ((stat = loadfunc(L, filename, name)) != 0) {
if (stat != ERRFUNC)
@@ -444,35 +469,46 @@ static int searcher_preload (lua_State *L) {
}
-static int ll_require (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
+static void findloader (lua_State *L, const char *name) {
int i;
- lua_settop(L, 1); /* _LOADED table will be at index 2 */
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, 2, name);
- if (lua_toboolean(L, -1)) /* is it there? */
- return 1; /* package is already loaded */
- /* else must load it; iterate over available seachers to find a loader */
- lua_getfield(L, lua_upvalueindex(1), "searchers");
- if (!lua_istable(L, -1))
+ luaL_Buffer msg; /* to build error message */
+ luaL_buffinit(L, &msg);
+ lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
+ if (!lua_istable(L, 3))
luaL_error(L, LUA_QL("package.searchers") " must be a table");
- lua_pushliteral(L, ""); /* error message accumulator */
- for (i=1; ; i++) {
- lua_rawgeti(L, -2, i); /* get a seacher */
- if (lua_isnil(L, -1)) /* no more searchers? */
+ /* iterate over available seachers to find a loader */
+ for (i = 1; ; i++) {
+ lua_rawgeti(L, 3, i); /* get a seacher */
+ if (lua_isnil(L, -1)) { /* no more searchers? */
+ lua_pop(L, 1); /* remove nil */
+ luaL_pushresult(&msg); /* create error message */
luaL_error(L, "module " LUA_QS " not found:%s",
- name, lua_tostring(L, -2));
+ name, lua_tostring(L, -1));
+ }
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
if (lua_isfunction(L, -2)) /* did it find a loader? */
- break; /* module loader found */
+ return; /* module loader found */
else if (lua_isstring(L, -2)) { /* searcher returned error message? */
lua_pop(L, 1); /* remove extra return */
- lua_concat(L, 2); /* accumulate error message */
+ luaL_addvalue(&msg); /* concatenate error message */
}
else
lua_pop(L, 2); /* remove both returns */
}
+}
+
+
+static int ll_require (lua_State *L) {
+ const char *name = luaL_checkstring(L, 1);
+ lua_settop(L, 1); /* _LOADED table will be at index 2 */
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, 2, name); /* _LOADED[name] */
+ if (lua_toboolean(L, -1)) /* is it there? */
+ return 1; /* package is already loaded */
+ /* else must load package */
+ lua_pop(L, 1); /* remove 'getfield' result */
+ findloader(L, name);
lua_pushstring(L, name); /* pass name as argument to module loader */
lua_insert(L, -2); /* name is 1st argument (before search data) */
lua_call(L, 2, 1); /* run loader to load module */
@@ -516,9 +552,11 @@ static void set_env (lua_State *L) {
static void dooptions (lua_State *L, int n) {
int i;
for (i = 2; i <= n; i++) {
- lua_pushvalue(L, i); /* get option (a function) */
- lua_pushvalue(L, -2); /* module */
- lua_call(L, 1, 0);
+ if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
+ lua_pushvalue(L, i); /* get option (a function) */
+ lua_pushvalue(L, -2); /* module */
+ lua_call(L, 1, 0);
+ }
}
}
diff --git a/src/lobject.c b/src/lobject.c
index d8cc3ce9..148d4bce 100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.52 2011/06/24 12:25:02 roberto Exp $
+** $Id: lobject.c,v 2.53 2011/07/27 12:13:08 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -103,8 +103,8 @@ static int isneg (const char **s) {
static lua_Number readhexa (const char **s, lua_Number r, int *count) {
- while (lisxdigit(cast_uchar(**s))) { /* read integer part */
- r = (r * 16.0) + cast_num(luaO_hexavalue(cast_uchar(*(*s)++)));
+ for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */
+ r = (r * 16.0) + cast_num(luaO_hexavalue(cast_uchar(**s)));
(*count)++;
}
return r;
@@ -157,7 +157,9 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
int luaO_str2d (const char *s, size_t len, lua_Number *result) {
char *endptr;
- if (strpbrk(s, "xX")) /* hexa? */
+ if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
+ return 0;
+ else if (strpbrk(s, "xX")) /* hexa? */
*result = lua_strx2number(s, &endptr);
else
*result = lua_str2number(s, &endptr);
diff --git a/src/lobject.h b/src/lobject.h
index d69d6153..06246bfa 100644
--- a/src/lobject.h
+++ b/src/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.61 2011/07/04 20:29:02 roberto Exp $
+** $Id: lobject.h,v 2.64 2011/10/31 17:48:22 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -132,7 +132,7 @@ typedef struct lua_TValue TValue;
#define ttislcf(o) checktag((o), LUA_TLCF)
#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA))
#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
-#define ttisdeadkey(o) checktag((o), ctb(LUA_TDEADKEY))
+#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
#define ttisequal(o1,o2) (rttype(o1) == rttype(o2))
@@ -151,6 +151,8 @@ typedef struct lua_TValue TValue;
#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h)
#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th)
+/* a dead value may get the 'gc' field, but cannot access its contents */
+#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
@@ -224,7 +226,7 @@ typedef struct lua_TValue TValue;
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TPROTO)); \
checkliveness(G(L),io); }
-#define setdeadvalue(obj) settt_(obj, ctb(LUA_TDEADKEY))
+#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
@@ -262,51 +264,73 @@ typedef struct lua_TValue TValue;
** =======================================================
*/
-#if defined(LUA_NANTRICKLE) || defined(LUA_NANTRICKBE)
+#if defined(LUA_NANTRICK) \
+ || defined(LUA_NANTRICK_LE) \
+ || defined(LUA_NANTRICK_BE)
/*
** numbers are represented in the 'd_' field. All other values have the
-** value (NNMARK | tag) in 'tt_'. A number with such pattern would be
+** value (NNMARK | tag) in 'tt__'. A number with such pattern would be
** a "signaled NaN", which is never generated by regular operations by
** the CPU (nor by 'strtod')
*/
#if !defined(NNMARK)
#define NNMARK 0x7FF7A500
+#define NNMASK 0x7FFFFF00
#endif
#undef TValuefields
#undef NILCONSTANT
-#if defined(LUA_NANTRICKLE)
+
+#if defined(LUA_NANTRICK_LE)
+
/* little endian */
#define TValuefields \
- union { struct { Value v_; int tt_; } i; double d_; } u
+ union { struct { Value v__; int tt__; } i; double d__; } u
#define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}}
-#else
+/* field-access macros */
+#define v_(o) ((o)->u.i.v__)
+#define d_(o) ((o)->u.d__)
+#define tt_(o) ((o)->u.i.tt__)
+
+#elif defined(LUA_NANTRICK_BE)
+
/* big endian */
#define TValuefields \
- union { struct { int tt_; Value v_; } i; double d_; } u
+ union { struct { int tt__; Value v__; } i; double d__; } u
#define NILCONSTANT {{tag2tt(LUA_TNIL), {NULL}}}
+/* field-access macros */
+#define v_(o) ((o)->u.i.v__)
+#define d_(o) ((o)->u.d__)
+#define tt_(o) ((o)->u.i.tt__)
+
+#elif !defined(TValuefields)
+#error option 'LUA_NANTRICK' needs declaration for 'TValuefields'
+
#endif
+
+/* correspondence with standard representation */
+#undef val_
+#define val_(o) v_(o)
+#undef num_
+#define num_(o) d_(o)
+
+
#undef numfield
#define numfield /* no such field; numbers are the entire struct */
/* basic check to distinguish numbers from non-numbers */
#undef ttisnumber
-#define ttisnumber(o) (((o)->u.i.tt_ & 0x7fffff00) != NNMARK)
+#define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK)
#define tag2tt(t) (NNMARK | (t))
-#undef val_
-#define val_(o) ((o)->u.i.v_)
-#undef num_
-#define num_(o) ((o)->u.d_)
-
#undef rttype
-#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : (o)->u.i.tt_ & 0xff)
+#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff)
#undef settt_
-#define settt_(o,t) ((o)->u.i.tt_=tag2tt(t))
+#define settt_(o,t) (tt_(o) = tag2tt(t))
#undef setnvalue
#define setnvalue(obj,x) \
@@ -324,11 +348,11 @@ typedef struct lua_TValue TValue;
*/
#undef checktag
-#define checktag(o,t) ((o)->u.i.tt_ == tag2tt(t))
+#define checktag(o,t) (tt_(o) == tag2tt(t))
#undef ttisequal
#define ttisequal(o1,o2) \
- (ttisnumber(o1) ? ttisnumber(o2) : ((o1)->u.i.tt_ == (o2)->u.i.tt_))
+ (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2)))
@@ -435,11 +459,11 @@ typedef struct Proto {
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
- int *lineinfo; /* map from opcodes to source lines */
- LocVar *locvars; /* information about local variables */
+ int *lineinfo; /* map from opcodes to source lines (debug information) */
+ LocVar *locvars; /* information about local variables (debug information) */
Upvaldesc *upvalues; /* upvalue information */
union Closure *cache; /* last created closure with this prototype */
- TString *source;
+ TString *source; /* used for debug information */
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of `k' */
int sizecode;
diff --git a/src/lopcodes.h b/src/lopcodes.h
index 01c69bdb..07d2b3f3 100644
--- a/src/lopcodes.h
+++ b/src/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.141 2011/04/19 16:22:13 roberto Exp $
+** $Id: lopcodes.h,v 1.142 2011/07/15 12:50:29 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -196,7 +196,7 @@ OP_LEN,/* A B R(A) := length of R(B) */
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
-OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */
+OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */
OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
diff --git a/src/lparser.c b/src/lparser.c
index d9c41739..a53a9312 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.113 2011/07/02 15:58:14 roberto Exp $
+** $Id: lparser.c,v 2.122 2011/10/31 17:46:04 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -41,8 +41,8 @@
*/
typedef struct BlockCnt {
struct BlockCnt *previous; /* chain */
- int firstlabel; /* index of first label in this block */
- int firstgoto; /* index of first pending goto in this block */
+ short firstlabel; /* index of first label in this block */
+ short firstgoto; /* index of first pending goto in this block */
lu_byte nactvar; /* # active locals outside the block */
lu_byte upval; /* true if some variable in the block is an upvalue */
lu_byte isloop; /* true if `block' is a loop */
@@ -81,13 +81,14 @@ static void error_expected (LexState *ls, int token) {
static void errorlimit (FuncState *fs, int limit, const char *what) {
+ lua_State *L = fs->ls->L;
const char *msg;
int line = fs->f->linedefined;
const char *where = (line == 0)
? "main function"
- : luaO_pushfstring(fs->L, "function at line %d", line);
- msg = luaO_pushfstring(fs->L, "too many %s (limit is %d) in %s",
- what, limit, where);
+ : luaO_pushfstring(L, "function at line %d", line);
+ msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
+ what, limit, where);
luaX_syntaxerror(fs->ls, msg);
}
@@ -182,7 +183,7 @@ static void new_localvar (LexState *ls, TString *name) {
MAXVARS, "local variables");
luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,
dyd->actvar.size, Vardesc, MAX_INT, "local variables");
- dyd->actvar.arr[dyd->actvar.n++].idx = cast(unsigned short, reg);
+ dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);
}
@@ -231,13 +232,13 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
Proto *f = fs->f;
int oldsize = f->sizeupvalues;
checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
- luaM_growvector(fs->L, f->upvalues, fs->nups, f->sizeupvalues,
+ luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
Upvaldesc, MAXUPVAL, "upvalues");
while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
f->upvalues[fs->nups].name = name;
- luaC_objbarrier(fs->L, f, name);
+ luaC_objbarrier(fs->ls->L, f, name);
return fs->nups++;
}
@@ -327,13 +328,13 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
static void enterlevel (LexState *ls) {
- global_State *g = G(ls->L);
- ++g->nCcalls;
- checklimit(ls->fs, g->nCcalls, LUAI_MAXCCALLS, "syntax levels");
+ lua_State *L = ls->L;
+ ++L->nCcalls;
+ checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "syntax levels");
}
-#define leavelevel(ls) (G((ls)->L)->nCcalls--)
+#define leavelevel(ls) ((ls)->L->nCcalls--)
static void closegoto (LexState *ls, int g, Labeldesc *label) {
@@ -343,9 +344,10 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) {
Labeldesc *gt = &gl->arr[g];
lua_assert(eqstr(gt->name, label->name));
if (gt->nactvar < label->nactvar) {
+ TString *vname = getlocvar(fs, gt->nactvar)->varname;
const char *msg = luaO_pushfstring(ls->L,
"<goto %s> at line %d jumps into the scope of local " LUA_QS,
- getstr(gt->name), gt->line, getstr(getlocvar(fs, gt->nactvar)->varname));
+ getstr(gt->name), gt->line, getstr(vname));
semerror(ls, msg);
}
luaK_patchlist(fs, gt->pc, label->pc);
@@ -382,7 +384,8 @@ static int findlabel (LexState *ls, int g) {
static int newlabelentry (LexState *ls, Labellist *l, TString *name,
int line, int pc) {
int n = l->n;
- luaM_growvector(ls->L, l->arr, n, l->size, Labeldesc, MAX_INT, "labels");
+ luaM_growvector(ls->L, l->arr, n, l->size,
+ Labeldesc, SHRT_MAX, "labels/gotos");
l->arr[n].name = name;
l->arr[n].line = line;
l->arr[n].nactvar = ls->fs->nactvar;
@@ -418,7 +421,7 @@ static void movegotosout (FuncState *fs, BlockCnt *bl) {
int i = bl->firstgoto;
Labellist *gl = &fs->ls->dyd->gt;
/* correct pending gotos to current block and try to close it
- with visible labels */
+ with visible labels */
while (i < gl->n) {
Labeldesc *gt = &gl->arr[i];
if (gt->nactvar > bl->nactvar) {
@@ -514,7 +517,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
Proto *f;
fs->prev = ls->fs; /* linked list of funcstates */
fs->ls = ls;
- fs->L = L;
ls->fs = fs;
fs->pc = 0;
fs->lasttarget = 0;
@@ -1039,7 +1041,7 @@ static const struct {
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
** where `binop' is any binary operator with a priority higher than `limit'
*/
-static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
+static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
BinOpr op;
UnOpr uop;
enterlevel(ls);
@@ -1105,31 +1107,34 @@ struct LHS_assign {
/*
-** check whether, in an assignment to a local variable, the local variable
-** is needed in a previous assignment (to a table). If so, save original
-** local value in a safe place and use this safe copy in the previous
-** assignment.
+** check whether, in an assignment to an upvalue/local variable, the
+** upvalue/local variable is begin used in a previous assignment to a
+** table. If so, save original upvalue/local value in a safe place and
+** use this safe copy in the previous assignment.
*/
static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
FuncState *fs = ls->fs;
int extra = fs->freereg; /* eventual position to save local variable */
int conflict = 0;
- for (; lh; lh = lh->prev) {
- /* conflict in table 't'? */
- if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
- conflict = 1;
- lh->v.u.ind.vt = VLOCAL;
- lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
- }
- /* conflict in index 'idx'? */
- if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
- conflict = 1;
- lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
+ for (; lh; lh = lh->prev) { /* check all previous assignments */
+ if (lh->v.k == VINDEXED) { /* assigning to a table? */
+ /* table is the upvalue/local being assigned now? */
+ if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
+ conflict = 1;
+ lh->v.u.ind.vt = VLOCAL;
+ lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
+ }
+ /* index is the local being assigned? (index cannot be upvalue) */
+ if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
+ conflict = 1;
+ lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
+ }
}
}
if (conflict) {
+ /* copy upvalue/local value to a temporary (in position 'extra') */
OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
- luaK_codeABC(fs, op, fs->freereg, v->u.info, 0); /* make copy */
+ luaK_codeABC(fs, op, extra, v->u.info, 0);
luaK_reserveregs(fs, 1);
}
}
@@ -1144,7 +1149,7 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
primaryexp(ls, &nv.v);
if (nv.v.k != VINDEXED)
check_conflict(ls, lh, &nv.v);
- checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls,
+ checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
"variable names");
assignment(ls, &nv, nvars+1);
}
@@ -1178,10 +1183,18 @@ static int cond (LexState *ls) {
}
-static void gotostat (LexState *ls, TString *label, int line) {
- /* create new entry for this goto */
- int g = newlabelentry(ls, &ls->dyd->gt, label, line, luaK_jump(ls->fs));
- findlabel(ls, g);
+static void gotostat (LexState *ls, int pc) {
+ int line = ls->linenumber;
+ TString *label;
+ int g;
+ if (testnext(ls, TK_GOTO))
+ label = str_checkname(ls);
+ else {
+ luaX_next(ls); /* skip break */
+ label = luaS_new(ls->L, "break");
+ }
+ g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
+ findlabel(ls, g); /* close it if label already defined */
}
@@ -1190,7 +1203,7 @@ static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
int i;
for (i = fs->bl->firstlabel; i < ll->n; i++) {
if (eqstr(label, ll->arr[i].name)) {
- const char *msg = luaO_pushfstring(fs->ls->L,
+ const char *msg = luaO_pushfstring(fs->ls->L,
"label " LUA_QS " already defined on line %d",
getstr(label), ll->arr[i].line);
semerror(fs->ls, msg);
@@ -1360,38 +1373,51 @@ static void forstat (LexState *ls, int line) {
}
-static int test_then_block (LexState *ls) {
+static void test_then_block (LexState *ls, int *escapelist) {
/* test_then_block -> [IF | ELSEIF] cond THEN block */
- int condexit;
+ BlockCnt bl;
+ FuncState *fs = ls->fs;
+ expdesc v;
+ int jf; /* instruction to skip 'then' code (if condition is false) */
luaX_next(ls); /* skip IF or ELSEIF */
- condexit = cond(ls);
+ expr(ls, &v); /* read condition */
checknext(ls, TK_THEN);
- block(ls); /* `then' part */
- return condexit;
+ if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
+ luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
+ enterblock(fs, &bl, 0); /* must enter block before 'goto' */
+ gotostat(ls, v.t); /* handle goto/break */
+ if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
+ leaveblock(fs);
+ return; /* and that is it */
+ }
+ else /* must skip over 'then' part if condition is false */
+ jf = luaK_jump(fs);
+ }
+ else { /* regular case (not goto/break) */
+ luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
+ enterblock(fs, &bl, 0);
+ jf = v.f;
+ }
+ statlist(ls); /* `then' part */
+ leaveblock(fs);
+ if (ls->t.token == TK_ELSE ||
+ ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */
+ luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */
+ luaK_patchtohere(fs, jf);
}
static void ifstat (LexState *ls, int line) {
/* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
FuncState *fs = ls->fs;
- int flist;
- int escapelist = NO_JUMP;
- flist = test_then_block(ls); /* IF cond THEN block */
- while (ls->t.token == TK_ELSEIF) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, flist);
- flist = test_then_block(ls); /* ELSEIF cond THEN block */
- }
- if (ls->t.token == TK_ELSE) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, flist);
- luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
+ int escapelist = NO_JUMP; /* exit list for finished parts */
+ test_then_block(ls, &escapelist); /* IF cond THEN block */
+ while (ls->t.token == TK_ELSEIF)
+ test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */
+ if (testnext(ls, TK_ELSE))
block(ls); /* `else' part */
- }
- else
- luaK_concat(fs, &escapelist, flist);
- luaK_patchtohere(fs, escapelist);
check_match(ls, TK_END, TK_IF, line);
+ luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */
}
@@ -1551,15 +1577,9 @@ static void statement (LexState *ls) {
retstat(ls);
break;
}
- case TK_BREAK: { /* stat -> breakstat */
- luaX_next(ls); /* skip BREAK */
- /* code it as "goto 'break'" */
- gotostat(ls, luaS_new(ls->L, "break"), line);
- break;
- }
+ case TK_BREAK: /* stat -> breakstat */
case TK_GOTO: { /* stat -> 'goto' NAME */
- luaX_next(ls); /* skip GOTO */
- gotostat(ls, str_checkname(ls), line);
+ gotostat(ls, luaK_jump(ls->fs));
break;
}
default: { /* stat -> func | assignment */
@@ -1595,8 +1615,8 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
close_func(&lexstate);
L->top--; /* pop name */
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
- return funcstate.f;
/* all scopes should be correctly finished */
lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
+ return funcstate.f;
}
diff --git a/src/lparser.h b/src/lparser.h
index 4e7e06fc..caabf46c 100644
--- a/src/lparser.h
+++ b/src/lparser.h
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.h,v 1.68 2011/02/23 13:13:10 roberto Exp $
+** $Id: lparser.h,v 1.69 2011/07/27 18:09:01 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -55,7 +55,7 @@ typedef struct expdesc {
/* description of active local variable */
typedef struct Vardesc {
- unsigned short idx; /* variable index in stack */
+ short idx; /* variable index in stack */
} Vardesc;
@@ -98,18 +98,17 @@ typedef struct FuncState {
Table *h; /* table to find (and reuse) elements in `k' */
struct FuncState *prev; /* enclosing function */
struct LexState *ls; /* lexical state */
- struct lua_State *L; /* copy of the Lua state */
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to `ncode') */
- int lasttarget; /* `pc' of last `jump target' */
+ int lasttarget; /* 'label' of last 'jump label' */
int jpc; /* list of pending jumps to `pc' */
- int freereg; /* first free register */
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
- int firstlocal; /* index of first local var of this function */
- short nlocvars; /* number of elements in `locvars' */
+ int firstlocal; /* index of first local var (in Dyndata array) */
+ short nlocvars; /* number of elements in 'f->locvars' */
lu_byte nactvar; /* number of active local variables */
lu_byte nups; /* number of upvalues */
+ lu_byte freereg; /* first free register */
} FuncState;
diff --git a/src/lstate.c b/src/lstate.c
index 45dac3c5..6e2801c4 100644
--- a/src/lstate.c
+++ b/src/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.89 2010/12/20 19:40:07 roberto Exp $
+** $Id: lstate.c,v 2.92 2011/10/03 17:54:25 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -136,10 +136,10 @@ static void init_registry (lua_State *L, global_State *g) {
luaH_resize(L, registry, LUA_RIDX_LAST, 0);
/* registry[LUA_RIDX_MAINTHREAD] = L */
setthvalue(L, &mt, L);
- setobj2t(L, luaH_setint(L, registry, LUA_RIDX_MAINTHREAD), &mt);
+ luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
/* registry[LUA_RIDX_GLOBALS] = table of globals */
sethvalue(L, &mt, luaH_new(L));
- setobj2t(L, luaH_setint(L, registry, LUA_RIDX_GLOBALS), &mt);
+ luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
}
@@ -171,6 +171,7 @@ static void preinit_state (lua_State *L, global_State *g) {
L->ci = NULL;
L->stacksize = 0;
L->errorJmp = NULL;
+ L->nCcalls = 0;
L->hook = NULL;
L->hookmask = 0;
L->basehookcount = 0;
@@ -191,7 +192,7 @@ static void close_state (lua_State *L) {
luaZ_freebuffer(L, &g->buff);
freestack(L);
lua_assert(gettotalbytes(g) == sizeof(LG));
- (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);
+ (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
}
@@ -237,7 +238,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
L->marked = luaC_white(g);
g->gckind = KGC_NORMAL;
- g->nCcalls = 0;
preinit_state(L, g);
g->frealloc = f;
g->ud = ud;
@@ -279,9 +279,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
LUA_API void lua_close (lua_State *L) {
L = G(L)->mainthread; /* only the main thread can be closed */
lua_lock(L);
- luaF_close(L, L->stack); /* close all upvalues for this thread */
- luaC_separateudata(L, 1); /* separate all udata with GC metamethods */
- lua_assert(L->next == NULL);
luai_userstateclose(L);
close_state(L);
}
diff --git a/src/lstate.h b/src/lstate.h
index 9d21e7e8..4743d741 100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.72 2011/06/02 19:31:40 roberto Exp $
+** $Id: lstate.h,v 2.74 2011/09/30 12:45:07 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -47,8 +47,6 @@ struct lua_longjmp; /* defined in ldo.c */
#define EXTRA_STACK 5
-#define BASIC_CI_SIZE 8
-
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
@@ -118,7 +116,6 @@ typedef struct global_State {
lu_mem lastmajormem; /* memory in use after last major collection */
stringtable strt; /* hash table for strings */
TValue l_registry;
- unsigned short nCcalls; /* number of nested C calls */
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
lu_byte gckind; /* kind of GC running */
@@ -161,6 +158,7 @@ struct lua_State {
StkId stack; /* stack base */
int stacksize;
unsigned short nny; /* number of non-yieldable calls in stack */
+ unsigned short nCcalls; /* number of nested C calls */
lu_byte hookmask;
lu_byte allowhook;
int basehookcount;
diff --git a/src/lstrlib.c b/src/lstrlib.c
index 5e200f1c..84193ebd 100644
--- a/src/lstrlib.c
+++ b/src/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.170 2011/06/28 17:13:52 roberto Exp $
+** $Id: lstrlib.c,v 1.172 2011/10/25 12:01:20 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -138,7 +138,7 @@ static int str_byte (lua_State *L) {
if (pose > l) pose = l;
if (posi > pose) return 0; /* empty interval; return no values */
n = (int)(pose - posi + 1);
- if (posi + n <= pose) /* overflow? */
+ if (posi + n <= pose) /* (size_t -> int) overflow? */
return luaL_error(L, "string slice too long");
luaL_checkstack(L, n, "string slice too long");
for (i=0; i<n; i++)
@@ -154,7 +154,7 @@ static int str_char (lua_State *L) {
char *p = luaL_buffinitsize(L, &b, n);
for (i=1; i<=n; i++) {
int c = luaL_checkint(L, i);
- luaL_argcheck(L, uchar(c) == c, i, "invalid value");
+ luaL_argcheck(L, uchar(c) == c, i, "value out of range");
p[i - 1] = uchar(c);
}
luaL_pushresultsize(&b, n);
@@ -865,11 +865,20 @@ static int str_format (lua_State *L) {
nb = sprintf(buff, form, luaL_checkint(L, arg));
break;
}
- case 'd': case 'i':
+ case 'd': case 'i': {
+ lua_Number n = luaL_checknumber(L, arg);
+ LUA_INTFRM_T r = (LUA_INTFRM_T)n;
+ luaL_argcheck(L, (lua_Number)r == n, arg,
+ "not an integer in proper range");
+ addlenmod(form, LUA_INTFRMLEN);
+ nb = sprintf(buff, form, r);
+ break;
+ }
case 'o': case 'u': case 'x': case 'X': {
lua_Number n = luaL_checknumber(L, arg);
- LUA_INTFRM_T r = (n < 0) ? (LUA_INTFRM_T)n :
- (LUA_INTFRM_T)(unsigned LUA_INTFRM_T)n;
+ unsigned LUA_INTFRM_T r = (unsigned LUA_INTFRM_T)n;
+ luaL_argcheck(L, (lua_Number)r == n, arg,
+ "not a non-negative integer in proper range");
addlenmod(form, LUA_INTFRMLEN);
nb = sprintf(buff, form, r);
break;
diff --git a/src/ltable.c b/src/ltable.c
index a9379596..d96d2558 100644
--- a/src/ltable.c
+++ b/src/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.60 2011/06/16 14:14:31 roberto Exp $
+** $Id: ltable.c,v 2.65 2011/09/30 12:45:27 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -64,13 +64,6 @@
#define hashpointer(t,p) hashmod(t, IntPoint(p))
-/*
-** number of ints inside a lua_Number
-*/
-#define numints cast_int(sizeof(lua_Number)/sizeof(int))
-
-
-
#define dummynode (&dummynode_)
#define isdummy(n) ((n) == dummynode)
@@ -152,7 +145,7 @@ static int findindex (lua_State *L, Table *t, StkId key) {
/* key may be dead already, but it is ok to use it in `next' */
if (luaV_rawequalobj(gkey(n), key) ||
(ttisdeadkey(gkey(n)) && iscollectable(key) &&
- gcvalue(gkey(n)) == gcvalue(key))) {
+ deadvalue(gkey(n)) == gcvalue(key))) {
i = cast_int(n - gnode(t, 0)); /* key index in hash table */
/* hash elements are numbered after array ones */
return i + t->sizearray;
@@ -314,7 +307,7 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
/* re-insert elements from vanishing slice */
for (i=nasize; i<oldasize; i++) {
if (!ttisnil(&t->array[i]))
- setobjt2t(L, luaH_setint(L, t, i+1), &t->array[i]);
+ luaH_setint(L, t, i + 1, &t->array[i]);
}
/* shrink array */
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
@@ -322,8 +315,11 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
/* re-insert elements from hash part */
for (i = twoto(oldhsize) - 1; i >= 0; i--) {
Node *old = nold+i;
- if (!ttisnil(gval(old)))
+ if (!ttisnil(gval(old))) {
+ /* doesn't need barrier/invalidate cache, as entry was
+ already present in the table */
setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
+ }
}
if (!isdummy(nold))
luaM_freearray(L, nold, twoto(oldhsize)); /* free old array */
@@ -398,14 +394,19 @@ static Node *getfreepos (Table *t) {
** put new key in its main position; otherwise (colliding node is in its main
** position), new key goes to an empty position.
*/
-static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
- Node *mp = mainposition(t, key);
+TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
+ Node *mp;
+ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
+ else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
+ luaG_runerror(L, "table index is NaN");
+ mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
Node *othern;
Node *n = getfreepos(t); /* get a free place */
if (n == NULL) { /* cannot find a free place? */
rehash(L, t, key); /* grow table */
- return luaH_set(L, t, key); /* re-insert key into grown table */
+ /* whatever called 'newkey' take care of TM cache and GC barrier */
+ return luaH_set(L, t, key); /* insert key into grown table */
}
lua_assert(!isdummy(n));
othern = mainposition(t, gkey(mp));
@@ -493,41 +494,29 @@ const TValue *luaH_get (Table *t, const TValue *key) {
}
+/*
+** beware: when using this function you probably need to check a GC
+** barrier and invalidate the TM cache.
+*/
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key);
- t->flags = 0;
if (p != luaO_nilobject)
return cast(TValue *, p);
- else {
- if (ttisnil(key)) luaG_runerror(L, "table index is nil");
- else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
- luaG_runerror(L, "table index is NaN");
- return newkey(L, t, key);
- }
+ else return luaH_newkey(L, t, key);
}
-TValue *luaH_setint (lua_State *L, Table *t, int key) {
+void luaH_setint (lua_State *L, Table *t, int key, TValue *value) {
const TValue *p = luaH_getint(t, key);
+ TValue *cell;
if (p != luaO_nilobject)
- return cast(TValue *, p);
+ cell = cast(TValue *, p);
else {
TValue k;
setnvalue(&k, cast_num(key));
- return newkey(L, t, &k);
- }
-}
-
-
-TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
- const TValue *p = luaH_getstr(t, key);
- if (p != luaO_nilobject)
- return cast(TValue *, p);
- else {
- TValue k;
- setsvalue(L, &k, key);
- return newkey(L, t, &k);
+ cell = luaH_newkey(L, t, &k);
}
+ setobj2t(L, cell, value);
}
diff --git a/src/ltable.h b/src/ltable.h
index c14b0283..2f6f5c2d 100644
--- a/src/ltable.h
+++ b/src/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 2.14 2010/06/25 12:18:10 roberto Exp $
+** $Id: ltable.h,v 2.16 2011/08/17 20:26:47 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -15,12 +15,14 @@
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->i_key.nk.next)
+#define invalidateTMcache(t) ((t)->flags = 0)
+
LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
-LUAI_FUNC TValue *luaH_setint (lua_State *L, Table *t, int key);
+LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
-LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
+LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC Table *luaH_new (lua_State *L);
LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
diff --git a/src/ltablib.c b/src/ltablib.c
index 06353c7b..5c3abc35 100644
--- a/src/ltablib.c
+++ b/src/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.61 2011/07/05 12:49:35 roberto Exp $
+** $Id: ltablib.c,v 1.62 2011/09/30 12:45:45 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -86,7 +86,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, int i) {
if (!lua_isstring(L, -1))
luaL_error(L, "invalid value (%s) at index %d in table for "
LUA_QL("concat"), luaL_typename(L, -1), i);
- luaL_addvalue(b);
+ luaL_addvalue(b);
}
diff --git a/src/lua.c b/src/lua.c
index 8b317c6a..e1410000 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -1,5 +1,5 @@
/*
-** $Id: lua.c,v 1.200 2011/06/16 14:30:58 roberto Exp $
+** $Id: lua.c,v 1.202 2011/08/17 20:19:52 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -118,6 +118,7 @@ static void print_usage (const char *badoption) {
" -i enter interactive mode after executing " LUA_QL("script") "\n"
" -l name require library " LUA_QL("name") "\n"
" -v show version information\n"
+ " -E ignore environment variables\n"
" -- stop handling options\n"
" - stop handling options and execute stdin\n"
,
@@ -348,7 +349,16 @@ static int handle_script (lua_State *L, char **argv, int n) {
#define noextrachars(x) {if ((x)[2] != '\0') return -1;}
-static int collectargs (char **argv, int *pi, int *pv, int *pe) {
+/* indices of various argument indicators in array args */
+#define has_i 0 /* -i */
+#define has_v 1 /* -v */
+#define has_e 2 /* -e */
+#define has_E 3 /* -E */
+
+#define num_has 4 /* number of 'has_*' */
+
+
+static int collectargs (char **argv, int *args) {
int i;
for (i = 1; argv[i] != NULL; i++) {
if (argv[i][0] != '-') /* not an option? */
@@ -359,15 +369,18 @@ static int collectargs (char **argv, int *pi, int *pv, int *pe) {
return (argv[i+1] != NULL ? i+1 : 0);
case '\0':
return i;
+ case 'E':
+ args[has_E] = 1;
+ break;
case 'i':
noextrachars(argv[i]);
- *pi = 1; /* go through */
+ args[has_i] = 1; /* go through */
case 'v':
noextrachars(argv[i]);
- *pv = 1;
+ args[has_v] = 1;
break;
case 'e':
- *pe = 1; /* go through */
+ args[has_e] = 1; /* go through */
case 'l': /* both options need an argument */
if (argv[i][2] == '\0') { /* no concatenated argument? */
i++; /* try next 'argv' */
@@ -426,32 +439,46 @@ static int handle_luainit (lua_State *L) {
}
+static void resetpaths (lua_State *L) {
+ lua_getglobal(L, "package");
+ if (!lua_istable(L, -1)) /* no module 'package'? */
+ return; /* nothing to be done */
+ lua_pushliteral(L, LUA_PATH_DEFAULT);
+ lua_setfield(L, -2, "path"); /* package.path = default */
+ lua_pushliteral(L, LUA_CPATH_DEFAULT);
+ lua_setfield(L, -2, "cpath"); /* package.cpath = default */
+ lua_pop(L, 1); /* remove 'package' */
+}
+
+
static int pmain (lua_State *L) {
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;
+ int args[num_has];
+ args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0;
if (argv[0] && argv[0][0]) progname = argv[0];
- script = collectargs(argv, &has_i, &has_v, &has_e);
+ script = collectargs(argv, args);
if (script < 0) { /* invalid arg? */
print_usage(argv[-script]);
return 0;
}
- if (has_v) print_version();
+ if (args[has_v]) print_version();
/* open standard libraries */
luaL_checkversion(L);
lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
luaL_openlibs(L); /* open libraries */
lua_gc(L, LUA_GCRESTART, 0);
- /* run LUA_INIT */
- if (handle_luainit(L) != LUA_OK) return 0;
+ if (args[has_E]) /* avoid LUA_INIT? */
+ resetpaths(L);
+ else if (handle_luainit(L) != LUA_OK) return 0;
/* execute arguments -e and -l */
if (!runargs(L, argv, (script > 0) ? script : argc)) return 0;
/* execute main script (if there is one) */
if (script && handle_script(L, argv, script) != LUA_OK) return 0;
- if (has_i) /* -i option? */
+ if (args[has_i]) /* -i option? */
dotty(L);
- else if (script == 0 && !has_e && !has_v) { /* no arguments? */
+ else if (script == 0 && !args[has_e] && !args[has_v]) { /* no arguments? */
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
diff --git a/src/lua.h b/src/lua.h
index 518d44c4..2d94f084 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.278 2011/07/02 16:00:15 roberto Exp $
+** $Id: lua.h,v 1.281 2011/10/24 16:53:05 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@@ -19,7 +19,7 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "2"
#define LUA_VERSION_NUM 502
-#define LUA_VERSION_RELEASE "0" " (beta)"
+#define LUA_VERSION_RELEASE "0"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
@@ -215,10 +215,12 @@ LUA_API int (lua_pushthread) (lua_State *L);
/*
** get functions (Lua -> stack)
*/
+LUA_API void (lua_getglobal) (lua_State *L, const char *var);
LUA_API void (lua_gettable) (lua_State *L, int idx);
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawget) (lua_State *L, int idx);
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
+LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p);
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
@@ -228,10 +230,12 @@ LUA_API void (lua_getuservalue) (lua_State *L, int idx);
/*
** set functions (stack -> Lua)
*/
+LUA_API void (lua_setglobal) (lua_State *L, const char *var);
LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawset) (lua_State *L, int idx);
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
+LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p);
LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
LUA_API void (lua_setuservalue) (lua_State *L, int idx);
@@ -261,7 +265,7 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx,
lua_CFunction k);
#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
-LUA_API int (lua_resume) (lua_State *L, int narg);
+LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg);
LUA_API int (lua_status) (lua_State *L);
/*
@@ -314,13 +318,6 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
#define lua_newtable(L) lua_createtable(L, 0, 0)
-#define lua_setglobal(L,s) \
- (lua_pushglobaltable(L), lua_pushvalue(L, -2), \
- lua_setfield(L, -2, (s)), lua_pop(L, 2))
-
-#define lua_getglobal(L,s) \
- (lua_pushglobaltable(L), lua_getfield(L, -1, (s)), lua_remove(L, -2))
-
#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
diff --git a/src/luac.c b/src/luac.c
index 62ff9cc5..fe91beea 100644
--- a/src/luac.c
+++ b/src/luac.c
@@ -1,5 +1,5 @@
/*
-** $Id: luac.c,v 1.67 2011/06/21 12:29:00 lhf Exp $
+** $Id: luac.c,v 1.68 2011/11/23 17:48:18 lhf Exp $
** Lua compiler (saves bytecodes to files; also list bytecodes)
** See Copyright Notice in lua.h
*/
@@ -53,7 +53,7 @@ static void usage(const char* message)
fprintf(stderr,
"usage: %s [options] [filenames]\n"
"Available options are:\n"
- " -l list\n"
+ " -l list (use -l -l for full listing)\n"
" -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
" -p parse only\n"
" -s strip debug information\n"
@@ -203,7 +203,7 @@ int main(int argc, char* argv[])
}
/*
-** $Id: print.c,v 1.67 2011/05/06 13:37:15 lhf Exp $
+** $Id: print.c,v 1.68 2011/09/30 10:21:20 lhf Exp $
** print bytecodes
** See Copyright Notice in lua.h
*/
@@ -218,7 +218,6 @@ int main(int argc, char* argv[])
#include "lobject.h"
#include "lopcodes.h"
-#define Sizeof(x) ((int)sizeof(x))
#define VOID(p) ((const void*)(p))
static void PrintString(const TString* ts)
diff --git a/src/luaconf.h b/src/luaconf.h
index 1135e508..a5d62470 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.161 2011/07/08 20:07:11 roberto Exp $
+** $Id: luaconf.h,v 1.166 2011/11/09 14:47:14 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -29,8 +29,8 @@
#endif
-#if !defined(LUA_ANSI) && defined(_WIN32)
-#define LUA_WIN
+#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE)
+#define LUA_WIN /* enable goodies for regular Windows platforms */
#endif
#if defined(LUA_WIN)
@@ -210,10 +210,14 @@
/*
@@ luai_writestring/luai_writeline define how 'print' prints its results.
+** They are only used in libraries and the stand-alone program. (The #if
+** avoids including 'stdio.h' everywhere.)
*/
+#if defined(LUA_LIB) || defined(lua_c) || defined(luaall_c)
#include <stdio.h>
#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout))
+#endif
/*
@@ luai_writestringerror defines how to print error messages.
@@ -459,7 +463,7 @@
/* On a Microsoft compiler on a Pentium, use assembler to avoid clashes
with a DirectX idiosyncrasy */
-#if defined(_MSC_VER) && defined(M_IX86) /* { */
+#if defined(LUA_WIN) && defined(_M_IX86) /* { */
#define MS_ASMTRICK
@@ -492,12 +496,13 @@
/*
-@@ LUA_NANTRICKLE/LUA_NANTRICKBE controls the use of a trick to pack all
-** types into a single double value, using NaN values to represent
-** non-number values. The trick only works on 32-bit machines (ints and
-** pointers are 32-bit values) with numbers represented as IEEE 754-2008
-** doubles with conventional endianess (12345678 or 87654321), in CPUs
-** that do not produce signaling NaN values (all NaNs are quiet).
+@@ LUA_NANTRICK_LE/LUA_NANTRICK_BE controls the use of a trick to
+** pack all types into a single double value, using NaN values to
+** represent non-number values. The trick only works on 32-bit machines
+** (ints and pointers are 32-bit values) with numbers represented as
+** IEEE 754-2008 doubles with conventional endianess (12345678 or
+** 87654321), in CPUs that do not produce signaling NaN values (all NaNs
+** are quiet).
*/
#if defined(LUA_CORE) && \
defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
@@ -506,7 +511,7 @@
#if defined(__i386__) || defined(__i386) || defined(__X86__) || \
defined(_M_IX86)
-#define LUA_NANTRICKLE
+#define LUA_NANTRICK_LE
#endif
diff --git a/src/lvm.c b/src/lvm.c
index e4f90af4..de340776 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.141 2011/06/09 18:24:22 roberto Exp $
+** $Id: lvm.c,v 2.144 2011/10/07 20:45:19 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -127,29 +127,38 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
int loop;
- TValue temp;
for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
- TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
- if (!ttisnil(oldval) || /* result is not nil? */
- (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
- setobj2t(L, oldval, val);
+ TValue *oldval = cast(TValue *, luaH_get(h, key));
+ /* if previous value is not nil, there must be a previous entry
+ in the table; moreover, a metamethod has no relevance */
+ if (!ttisnil(oldval) ||
+ /* previous value is nil; must check the metamethod */
+ ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
+ /* no metamethod; is there a previous entry in the table? */
+ (oldval != luaO_nilobject ||
+ /* no previous entry; must create one. (The next test is
+ always true; we only need the assignment.) */
+ (oldval = luaH_newkey(L, h, key), 1)))) {
+ /* no metamethod and (now) there is an entry with given key */
+ setobj2t(L, oldval, val); /* assign new value to that entry */
+ invalidateTMcache(h);
luaC_barrierback(L, obj2gco(h), val);
return;
}
- /* else will try the tag method */
+ /* else will try the metamethod */
}
- else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
- luaG_typeerror(L, t, "index");
+ else /* not a table; check metamethod */
+ if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
+ luaG_typeerror(L, t, "index");
+ /* there is a metamethod */
if (ttisfunction(tm)) {
callTM(L, tm, t, key, val, 0);
return;
}
- /* else repeat with 'tm' */
- setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */
- t = &temp;
+ t = tm; /* else repeat with 'tm' */
}
luaG_runerror(L, "loop in settable");
}
@@ -217,9 +226,9 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
return luai_numlt(L, nvalue(l), nvalue(r));
else if (ttisstring(l) && ttisstring(r))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
- else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
- return res;
- return luaG_ordererror(L, l, r);
+ else if ((res = call_orderTM(L, l, r, TM_LT)) < 0)
+ luaG_ordererror(L, l, r);
+ return res;
}
@@ -229,11 +238,11 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
return luai_numle(L, nvalue(l), nvalue(r));
else if (ttisstring(l) && ttisstring(r))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
- else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
+ else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
return res;
- else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
- return !res;
- return luaG_ordererror(L, l, r);
+ else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */
+ luaG_ordererror(L, l, r);
+ return !res;
}
@@ -808,7 +817,7 @@ void luaV_execute (lua_State *L) {
luaH_resizearray(L, h, last); /* pre-allocate it at once */
for (; n > 0; n--) {
TValue *val = ra+n;
- setobj2t(L, luaH_setint(L, h, last--), val);
+ luaH_setint(L, h, last--, val);
luaC_barrierback(L, obj2gco(h), val);
}
L->top = ci->top; /* correct top (in case of previous open call) */
diff --git a/src/lzio.c b/src/lzio.c
index 7d2677bd..354f94e7 100644
--- a/src/lzio.c
+++ b/src/lzio.c
@@ -1,5 +1,5 @@
/*
-** $Id: lzio.c,v 1.33 2011/02/23 13:13:10 roberto Exp $
+** $Id: lzio.c,v 1.34 2011/07/15 12:35:32 roberto Exp $
** a generic input stream interface
** See Copyright Notice in lua.h
*/
@@ -29,7 +29,7 @@ int luaZ_fill (ZIO *z) {
return EOZ;
z->n = size - 1; /* discount char being returned */
z->p = buff;
- return char2int(*(z->p++));
+ return cast_uchar(*(z->p++));
}
diff --git a/src/lzio.h b/src/lzio.h
index 4174986d..08682301 100644
--- a/src/lzio.h
+++ b/src/lzio.h
@@ -1,5 +1,5 @@
/*
-** $Id: lzio.h,v 1.24 2011/02/23 13:13:10 roberto Exp $
+** $Id: lzio.h,v 1.26 2011/07/15 12:48:03 roberto Exp $
** Buffered streams
** See Copyright Notice in lua.h
*/
@@ -17,11 +17,7 @@
typedef struct Zio ZIO;
-#define char2int(c) cast(int, cast(unsigned char, (c)))
-
-#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
-
-#define zungetc(z) ((z)->n++, (z)->p--)
+#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z))
typedef struct Mbuffer {